Linux -- 认识gcc/g++、代码的编译过程

目录

前言:

使用 gcc/g++:

代码的编译过程: 

预处理:

头文件展开:

宏替换+去注释: 

​编辑

条件编译: 

编译:

汇编:

链接:

动态库(动态链接):

静态库(静态链接):


前言:

我们写完一段源代码后,需要让代码跑起来,在Linux中,我们使用 gcc/g++来编译C语言/C++代码。

使用 gcc/g++:

我们现在新建了一个文件,且代码如下:

 gcc  [ 源代码文件名 ] 就可以对指定的代码文件进行编译,编译时会生成一个可执行程序,如果没有为可执行程序命名,默认文件名为 a.out,运行 a.out ,就会运行我们所写的代码!

我们也可以为可执行程序命名,gcc  [ 源代码文件名 ]  -o   [ 可执行程序文件名 ]

-o 后接目标文件

g++ 的使用方法和 gcc 相同,这里不再赘述。

需要区别的是,gcc只能编译 C语言 ,g++可以编译 C语言 和 C++!

代码的编译过程: 

预处理:

预处理时,会对代码进行宏替换、去掉注释、条件编译、头文件展开,如果想查看预处理后的代码,以 gcc 为例:gcc  -E  test.c  -o  test.i ,就可以把预处理后的代码存放到指定的文件中,注意,目标文件后缀为 .i 。

-E 表示从现在开始进行程序的预处理过程,当预处理工作结束后,就停下来,不再进行后续的工作! 

头文件展开:

虽然我们原来的代码只有15行,经过头文件展开后,代码行数已经达到851行!

宏替换+去注释: 

如果代码中有注释和宏定义,预处理时,会进行宏替换和删除注释,通过下面的对比可以看出: 

条件编译: 

由于宏定义时只定义了VERSION1,在条件编译时,只有VERSION1的代码保留下来,其余未定义的全部被动态裁剪了!若只定义了VERSION2,或者没有宏定义,也同理!

可以看出,预处理时,可以对代码进行编辑和裁剪。

我们也可以在预处理的指令中进行宏定义, 即使在源代码中我们没有定义 VERSION1,但我们在指令中定义了,效果和在源代码中定义相同!

指令: gcc -E  test.c  -o  test.i  -D  VERSION1=1

条件编译可以防止头文件重复包含!头文件重复包含,会导致头文件展开时,代码量太大,导致编译效率低下!我们需要规避头文件重复包含!这是个好的编程习惯。  

#ifndef _NAME_H
#define _NAME_H
//头文件内容
#endif

这里的 _NAME_H 可以是自定义的宏,这里的宏应为独一无二的,不可以与文件中的其他宏的名字相同!

# ifndef _NAME_H (if not define _NAME_H )

1、如果宏_NAME_H未定义,那么就会走 #define _NAME_H 语句,定义宏 _NAME_H,并且引入头文件

2、如果宏_NAME_H已经定义了,则不会走 #define _NAME_H 语句,直接进入#endif,不引入头文件

编译:

编译时,把代码转为汇编语言

-S:从现在开始进行程序的编译,当编译工作完成,就停下来!

形成汇编文件,可以直接在预处理的文件上进行编译,也可以直接在源代码上进行编译,即两种写法:gcc  -S  test.c  -o  test.s  (在源代码上)或 gcc  -S  test.i  -o  test.s(在预处理后的文件上)。

汇编:

汇编时,把编译后生成的汇编语言转为二进制语言

-c :从现在开始进行程序的汇编,汇编工作结束后,就停下来!

同样可以在源代码的基础上进行汇编,也可以在编译文件上进行汇编! 

 转为二进制后,代码还不可以运行起来,即使开放了可执行权限,也是运行不起来的!

还需要最后一步--链接! 

链接:

直接 gcc test.o  -o  test 就可以进行链接,所谓链接,就是把代码和库文件进行链接,默认与动态库进行链接

 ldd 可以查看代码和动态库还是静态库产生链接

在 Linux 中,动态库以 .so 结尾,静态库以 .a 结尾;

在Windows中,动态库以 .dll 结尾,静态库以 .lib 结尾。 

动态库(动态链接):

动态库在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入

程序运行时,如果我们需要调用 printf 函数, printf 函数会被修改为库函数中 printf 实现的地址,这时候动态链接就建立好了。

动态库也叫共享库。

优点:比较节省资源(内存资源、网络资源等),不会出现太多的重复的代码;

缺点:对库的依赖性比较强,一旦库丢失,所有依赖该库的程序都无法运行。

 用 file 命令查看文件类型时,可以看出代码是动态链接的:

静态库(静态链接):

编译链接时,把库文件的代码全部加入到可执行文件中

优点:可执行程序不依赖库,同类型平台中进行跨平台使用;

缺点:生成的文件比较大,比较浪费资源(占用内存--内存资源、网络传输时传输量大--网络资源等)。

代码默认与动态库链接,我们也可以让代码与静态库链接:

gcc -o mybin-static  test.c  -static 就可以让代码与静态库链接,但是系统是默认没有安装静态库的,此时静态链接会出错,我们需要在系统中下载静态库!

在普通用户下,sudo  yum  install  -y  glibc-static  libstdc++-static 就可以安装静态库。 

 安装完成后,用 ldd 和 file 命令可以看出,test-static 与静态库链接。

test 是动态链接的,test-static 是静态链接的,通过对比可以看出, 同样的源代码,静态链接的代码占用的空间比动态链接的大很多。

 

本文到这里就结束了,欢迎各位大佬的指正! 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高速公路事故检测数据集点亮智能交通:视频动作识别的崭新征程(目标检测)

亲爱的读者们,您是否在寻找某个特定的数据集,用于研究或项目实践?欢迎您在评论区留言,或者通过公众号私信告诉我,您想要的数据集的类型主题。小编会竭尽全力为您寻找,并在找到后第一时间与您分享。 引言 …

spring tx @Transactional 详解 `Advisor`、`Target`、`ProxyFactory

在Spring中,Transactional注解的处理涉及到多个关键组件,包括Advisor、Target、ProxyFactory等。下面是详细的解析和代码示例,解释这些组件是如何协同工作的。 1. 关键组件介绍 1.1 Advisor Advisor是一个Spring AOP的概念,它包…

射频硅基氮化镓:两个世界的最佳选择

当世界继续努力追求更高速的连接,并要求低延迟和高可靠性时,信息通信技术的能耗继续飙升。这些市场需求不仅将5G带到许多关键应用上,还对能源效率和性能提出了限制。5G网络性能目标对基础半导体器件提出了一系列新的要求,增加了对…

如何使用ParaView可视化工具来绘制点云数据的3D点云图像(亲测好用)

如何使用ParaView来绘制点云数据。以下是如何将你的数据导入ParaView并进行可视化的步骤 一、准备数据 首先,你需要将你的数据转换为ParaView可以读取的格式。ParaView支持多种文件格式,其中最常见的是.vtk和.csv格式。为了简单起见,这里我…

JFlash读取和烧录加密stm32程序

JFlash读取和烧录加密stm32程序 安装后JFlash所在的目录:C:\Program Files\SEGGER\JLink 一、烧写加密程序 1、打开C:\Program Files\SEGGER\JLink目录,找到JFlash.exe,双击它,就可以打开该执行程序。见下图: 2、选择“Create …

华为eNSP:HCIA综合实验

一实验要求 HCIA综合实验的配置要求: 1.ISP路由器只能配置IP地址,之后不进行任何配置 2.内部整个网络基于192.168.1.0/24进行地址划分 3.R1/2之间启动OSPF协议,单区域 4.PC1-4自动获取IP地址 5.PC1-4,可以访问PC5,R2…

布隆过滤器 redis

一.为什么要用到布隆过滤器? 缓存穿透:查询一条不存在的数据,缓存中没有,则每次请求都打到数据库中,导致数据库瞬时请求压力过大,多见于爬虫恶性攻击因为布隆过滤器是二进制的数组,如果使用了它…

9.2 栅格图层符号化单波段灰度渲染

文章目录 前言单波段灰度QGis设置为单波段灰度二次开发代码实现单波段灰度 总结 前言 介绍栅格图层数据渲染之单波段灰度显示说明:文章中的示例代码均来自开源项目qgis_cpp_api_apps 单波段灰度 以“3420C_2010_327_RGB_LATLNG.tif”数据为例,在QGis中…

RTK_ROS_导航(2):卫星图查看

目录 1. 基于MapViz的卫星图查看 1. 基于MapViz的卫星图查看 安装 # 源码安装 mkdir -p RTK_VISION/src cd RTK_VISION/src git clone https://github.com/swri-robotics/mapviz.git --branchmelodic-eol sudo apt-get install ros-$ROS_DISTRO-mapviz ros-$ROS_DISTRO-mapviz-…

Idea-单个窗口导入并开启多个module项目

前言 大家是否有过这样的困扰,我们每次打开一个项目就需要单开一个idea窗口,项目少时了还好,一旦涉及多个项目间服务调用,特别是再包括网关、注册中心、前端web服务,需要开启的窗口就会是一大批,每次切换的…

B端全局导航:左侧还是顶部?不是随随便便,有依据在。

一、什么是全局导航 B端系统的全局导航是指在B端系统中的主要导航菜单,它通常位于系统的顶部或左侧,提供了系统中各个模块和功能的入口。全局导航菜单可以帮助用户快速找到和访问系统中的各个功能模块,提高系统的可用性和用户体验。 全局导航…

二叉树树的知识,选择➕编程

在一棵深度为7的完全二叉树中,可能有多少个结点?(1层深度为1,节点个数为1) 对于深度 d的完全二叉树: 完全二叉树中,前 d−1层是满的。 最后一层(第 d 层)可以不满&#x…

【vue3|第16期】初探Vue-Router与现代网页路由

日期:2024年7月6日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083…

前端工程师

15年前,前端主流的框架jquery,那个时候还没有前端工程师,后端开发人员既要写后台业务逻辑,又要写页面设计,还要应付IE不同版本浏览器兼容问题,非常的繁琐、难搞。 现在前端框架很多、很强大,前端开发工程师…

MySQL——第一次作业

部署MySQL 8.0环境 1,删除之前存在的MySQL程序 控制面板删除 2,删除完成后下载MySQL 官网: https://www.mysql.com 在window下下载MSI版本 3,自定义安装 4,配置环境变量 1,系统高级系统设置 2&#xff…

YOLOV8 + PYQT5单目测距—风险类别检测(五)

YOLOV8 PYQT5单目测距 1. 相关配置2. 测距源码3. PYQT环境配置4. 实验结果4.1 界面4.2 界面卡住解决方案 5. 实现效果 1. 相关配置 系统:win 10 YOLO版本:yolov8 拍摄视频设备:安卓手机 电脑显卡:NVIDIA 2080Ti(CPU也…

【Python】 已解决:ValueError: document with multiple roots

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决:ValueError: document with multiple roots 一、分析问题背景 在Python编程中,处理XML或HTML文档时,有时会遇到“ValueError: document …

安防监控视频平台LntonAIServer视频智能分析平台行人入侵检测算法

在当今社会,随着科技的迅速发展和安全需求的日益增长,行人入侵检测技术成为了安全防护领域的重要研究方向。LntonAIServer行人入侵检测算法作为该领域的先进技术之一,其性能和应用效果受到了广泛关注。 首先,从技术角度来看&#…

【线程安全】线程互斥的原理

文章目录 Linux线程互斥线程互斥相关概念互斥量mutex引出线程并发问题引出互斥锁、互斥量 互斥量的接口初始化互斥量销毁互斥量互斥量加锁和解锁使用互斥锁抢票 可重入和线程安全概念:常见线程不安全的情况常见线程安全的情况常见不可重入的情况常见可重入情况可重入…

中霖教育怎么样?中级经济师证书领取流程介绍

在成功通过中级经济师考试之后,需要等待约2到3个月的时间,会发布相关领证公告。 在准备材料方面,考生需确保携带以下文件:身份证件、学历证明以及工作年限的证明文件等,前往相应的人事考试局进行资格审核。 资格审核…