Linux编译器gcc/g++介绍

news2024/11/23 14:55:41

gcc/g++编译器介绍

编译器的功能就是把代码经过一系列处理变成可执行文件,然后就可以执行文件实现代码的功能。

gcc编译器编译C语言文件,g++编译C++文件,g++也可以编译C语言,但gcc不能编译C++文件。

gcc使用方法:gcc [选项] 要编译的文件 [选项] [目标文件] g++和gcc使用方法相同。

常见的C++文件后缀有.cpp|.cc|.cxx

注意以下代码使用gcc编译时可能会报错,代码本身没有语法问题。

  1 #include<stdio.h>
  2 
  3 int main()
  4 {
  5   for(int i = 0; i < 10; i++)
  6   {
  7     printf("123\n");
  8   }
  9   return 0;      
 10 }

image-20231104204935434

报错显示第五行在for循环里定义变量是c99才有的,所以我们在编译时还要手动设置c99标准来编译该代码

加了标准之前:gcc code1.c

加了标准之后:gcc code1.c -std=c99

程序翻译过程:

  1. 预处理
  2. 编译
  3. 汇编
  4. 链接
  5. 生成可执行程序

在介绍程序翻译过程之前我们先介绍一下编译器的发展史,更有利于理解后面的程序翻译。

编译器的发展史

​ 计算机语言最开始是二进制语言,所有指令都由0101组成,因为二进制语言比较麻烦所以后面就发明了汇编语言。计算机只能读懂二进制,所以以前的人们还得开发一个软件汇编语言翻译成二进制语言才能让计算机读懂,所以人们就开发出了这样的软件,这个软件只能用二进制语言来写,这样才能让计算机运行这个软件把汇编语言翻译成二进制语言。这个软件就叫做编译器,因为是二进制语言写的所以就叫二进制编译器

​ 随着时间的流逝,人们发现汇编语言也不是很方便,于是就发明了高级语言,比如C语言。这时候又需要一个软件来把高级语言翻译成汇编语言,然后再由二进制编译器汇编语言翻译成计算机看得懂的二进制语言。这个软件就叫做汇编编译器,这样我们就能比较方便的进行编程了。

image-20231104165111547

​ 既然我们有了汇编编译器二进制编译器,那么我们就可以重写编译器,比如用汇编语言重写二进制编译器,用高级语言重写汇编编译器,于是就变成了下面这样:

image-20231104170400613

​ 因为我们还有汇编编译器(汇编语言写的)二进制编译器(二进制语言写的),所以就能翻译高级语言写的汇编编译器汇编语言写的二进制编译器

​ 有人说为什么不直接把高级语言翻译成二进制语言呢?可以但没必要,因为已经有人造好了轮子,在人们发明了高级语言时只需要写一个编译器翻译成汇编语言即可,不需要再大费周章的写一个编译器把高级语言翻译成二进制语言。

程序翻译的过程

假设我们有一个代码名为code.c

  1. 预处理

    gcc -E code.c -o code.i这句代码的意思是对程序进行翻译,做完预处理就停止,生成的文件重命名为code.i

    • 头文件展开(编译前十几行的代码在头文件展开后可能有一千行)
    • 去注释
    • 条件编译(通过条件编译可以实现对代码的动态裁减)
    • 宏替换
  2. 编译

    gcc -S code.i -o code.s这句代码的意思就是从现在开始对程序进行翻译,做完编译就停止,生成的文件重命名为code.s

    • 检查代码的规范性,是否具有语法错误
    • 将C语言翻译成汇编语言
  3. 汇编

    gcc -c code.s -o code.o这句代码的意思就是从现在开始对程序进行翻译,做完汇编就停止,生成的文件重命名为code.o

    • 把编译阶段生成的.s文件转成目标文件
    • 虽然code.o已经是二进制文件了,但此时无法执行code.o文件,不过可以编译形成可执行程序
  4. 链接

    *.o+系统库=可执行程序

    系统库就是函数库,下面我们将会详细介绍。

函数库

​ 用C语言举例,我们的熟知的printfscanf函数,我们自己没有定义又为什么能用呢?实际上这些函数的实现都放在库文件里去了,这些库都在特定的路径下,一般没有指定时,编译器会去系统默认搜索路径查找。而在Linux中,这个路径为usr/lib,我所用的CentOS7系统的printf函数存放在libc.so.6的库文件中。函数库分为静态库和动态库。

ldd [文件名]可以查看该文件所依赖的动态库文件

静态库和动态库

Linux下动态库是.so,静态库是.a,Windows下静态库的后缀是.dll,静态库是.lib

动态库:是C/C++或者其他第三方提供的所有方法的集合,被所有程序以链接的方式关联起来,这种称为动态链接。库中所有的函数,都有入口地址,所谓的动态链接,其实就是把要连接的库中的函数地址拷贝到我们可执行程序的特定位置,也就是链接的合并符号表

静态库:是C/C++或者其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码,拷贝到自己的可执行程序中,这种叫做静态链接

动态库的优缺点

优点:形成的可执行程序体积比较小,比较节省资源。(磁盘和内存)

缺点:稍慢一点,因为要通过函数地址找到函数的实现。强依赖动态库,动态库没了,所有依赖这个库的程序都无法运行了

静态库的优缺点

优点:无视库,可以独立运行

缺点:体积太大,浪费资源

​ 动态库居多,静态库比较少,下面是使用动态链接和静态链接文件的对比:

gcc code.c -o code-s -static后面加上-static就是静态链接的方式编译

image-20231104202303316

code-s是静态链接编译的,code.exe是动态链接编译的,很明显可以看到静态链接的可执行文件大小比动态链接的大的多。

​ 当然这里有些人使用静态链接的方式编译时可能会报错,因为有些云服务器是没有安装静态库的,需要手动安装,输入以下代码:

C: sudo yum install glibc-static

C++: sudo yum install -y libstdc++-static

​ 从上面可以看出系统一般自带动态库,而不是静态库,编译器默认链接的方式也是动态链接,原因是:

系统中有各种各样的软件,如果每个程序都是用静态链接的方式,那么每个程序执行时都要拷贝一份静态库,最后在内存里就会有很多相同的静态库,就会极大的浪费内存资源。

这也就是为什么动态库比静态库多的原因了


​ 所以,我们的开发环境,默认都要为我们做什么呢?

  • 下载开发环境
  • 设置合理的查找路径
  • 规定好我们形成可执行文件的链接方式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1171588.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【漏洞复现】fastjson_1.2.24_unserializer_rce

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞检测3、漏洞验证 1.5、深度利用1、GetShell 说明内容漏洞编号漏洞名称fastjson 1.2.24 反序列化导致…

vbox虚拟机导出减少体积:压缩VDI文件

前言部分&#xff1a; 网上找了一些virtualBox虚拟机压缩方法&#xff0c;做了测试。虚拟机导出体积有了明显减少。 参考文档&#xff1a;https://blog.csdn.net/mr__bai/article/details/129147223 里面有一些注意事项&#xff0c;包括我在实践时遇到的一些问题&#xff0c;在…

Redis7.x 高级篇

Redis7.x 高级篇 Redis版本发行时间Redis单线程说的是什么东西 Redis版本发行时间 Redis单线程说的是什么东西

微信小程序获取剪切板的内容到输入框中

xml代码 <navigation-bar title"Weixin" back"{{false}}" color"black" background"#FFF"></navigation-bar> <view><input placeholder"请输入内容" name"content" type"text" …

FreeRTOS-定时器\二值信号互斥信号\事件组

FreeRTOS整体知识框架可以参考下文: FreeRTOS整体知识框架 一. FreeRTOS定时器 FreeRTOS定时器 博文路径 FreeRTOS提供了一种软件定时器&#xff0c;用来快速实现一些周期性的操作&#xff0c;并且节约了硬件定时器。不过尽量还是不要做过多的操作&#xff0c;以免影响其他…

文件夹重命名与大小写转换:提高文件检索准确性的技巧

在文件管理中&#xff0c;文件夹的命名和大小写转换是非常重要的操作。正确的文件夹命名和大小写转换可以提高文件检索的准确性&#xff0c;从而提高工作效率和文件管理的便利性。现在来看云炫文件管理器如何进行文件夹重命名和大小写转换的技巧&#xff0c;以帮助您更好地管理…

python 成绩统计,输出及格率和优

题目描述&#xff1a; 小蓝给学生们组织了一场考试&#xff0c;卷面总分为100分&#xff0c;每个学生的得分都是一个0到100的整数。 如果得分至少是60分&#xff0c;则称为及格。如果得分至少为85分&#xff0c;则称为优秀。 请计算及格率和优秀率&#xff0c;用百分数表示&am…

C++入门讲解第一篇

大家好&#xff0c;我是Dark Fire&#xff0c;终于进入了C的学习&#xff0c;我知道面对我的将是什么&#xff0c;就算变成秃头佬&#xff0c;也要把C学好&#xff0c;今天是C入门第一篇&#xff0c;我会尽全力将知识以清晰易懂的方式表达出&#xff0c;希望我们一起加油&#…

电脑出现emp.dll文件缺失的错误提示怎么办,教你一键解决dll丢失问题

今天&#xff0c;我想和大家分享一下关于emp.dll文件丢失的4个解决方法&#xff0c;希望能对大家有所帮助。 首先&#xff0c;我们要明确emp.dll文件的作用。emp.dll是一个动态链接库文件&#xff0c;这个文件对于许多程序的正常运行至关重要&#xff0c;一旦丢失&#xff0c;…

在树莓派上使用Nginx搭建本地站点并通过内网穿透实现远程访问

目录 前言 1. Nginx安装 2. 安装cpolar 3.配置域名访问Nginx 4. 固定域名访问 5. 配置静态站点 前言 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务…

代码随想录算法训练营第23期day41|01背包问题、01背包问题——滚动数组、416. 分割等和子集

目录 一、01背包理论基础 1.二维dp数组01背包 1&#xff09;确定dp数组以及下标的含义 2&#xff09;确定递推公式 3&#xff09;dp数组如何初始化 4&#xff09;确定遍历顺序 5&#xff09;举例推导dp数组 2.一维dp数组&#xff08;滚动数组&#xff09; 1&#xf…

CSS必学:元素之间的空白与行内块的幽灵空白问题

作者:WangMin 格言:努力做好自己喜欢的每一件事 CSDN原创文章 博客地址 &#x1f449; WangMin 我们在开发的过程中&#xff0c;难免会出现一些难以预料的问题。那么其中&#xff0c;CSS空白现象就是非常常见的问题之一。虽然它已经被发现很久&#xff0c;但仍然有许多新手和经…

Redis中的List类型

目录 List类型的命令 lpush lpushx rpush lrange lpop rpop lindex linsert llen lrem ltrim lset 阻塞命令 阻塞命令的使用场景 1.针对一个非空的列表进行操作 2.针对一个空的列表进行操作 3.针对多个key进行操作. 内部编码 lisi类型的应用场景 存储(班级…

智慧工厂人员定位系统及uwb定位技术在现代工厂安全管理中的应用【uwb定位系统源码】

uwb定位系统源码 智慧工厂人员定位系统源码 定位系统源码 随着经济的高速发展&#xff0c;现代制造业规模不断扩大&#xff0c;生产车间面积广阔&#xff0c;生产设备日益繁多&#xff0c;生产工人数量多且分散作业&#xff0c;难以进行有效管理和实施全方位风险管控。现代工厂…

C++查漏补缺与新标准(C++20,C++17,C++11)01 C++快速回顾(一)

本内容参考C20高级编程 模块导入 C 20提供了对于模块的支持&#xff0c;用来代替之前的头文件机制 //Helloworld.cpp import <iostream>int main(){std::cout<<"Hello World!"<<std::end;return 0; }如果在你的编译器中尚未支持模块&#xff0c…

大数据之陌陌聊天数据分析案例

目录 目标需求 数据内容 基于Hive数仓实现需求开发 1.建库建表、加载数据 2.ETL数据清洗 3需求指标统计 目标需求 基于Hadoop和hive实现聊天数据统计分析&#xff0c;构建聊天数据分析报表 1.统计今日总消息量 2.统计今日每小时消息量&#xff0c;发送和接收用户数 3.…

分隔节点(C++解法)

题目 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输…

JavaScript 自定义对象

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>JS-定义对象</title> </head><body&g…

leetCode 322.零钱兑换 完全背包 + 动态规划 + 记忆化搜索 + 递推 + 空间优化 + 画递归树

关于此题我的往期文章&#xff1a;LeetCode 322.零钱兑换 完全背包 动态规划_呵呵哒(&#xffe3;▽&#xffe3;)"的博客-CSDN博客https://heheda.blog.csdn.net/article/details/133386579看本期文章时&#xff0c;可以先回顾一下动态规划入门知识和完全背包理论和实战…