Linux系统上C程序的编译与调试
一、环境配置
在Linux操作系统(ubuntu)中,打开终端,以管理员root模式登录
1.更新:输入命令apt update
2.下载vim:输入命令apt install vim -y
3.下载gcc:输入命令apt install gcc -y
4.下载g++:输入命令apt install g++ -y
5.下载make:输入命令apt install make -y
安装成功:
二、建立c程序
【例1】输出Hello word!
1.先在进入自己要建立文件的目录,然后建立一个.c
文件:
比如说,这里建立一个main.c文件
2.通过vi,打开main.c文件vi main.c
(1)进入vi,此时处于命令模式,命令模式,不可以进行一般输入操作。
(2)输入i
进入插入模式
示例:
处于插入模式时,可以进行输入操作:
输入完成之后,按Esc返回命令模式:
(3)输入:
进入末行模式:
(4)输入wq,按回车保存退出:
三、编译C程序
当在main.c中写入一段代码之后,在终端输入gcc -o main main.c
去编译main.c文件:
这时,可以看到在当前目录下,生成了一个可执行程序main,当我们用ls -l
去查看的时候,发现这个生成的文件具有可执行权限,也就是说它可以运行。
四、执行C程序
输入可执行程序的路径就可以执行所要执行的C程序:
相当于:
五、c程序的编译链接过程
c语言的源程序的后缀必须为.c
,源文件是在硬盘上存放着它可以持久存储。C语言.c
程序是无法直接执行的,必须要经过编译链接生成一个能够在计算机上执行的二进制可执行程序,这样才能运行这个二进制可执行程序。可以通过gcc -o main main.c
将无法执行的.c
程序转换为可执行的二进制程序main。
程序编译的过程分为4步:预编译、编译、汇编和链接。通过这四步将高级语言翻译成机器指令(二进制),在计算机上可以直接执行的就是最终的二进制机器指令。
【例】进入vi写一个初始化数组的C语言代码并保存
1.预编译阶段
(1)删除所有的“#define”,并且展开所有的宏定义;
(2)处理所有的条件预编译指令,“#if”、“#ifdef”、“#endif”等;
(3)处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置;
(4)删除所有的注释;
(5)添加行号和文件名标识,以便于编译器产生调试用的符号信息及编译时产生编译错误和警告时显示行号;
(6)保留所有的#pragma编译器指令,因为编译器需要使用它们。
示例:
在删除main文件之后,预编译当前的main.c文件,通过gcc -E main.c -o main.i
预编译main.c文件并显示结果,可以看到main.i文件被生成了:
通过vi打开这个main.i文件:
可以看到include文件被全部展开,宏被也被展开,注释也被删除了
2.编译阶段
词法分析、语法分析、语义分析,代码优化,汇总符号。
示例:
通过gcc -S main.i -o main.s
,将预编译生成的文件main.i转换为编译完成的文件main.s,并用vi打开这个main.s文件:
main.s文件中都是汇编代码:
3.汇编阶段
将汇编指令翻译成二进制格式,生成各个section,生成符号表。
示例:
通过gcc -c main.s -o main.o
,将编译阶段生成的文件main.s转换为汇编完成的二进制机器指令main.o,并用vi打开这个main.o文件:
main.o文件是二进制机器指令:
上图中的ELF是该文件的格式。
main.o虽然是二进制指令文件,但是不可以执行,因为当前的main.o是把我们自己写的main.c文件翻译成了二进制的指令,main.o此时只是我们整个程序的一部分,因为我们自己写的代码用到了别人的许多代码,比如说priintf
,是我们没有自己实现的,#include<stdio.h>
中只是放了printf
的声明,printf
的实现是在C的库函数中,所以最后要将它链接过来,才可以运行起来。因此,最终的可执行程序除了自己已经写的代码以外,还链接了一些都会用到的基础代码。库里边放的其实就是已经编译好的.o
文件。
4.链接阶段
(1)合并各个section,调整section的起始位移和段大小,合并符号表,进行符号解析,给符号分配虚拟地址 .
(2)符号重定位 。
示例:
通过gcc -o main main.o
,将汇编阶段生成的文件main.o转换二进制可执行程序,并用vi打开这个main文件:
main文件是二进制可执行文件:
六、一般的编译写法
1.两步走
先通过gcc -c main.c
一步生成.o
文件,然后再通过gcc -o main main.o
把.o
文件转换为可执行文件main,并执行它:
2.一步走
直接通过gcc -o main main.c
一步生成可执行文件main,并执行:
更多推荐
所有评论(0)