在windows下的开发环境是集成开发环境,编译链接过程一键就可做到,而在linux下的操作都是离散的,对于编译链接的认识是建立在linux环境基础之上的;电脑只能识别二进制序列,而我们的代码是利用c语言写的,需要转换位机器所能识别的二进制序列,编译链接过程就是将代码转换成机器所能识别的二进制序列(目标文件)并生成可执行文件的过程。
整个过程为:
1.预处理
在此步骤对代码进行预处理:头文件展开,宏替换,去注释,条件编译;
gcc -E test.c -o test.i
此命令是对test.c进行到预处理,并将处理结果放到test.i中。
2.c代码转换为汇编;
gcc -S test.i -o tets.s
此命令是对test.i进行汇编转换,并将汇编转换结果放入test.s中。
3.汇编——>二进制;
gcc -c test.s -o test.o
此处test.o是目标文件,其中存放的是二进制序列;
4.链接
链接所有二进制程序,生成可执行文件。
头文件展开:展开为头文件所在的绝对地址,在linux下#include<stdio.h>展开为"/usr/include/stdio.h"
宏替换:出现宏标识符的位置,替换为其定义式标识符后面的文本;
例:
#define PRINT printf("Replace\n")
int main()
{
PRINT;
return 0;
}
替换后为:
#include<stdio.h>
#define PRINT printf("Replace\n")
int main()
{
PRINT;
return 0;
}
去注释:在预处理阶段,相当于直接将注释的这部分代码剔除掉,不出现在test.i文件中;
条件编译:
在编译程序时,使用条件编译可以实现某条语句或某组语句进行编译或者忽略;条件编译常常用于调试程序;
条件编译的基本结构为:
#if 常量表达式
语句;
#endif
和if语句一样也可以嵌套使用
如果常量表达式的值为非零值(真),正常执行语句部分,否则这部分就像去掉注释掉一样,不出现在文件中;
#ifdef MIN
语句;
#endif
如果MIN这个宏已被定义就执行语句部分,如果没有定义,就删除语句部分(即这部分不进行编译);
例:
#include<stdio.h>
//#define DEBUG
int main()
{
#ifdef DEBUG
printf("DEBUG\n");
#endif
return 0;
}
DEBUG没有被定义,在预处理时,将printf();语句删除,即下面这样:
int main()
{
return 0;
}
若定义了DEBUG这个宏,在预处理后为:
int main()
{
printf("DEBUG\n");
return 0;
}