25、#define定义宏(#define是如何替换的)

#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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今儿背单词吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值