预处理
预处理:编译之前对源代码进行“规范化”处理,包括:处理包含的头文件,条件编译(表达式成立,包含此段代码),宏替换等,主要是对在编译之前对源文件根据预处理指令
(如:#include、#define、#undef、#ifdef、#ifndef等)进行相应处理。
预处理 - gcc编译指令
# gcc -E 源文件(如:hello.c) -o 目标文件(hello.i)
gcc -E hello.c -o hello.i
以上编译指令是对hello.c
文件进行预处理生成hello.i
文件。-E
表示预处理,-o
指定生成的目标文件名。
预处理 - 宏展开
给定hello.h
,内容如下:
#define EXPR (1 + 1)
给定hello.c
,内容如下:
#include "hello.h"
int main(int argc, char** argv)
{
int a = EXPR;
return 0;
}
使用gcc -E hello.c -o hello.i
生成预处理之后的文件hello.i
,之后通过cat hello.i
命令查看hello.i
的内容。可以发现hello.c
文件中的EXPR内容被替换成了(1 + 1)
,即预处理完成后,宏会被展开,但是hello.i
文件中并没有出现 #define EXPR (1+1)
,说明 #include "hello.h"
并不是简简单单的一种文件“引入”。详细的情况如下:
预处理 - #include
给定hello.h
,内容如下:
void hello()
{
}
给定hello.c
,内容如下:
#include "hello.h"
int main(int argc, char** argv)
{
return 0;
}
使用gcc -E hello.c -o hello.i
生成预处理之后的文件hello.i
,之后通过cat hello.i
命令查看hello.i
的内容。可以发现,头文件中定义的函数在hello.i
中出现,说明经过预处理之后,头文件中定义函数通过 #include
被引入,更详细信息,请查看下方图片:
预处理 - #ifdef
、#ifnef
、#endif
给定hello.h
,内容如下:
#ifdef HELLO1
void hello1();
#else
void world1();
#endif
#ifndef HELLO2
void hello2();
#else
void world2();
#endif
给定hello.c
,内容如下:
#define HELLO1 hello1
#include "hello.h"
int main(int argc, char** argv)
{
return 0;
}
使用gcc -E hello.c -o hello.i
生成预处理之后的文件hello.i
,之后通过cat hello.i
命令查看hello.i
的内容。发现通过#define
,#ifnef
,#else
,#endif
等,可以控制是否保留某段代码