目录
我们知道,一个程序想要跑起来必须经过 预处理、编译、汇编、链接这四个过程,将文本转化为计算机能识别的机器语言(二进制),才能生成可执行程序进行运行。那么在Linux下,gcc/g++是怎么完成这些操作的呢:
也可以用-o选项生成我们指定的可执行程序(链接)
-o:保留源文件,让编译器生成一个我们自己命名的可执行程序:
在gcc中,上述操作直接帮助我跳过了诸多步骤,若我们想详细查看一下程序的编译过程,gcc也是为我们提供了对应方法:
预处理功能主要包括宏替换,头文件展开,条件编译,去注释等
命令:gcc –E test.c –o test.i
-E:该选项的作用是让 gcc 在预处理结束后停止编译过程。
-o:是指目标文件,“.i”文件为已经过预处理的C原始程序
用vim打开test.c文件,底行模式输入:vs test.i,分屏查看:
ctrl + ww:实现两个文件间光标的切换
shift + b、shift +f 实现快速翻页
头文件能够展开的前提是,此头文件有路径保存,且编译器能够通路径找到此头文件
一般的头文件都在 /usr/include/ 目录下,用 ls 查看:
gcc 首先要检查代码的规范性、是否有语法错误等,在检查无误后,gcc 把代码翻译成汇编语言
命令:gcc –S test.i –o test.s
-S:该选项只进行编译而不进行汇编,生成汇编代码
这些都是汇编指令,我们在这里只需知道大致过程,不对这些文件做深入探讨。
汇编阶段是把编译阶段生成的".s"文件转成目标".o"文件--可重定位的目标文件
命令:gcc –c test.s –o test.o
-c:该选项只进行汇编,对程序进行翻译,然后停止,不进行链接
从开始到这一步,我们是对我们写的代码进行操作,写过函数的伙伴都知道,先实现才能调用。我们文本中用了打印函数 printf ,但我们并没有实现它,那么它在哪?怎样才能让它和我们写的ptintf 函数的调用产生联系?
不需要我们写的,可以直接调用的函数,都在C标准库中:
最后一步就是回答上一步问题:
-o:将我们写的调用函数与库中函数的实现产生链接
命令:gcc test.o –o mytest
查看可执行文件依赖的库:
一般链接过程中,默认用到的库是动态库,后缀为.so
优点:大家共享一个库,可以节省资源
缺点:一旦库确实,会导致几乎所有程序失效
将库中的相关代码,直接拷贝到自己的可执行程序中
如果我们想静态链接,在链接步骤后加 -static,静态库后缀为.a:
命令:gcc test.o -o mytest2 -static
优点:不依赖任何库,程序可独立运行
缺点:浪费资源
安装c语言的静态库:yum install -y glibc-static
安装c++的静态库:yum install -y libstdc++-static
创建新的文件,求10以内数的累加和:
我们可以看到给我们的提示:未找到调试符号
Linux默认生成的可执行程序是release版本,不支持调试,我们要先将可执行程序变成可调试的debug版本:
停到断点处,没有断点直接运行完程序
若有函数情况下,想要进入函数则继续s即可,不想要进入函数则n,n是逐过程执行。
用p查看变量后,再次逐语句或者逐过程执行后,不会再显示出变量,这需要我们再次用p查看,想要做到和vs下监视窗口一样的话,就需要用到display
如果我们进入到循环后,想跳出循环的话,一种方法就是一直走完循环,想快速跳过,可以
until+ 行数 :
执行完一个函数停止,跟我们上述的 until 跳转行的功能很像,当我们进入一个函数中,想要快速执行完这个函数,可以选择用 until + 行数,也可以选择直接 finish