之前我们说对一个源文件进行编译,其实上述可以细分为四个步骤,预处理(预编译),编译,汇编,链接
命令如下:
(1)预处理 (-E(大写))
gcc -E main.c -o mian.i
(2)编译(-S(大写))
gcc -S main.i -o mian.s
(3)汇编(-c(小写))
gcc -c main.s -o main.o
(4)链接(-o 指定生成的文件名)
gcc main.o
3.一步编译 3.1 上述四个步骤可以通过一行代码完成
命令如下:gcc main.c
3.2 上述前三个步骤可以通过一行代码完成命令如下:gcc -c main.c
4.编译后执行编译后生成的可执行文件,例如a.out可以用过./a.out去启动,但是如果不加“./”,想让a.out像pwd,ls一样去执行,则显示错误,说未找到命令,这时怎么办?
我们发现,pwd,ls可以直接执行,因为他们在标准路径下有备份,那么我们如果也将a.out放到标准路径下/usr/bin,是否可以达到相同的效果?
5.编译链接过程 6.g++上述一般“.c”文件是通过gcc去编译,而“.cpp”文件使用过g++那么“.cpp”有几种方法编译:
第一种:通过g++进行编译 那么命令如下:g++ main.c
第二种:通过gcc进行编译
-l :library:表示链接的库名称,注意:-l和库名中间不要加空格
7.makefile文件和make命令 1.安装和以往的gcc,g++同一个操作
2.makefile文件和make命令的介绍由于一个大型项目工程中有大量的源文件,个人编译起来容易漏一个,这个时候就可以使用makefile文件,makefile文件利用定义了一系列的规则来帮助我们去管理这些源文件,指定了哪些文件先进行编译,哪些源文件后进行编译,哪些文件被修改了,需要重新编译。
make命令:解释makefile文件,执行对应的操作
示例如下:
假设这里有三个源文件:main.c max.c add.c
接下来:对其进行编译:
假设,这里不是三个源文件,而是100个,自己编译容易漏,并且如果我们修改其中的一部分源文件,那么我们应该只对其中修改过的源文件进行重新编译最合理的,这里makefile文件可以完美达到我们的需求。
makefile具体代码实现:
通过make命令运行一下makefile文件:
如果需要保证编译后的整洁,则可以在makefile的最后加上clean:
8.gdb调试 8.1 Debug版本和Release版本
Debug版本,是可调式版本,具有调试信息。
Debug版本如何生成:gcc默认生成的是release版本,如果需要手动添加参数-g
命令格式如下:
第一种:gcc -c main.c -g(生成具有调试信息的中间文件main.o),再通过命令gcc -o main main.o
第二种:gcc -o main main.c -g
8.2 gdb应用测试文件:main.c
通过gcc -o main main.c -g 一步生成具有可调式信息的可执行文件:
运行起来,发现输入“end”的时候,正常退出不了:
这时,我们用gdb调试一下可执行文件main,找一下问题所在:
命令:
l //显示当前文件的源代码(默认一次显示10行)
list filename: num //显示具体指定的文件的num行附近的代码
b 行号 //给执定行下断点
info break //查看所有断点信息
delete 断点编号 //删除断点
r(run)//启动程序
q:退出调试
n:next//单步执行,逐过程 相当vs里面的F10p buff //临时打印指定数组中的内容
p val //临时打印指定变量中的内容
p &val//临时打印指定变量的地址
p *parr@num
display buff//一直跟踪buff,具体使用规则和上述的p一致
info display//显示所有的跟踪对象
undisplay 编号//取消对应编号的跟踪
s //进入到函数中 逐语句 相当于vs里面的F11
finish //跳出函数 相当于vs里面的shift+f11
c //continue 继续执行到下一个断点
ptype val //查看变量的类型
此时,发现问题,在于fgets将回车也获取了:
这时,输入end就可以正常退出了。
GDB总结:l //显示当前文件的源代码
list filename:num //显示filename文件中第num行附近的的源代码
b 行号 //给指定行添加断点
info break //显示所有断点信息
delete 断点编号 //删除对应断点
r (run)//启动程序
q //退出调试
p buff //临时打印数组所有元素的值
p val //临时打印变量val的值
p &val //临时打印变量val 的地址
p a+b //临时打印表达式的值
p *parr@num //通过指向数组的指针打印数组的元素值
display buff //自动显示监视对象,操作格式和p一致
info display //显示所有自动显示监视对象的信息
undisplay 编号 //删除对应的自动显示监视对象
n (next) //单步执行 逐过程(vs里面F10)
s //进入到将被调用的函数中(逐语句 vs里面F11)
finish //跳出函数(跳出 vs里面shift+ F11)
c (continue) //继续执行,直到执行到下一个断点出
ptype val //显示变量的数据类型



