#define 定义宏
#deifine机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或宏定义(define macro)
宏的声明方式:
#define name(parament-list) stuff
其中的parament-list
是一个由逗号隔开的符号表,他们可能出现在stuff中
比如:
#define ADD(a,b) a + b
// 这个宏接收两个参数 a,b
注意:参数列表的左括号必须与name紧邻
如果两者之间存在有任何的空白,参数列表就会被解释为stuff的一部分
还有一个注意点:
#define SQUARE(X) X*X
int ret = SQUARE(5+1); // 结果是11,而不是预想的36
因为对于宏来说,他的参数不是传参,而是替换
所以结果是5+1完整替换过去
,5+1*5+1
—> 11
如果我们希望这个 5+1是个整体,我们可以在定义宏的时候加上括号 #define SQUARE(X) (X)*(X)
#define DOUBLE(x) (x)+(x)
int a = 5;
int ret = 10*DOUBLE(a); //发现这个结果也不对
// 因为外面的*的优先级高于这个
// 正确写法是 #defiine DOUBLE(x) ((x)+(x))
综上,我们定义宏的时候,一定不可以吝啬括号
#define替换规则
在程序中扩展#define定义符号和宏时,需要涉及几个步骤:
- 在调用宏时,首先对参数进行检查,看看是否包含任何由 #define 定义的符号。如果有,他们首先被替换
- 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值替换
- 最后,再次对结果文件进行扫描,看看它是否包含任何由 #define 定义的符号。如果是,就重复上述过程
注意:
-
宏参数和 #define 定义中可以出现其他 #define 定义的变量。但是对于宏,不能出现递归
-
当预处理器搜索 # define 定义的符号的时候,字符串常量的内容不被搜索
printf("MAX = %d \n", MAX);
字符串里的MAX是不会被搜索替换的
# 和 ##
如何把参数插入到字符串中?
比如有这样的一个函数
void print(int a)
{
printf("the value of a is %d\n", a);
}
int a = 10;
int b = 20;
print(a); // the value of a is 10
print(b); // the value of a is 20
// 虽然后面的值替换了,但是字符串中 a 并没有被替换成b
这个时候就需要用到 # 和 ##这两个操作符了
在宏定义中
#define PRINT(X) printf("the value of" #X "is %d\n", X)
这里的 #X ,当X被传递过来的时候,会给他加上""
PRINT(a);---> the value of a is 10;
// printf("the value of" "a" "is %d\n", a)
PRINT(b);---> the value of b is 20;
// printf("the value of" "b" "is %d\n", a)
也就是在宏参数前面加上 # 不会把参数替换为参数的值,而是给这个参数名本身,加上""
## 可以把位于它两边的符号合成一个符号。它允许宏定义从分离的文本片段创建标识符
#define ADD_TO_SUM(num, value)
sum##num += value;
ADD_TO_SUM(5, 10); // 作用是 给sum5 增加10
#define CAT(X,Y) X##Y
int tempValue = 10;
// printf("%d\n", tempValue);
// ## 就是进行把 temp Value 进行拼接的
// temp##Value == tempValue
printf("%d\n", CAT(temp, Value));
利用gcc test.c -E > test.i
,查看 test.i
可以看出编译之后的文件,就是temp##Value
被替换成了tempValue