一、宏讲解
1、宏定义
宏(Macro),是一种批量处理的称谓。计算机科学里的宏是一种抽象(Abstraction),它根据一系列预定义的规则替换一定的文本模式。解释器或编译器在遇到宏时会自动进行这一模式替换。
2、C语言宏定义的常规用法
1) 定义符号常量
#define PI 3.1415926
#define MAX_N 10000
2) 定义傻瓜表达式(注意,定义的这种表达式一不小心很容易出现bug,下文会讲)
#define S(a, b) a * b
#define MAX(a, b) (a) > (b) ? (a) : (b)
3) 定义代码段
#define P(a) {\
printf("%d\n", a);}
ps:编译器对于宏的解析是很严谨的,只能支持一行解析,\是起连接作用,表示当行的宏代码与下一行宏连接在一起,使得编译器当成一行看待。
3、编译器预定义的宏
在C语言中,我们有很多预定义的宏,就是C语言帮程序员预先定义好的宏,可以让我们使用。
宏 说明
__DATE__ 日期:Mmm dd yyyy
__TIME__ 时间:hh:mm:ss
__LINE__ 当前源文件的代码行号
__FILE__ 文件名
__func__ 函数名/非标准
__FUNC__ 函数名/非标准
__PRETTY_FUNCTION__ 更详细的函数信息/非标准
4、预定义命令-条件式编译
函数 说明
#ifdef DEBUG 是否定义了DEBUG宏
#ifndef DEBUG 是否没有定义DEBUG宏
#if MAX_N == 5 宏MAX_N是否等于5
#elif MAX_N == 4 否则宏MAX_N是否等于4
#else
#endif
5、预定义命令
从上图可以看到:
预编译
将.c 文件转化成 .i文件
使用的gcc命令是:gcc –E
对应于预处理命令cpp
编译
将.c/.h文件转换成.s文件
使用的gcc命令是:gcc –S
对应于编译命令 cc –S
汇编
将.s 文件转化成 .o文件
使用的gcc 命令是:gcc –c
对应于汇编命令是 as
链接
将.o文件转化成可执行程序
使用的gcc 命令是: gcc
对应于链接命令是 ld
总结起来编译过程就上面的四个过程:预编译、编译、汇编、链接。这里我们主要讲预编译阶段,不去细究其他阶段,具体细节可以去看编译原理的书本。
而我们这里只讲预定义,也就是说,我们可以通过预编译生成的编译源码去看我们的宏替换后有没有符合我们的预期,下面会实际操作。
二、宏使用
上文,我们知道了宏的三种用法,分别如下:
1) 定义符号常量
2) 定义傻瓜表达式
3) 定义代码段
例子一:
定义一个宏,表示一年有多少秒?
//seconds.c #include <stdio.h> #define SEC_OF_A_YEAR (365 * 24 * 60 * 60) int main(void) { printf("%d\n", SEC_OF_A_YEAR); return 0; }
我们对源码进行预编译操作,顺便去查看预编译后的结果,如下
ydq@ubuntu:macro$ gcc -E seconds.c > seconds.txt ydq@ubuntu:macro$ tail seconds.txt # 2 "seconds.c" 2 # 4 "seconds.c" int main(void) { printf("%d\n", (365 * 24 * 60 * 60)); return 0; } ydq@ubuntu:macro$
可以看到预编译后,我们的宏SEC_OF_YEAR被替换成了(365 * 24 * 60 * 60),所以我们可以得知,宏定义在预编译后只是进行了简单的代码替换,这其实对于新手来说,是很危险的。
例子二:
请事先一个没有bug的MAX(a, b)宏,需要通过如下测试:
1、MAX(2, 3)
2、5 + MAX(2, 3);
3、MAX(2, MAX(3, 4))
4、MAX(2, 3 > 4 ? 3 : 4)
5、MAX(a++, 6)a的初值为7,函数返回值为7,a的值编程8。
验证1:
1 //max_version1.c 2 #include <stdio.h> 3 #define MAX(a, b) a > b ? a : b 4 5 int main(void) { 6 printf("MAX(%d, %d) = %d\n", 2, 3, MAX(2, 3)); 7 return 0; 8 }
ydq@ubuntu:macro$ gcc max_version1.c ydq@ubuntu:macro$ ./a.out MAX(2, 3) = 3
由结果得出验证通过,那么我们接着下来在该代码基础上,继续验证2.
1 //max_version2.c 2 #include <stdio.h> 3 #define MAX(a, b) a > b ? a : b 4 5 int main(void) { 6 printf("MAX(%d, %d) = %d\n", 2, 3, MAX(2, 3)); 7 printf("%d + MAX(%d, %d) = %d\n", 5, 2, 3, 5 + MAX(2, 3)); 8 return 0; 9 }
ydq@ubuntu:macro$ gcc max_version2.c ydq@ubuntu:macro$ ./a.out MAX(2, 3) = 3 5 + MAX(2, 3) = 2
原文:https://www.cnblogs.com/ydqblogs/p/13916906.html