如何使用##运算符连接和评估宏

时间:2019-04-16 13:03:26

标签: c macros

我写了这样的c代码

#include<stdio.h>
#include<stdint.h>
#define CHAN(n) ((0x8020##4+n) ## 20)
void main()
{
     int n = any_value;
     printf("%x",CHAN(n));
}

我收到编译错误pasting ")" and "20" does not give a valid preprocessing token

实际上,我想用值n计算表达式。因此,假设我将n的值传递为1而不是预期的输出0x8020520。同样,如果我将n的值作为8传递,比我期望的0x8020c20还要大。

如果我从宏中删除##20,则没有得到任何编译错误,并且得到了预期的一半输出,如0x802050x8020c,我的问题是我找不到一种在表达式求值之后连接20的方法,即(0x8020##4+n)##20。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

当您执行(0x8020##4+n)时,它将被解析为以下标记:“(”,“ 0x8020” ##“ 4”,“ +”,“ n”,“)”。

将“ 0x8020”和“ 4”粘贴在一起后,您将得到( 0x80204 + n )。粘贴前实际上并不会添加n。 (这怎么可能?预处理器不知道变量是什么,它认为“ n”只是一个长度为1的字符串)

当您执行) ## 20时,将得到无效的令牌“)20”,这是没有意义的。因此它正确地引发了错误。

似乎您想用n的值替换一个十六进制数字。您可以通过按位操作轻松地做到这一点:

 #define CHAN(n) (0x8020020 | ((4 + n) << 8))
 //                     ^

(当移位将由(4 + n)表示的单个十六进制数字移动到第二位的值时,|(按位或)将替换指示的0。