请解释C语言代码中带//***的两行及#define宏定义的工作原理
嘿,让我来拆解下这两行关键代码,帮你搞懂C语言预处理器里这个有意思的小技巧~
先把完整代码贴出来方便对照:
#include <stdio.h> #define get(s) #s //*** int main() { char str[] = get(hello); //*** printf("%s\n", str); return 0; }
1. 核心:#define get(s) #s 这行的运行机制
这里的#是C预处理器的字符串化运算符(Stringizing Operator),它的作用非常直白:在宏展开阶段,把传入宏的参数直接转换成对应的字符串字面量(自动加上双引号)。
要注意的是,这个转换是在编译前的预处理阶段完成的,和程序运行时完全无关。举几个例子你就懂了:
- 如果调用
get(hello),预处理器会把它替换成"hello" - 如果调用
get(1234),会被替换成"1234" - 甚至你传
get(foo bar)(注意参数里的空格),只要符合宏参数的写法,会被转换成"foo bar"
简单说,这个宏就是个“参数转字符串”的工具,把你给的标识符、数字甚至带空格的参数(只要预处理器能识别为一个宏参数),原封不动变成带双引号的字符串。
2. 再看char str[] = get(hello);
当预处理器处理这行的时候,会先把get(hello)展开成"hello",所以这行代码在预处理结束后,会变成:
char str[] = "hello";
这就很熟悉了——定义了一个字符数组str,并用字符串"hello"初始化它。数组的大小会自动被编译器设置为6(因为"hello"包含5个字符,加上C字符串必须的末尾终止符'\0',总共6个字节)。
额外小补充
你可能会问:直接写char str[] = "hello";不就行了?这个宏的价值在于复用字符串化逻辑,比如当你需要把一堆标识符转换成它们的名字字符串时,或者结合其他宏(比如和连接符##配合)做更复杂的代码生成时,这种字符串化宏就能帮你减少重复代码。
内容的提问来源于stack exchange,提问作者AA M
相关产品推荐
相关产品推荐

