- 一:C/C++程序程序编译过程
- (1)预处理
- (2)编译
- (3)汇编
- (4)链接
- 二:宏定义
- (1)数值宏常量
- (2)字符串宏常量
- (3)使用宏充当注释
- (4)使用宏充当表达式
- 三:宏其他
- 四:条件编译
- (1)#ifdef和#ifndef
- (2)#if
- 预处理主要包括宏定义,文件包含,条件编译,去注释
- 输入gcc -E hello.c -o hello.i,其中选项E作用是让gcc在预处理后停止编译
- 此阶段,gcc检查代码的规范性,是否具有语法错误
- 输入gcc -S hello.i -o hello.s,即可将预处理里的结果继续继续编译
- 编译阶段无误后,进入汇编,将“.s”文件转化为“.o”二进制文件
- 输入gcc -c hello.s -o hello.o,即可将编译停止在此阶段
(打开二进制文件使用od命令)
- 此阶段,将目标文件与系统库进行链接生成可执行文件。
- 输入gcc hello.o -o hello,则完成编译
| 选项 | 描述 |
|---|---|
| -E | 进行预处理,不进行编译,汇编和链接 |
| -S | 进行编译,不进行汇编和链接 |
| -c | 进行汇编,不进行链接 |
| -o | 链接 |
| static | 采用静态链接 |
| -g | 生成调试信息 |
| -shared | 使用动态库 |
| -O0 | 无优化 |
| -O1 | 默认优化级别 |
| -O3 | 优化最高 |
| -w | 不生成警告信息 |
| -Wall | 生成所有警告信息 |
略
(2)字符串宏常量略
(3)使用宏充当注释先去掉注释,再进行宏替换
(4)使用宏充当表达式#define SUM(X) (X)+(X)
int main()
{
printf("%dn", SUM(10));
return 0;
}
需要注意使用宏充当多条语句时有可能出现一些潜在的问题,比如下面这个宏有两条语句,但是在if后面如果直接跟上宏而没有带花括号就会出现问题
#define INT_VAL(a,b) a=0;b=0
如果需要宏替换大块语句,可以使用do-while(0)结构
#define GIVE_VALUE(a,b) do{a=0;b=0;}while(0)
int main()
{
int x = 10;
int y = 20;
int flag = 0;
scanf("%d", &flag);
printf("before:%d,%dn", x,y);
if (flag)
GIVE_VALUE(x, y);
else
x = 10, y = 20;
printf("after:%d,%dn", x, y);
}
三:宏其他
第一: 宏定义在文件的任何位置都可以,只要是在你使用这个宏之前定义就可以
void show()
{
#define M 10
printf("show:%dn", M);
}
int main()
{
show();
printf("main:%dn", M);
return 0;
}
第二 可以使用#undef来结束宏的作用
int main()
{
#define M 10//从这里开始
printf("main:%dn", M);
printf("main:%dn", M);
printf("main:%dn", M);
#undef M//到这里结束
printf("main:%dn", M);//错误
return 0;
}
四:条件编译
(1)#ifdef和#ifndef
- ifdef:判定宏是否被定义,宏为真假没有关系,倾向于要定义,
- ifndef:判定宏是否没有定义,宏为真假没有关系,倾向于不要定义
下面的例子中没有定义PRINT,所以代码只会保留#else这一部分,代码在预处理时直接被裁掉
int main()
{
#ifdef PRINT//实际未定义
printf("hellon");
#else
printf("no printn");
#endif
return 0;
}
如果PRINT被定义了,然后换成ifndef,效果也是一样的
#define PRINT//宏被定义
int main()
{
#ifndef PRINT//如果没有定义
printf("hellon");
#else
printf("no printn");
#endif
printf("continuen");
return 0;
}
(2)#if
- #if:判定是否存在,以及是否为真,倾向于存在且为真
如下宏PRINT,被定义了但是为0,因此会输出#else里面内容
# define PRINT 0//定义了但是为假
int main()
{
#if PRINT
printf("hellon");
#else PRINT
printf("other");
#endif
return 0;
}
#if可以进行多分支控制
#define HELLO 2
//注意这里使用的是==,像!=,<,>等可以使用
int main()
{
#if HELLO==1
printf("hello1n");
#elif HELLO==2
printf("hello2n");
#elif HELLO==3
printf("hello3n");
#else
printf("othern");
#endif
return 0;
}
如果要判断多个宏,可以这样进行
#define Condition1 1
#define Condition2 0
int main()
{
#if Condition1 && Condition2
printf("alln");
#else
printf("othern");
#endif
return 0;
}



