嵌套宏的参数应该当做宏还是普通字符串

本文介绍了一种在C预处理器中使用宏定义实现特定文本替换的方法,重点在于如何正确地将一个宏作为另一个带参数宏的参数,以实现预期的变量名连接效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自:http://www.cppblog.com/ownwaterloo/archive/2010/08/08/74219.html

 

/** 问题描述: */

/* 定义一个带参数的宏 */
#define setname(name) test##name

/* 用一段文本作为该宏的参数 */
int setname(1212) = 1212;
/* 该宏会被替换为:
int test1212 = 1212;
*/

/* 现在有另一个宏 */
#define var 326
/* 如何使用让宏var,作为另一个带参数的宏setnaem的参数? 即:
int setname(var) = 326;
被替换为:
int test326 = 326
而不是:
int testvar = 326;
*/

 

 

问题分析

需要注意:
I. 宏是作文本替换
II. 替换的终止条件是:文件中不再含有宏

对第9行的:SET_NAME(1212)
1. 首先根据I和第5行,SET_NAME(1212) 会被替换成:CONNECTION(test,1212)
2. CONNECTION依然是一个宏,根据II,继续替换
3. 根据I和第4行,CONNECTION(test,1212),被替换为 test1212
4. 所以第10行最终会被CPP替换成 "int test1212 = 1212;"

对第12行的:SET_NAME(VAR)
1. 首先根据I和第5行,SET_NAME(VAR)会被替换成:CONNECTION(test,VAR)
2. CONNECTIONVAR依然是一个宏,根据II,继续替换
3. 根据I和第11行,CONNECTION(test,VAR)被替换为CONNECTION(test,326)
4. 再根据I和第4行,CONNECTION(test,326)被替换为test326
5. 所以第12行最终会被CPP替换成 "int test326 = 326;"

对第16行的:SET_NAME(VAR),同第12行,最终会被替换成 test86



 

为什么setname不行?
setname(var) 会被替换成 testvar,而后者不再含有宏,替换终止

### 定义用于创建字符串变量 在C语言中,定义可以用来将任意表达式或值转化为字符串字面量。通过使用预处理器的 `#` 操作符,可以实现这一功能。以下是具体方法及其解释: #### 使用 `#` 操作符将参数转为字符串 当预处理器遇到带有 `#` 的定义时,它会将指定的参数转换为字符串字面量[^3]。例如: ```c #define STR(X) #X const char *str = STR(hello); ``` 在此例子中,`STR(hello)` 被替换为 `"hello"`,因此最终生成的代码相当于: ```c const char *str = "hello"; ``` 这种技术允许动态地将参数转化为字符串。 --- #### 将数值或其他类型数据转化为字符串 除了简单的字符串外,还可以利用定义将其他类型的值(如整数)转化为字符串。例如: ```c #define NUM_TO_STR(N) #N const char *numStr = NUM_TO_STR(123); ``` 在这里,`NUM_TO_STR(123)` 被替换为 `"123"`,从而实现了将数字转化为字符串的效果[^1]。 --- #### 字符串拼接的应用 如果需要组合多个部分形成一个完整的字符串,可以结合 `##` 和 `#` 来完成此任务。例如: ```c #define CONCATENATE(a, b) a##b #define STRINGIFY(x) #x const char *combinedString = STRINGIFY(CONCATENATE(prefix_, suffix)); ``` 在这个例子中: 1. 首先,`CONCATENATE(prefix_, suffix)` 展开为 `prefix_suffix`。 2. 接着,`STRINGIFY()` 将其进一步转化为字符串 `"prefix_suffix"`[^4]。 需要注意的是,在某些情况下,嵌套宏可能会导致未预期的行为,因为内部可能无法完全展开[^4]。 --- #### 注意事项 - 如果在定义后添加了多余的分,则可能导致编译器生成不必要的空语句[^5]。为了避免此类问题,请确保仅在必要时才附加分。 - 当涉及复杂逻辑或者条件判断时,建议优先考虑函数而非简单替代方案,以便提高程序可读性和维护性。 --- ### 示例代码 以下是一个综合应用上述概念的小型案例: ```c #include <stdio.h> #define PREFIX "example_" #define SUFFIX "value" #define COMBINE_STRING(p, s) p##s #define TO_STRING(str) #str int main() { const char *result = TO_STRING(COMBINE_STRING(PREFIX, SUFFIX)); printf("Combined string: %s\n", result); return 0; } ``` 运行以上代码将会打印出如下结果: ``` Combined string: example_value ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值