一、由源码到可执行程序的过程
- 源码.c-(编译)->elf可执行程序
- 源代码.c-(编译)->目标文件.o-(链接)->elf可执行程序
- 源代码.c-(编译)->汇编文件.s-(汇编)->目标文件.o-(链接)->elf可执行程序
- 源代码.c-(预处理)->预处理过的.i-(编译)->汇编文件.s-(汇编)->目标文件.o-(链接)->elf可执行程序
- 预处理用的是预处理器,汇编用的是汇编器,链接用的是链接器。合起来叫编译工具链。gcc就是编译工具链。
二、预处理的意义
- 编译器本身主要目的是编译源代码,将c的源代码转化成.s的汇编代码。编译器聚焦核心功能后剥离出了一些非核心的功能给预处理器。
- 预处理器帮编译器做些编译前的杂事。
三、编码中常见的预处理
#include <>
//和
#include “”
#if
#elif
#endif
#ifdef
- 宏定义
四、gcc中只预处理不编译的方法
- gcc编译时可以给一些参数做一些设置,譬如gcc xx.c-o xx可指定可执行程序的名字;比如gcc xx.c-c-o xx.o可指定只编译不链接,可以生成.o的目标文件。
- gcc-E xx.c-o xx.i,可以实现只预处理不编译。-o的意思是文件命名。可以帮助debug程序。
#define pchar char*
#typedef char* PCHAR
int main(void)
{
pchar p1;
pchar p2,p3;
PCHAR p4,p5;
return 0;
}
经过预处理后:
#typedef char* PCHAR
int main(void)
{
char* p1;
char* p2,p3;
PCHAR p4,p5;
return 0;
}
- 宏定义语句本身不见了,可见在编译器这个层次根本不知道还有个宏定义。宏定义在预处理就完成了。
- typedef重定义语句还在,说明重命名和宏定义有本质区别。重定义是在编译器中完成的。
- 预处理后pchar完全被char*替代了。