这是什么类型的宏?

17

我找到了以下代码:

#include<stdio.h>
#define d(x) x(#x[3])
int main(){
d(putchar);
}
打印出 c。我想知道宏 #define d(x) x(#x[3]) 是什么意思?在 C 语言中是否有像 # 这样的运算符?我可以在宏体内看到它,即这里 x(#x[3])。根据我的普通眼睛,它看起来与我在 C 语言中看到的某些东西不同,但实际上它是做什么的?
编辑:在现实世界中,# 的真正用途是什么?
我是 C 语言方面的新手,如果解释简单易懂将会很好。先谢谢了。

请注意,# 只是一个预处理器功能,而不是 C 语言功能。 - user395760
1
请参考此链接中有关“将标记转换为字符串”的内容:http://www.cprogramming.com/tutorial/cpreprocessor.html。 - JRL
1
+1 - 那也会让我措手不及,哈哈。 - John Humphreys
今天我明白了 ;) 为什么第一个回答的人会得到那么多赞 :P - Ant's
你在哪里找到这个宏的?我想不出除了说明预处理器有多奇怪之外还有任何一个有效的用例。 - AShelly
@AShelly 请查看 http://codegolf.stackexchange.com/questions/1091/whats-my-name-produce-the-name-of-the-language-indirectly - Ant's
4个回答

25

字符 '#' 是一个字符串化符号--它将一个符号变成字符串。代码变为

putchar("putchar"[3]);

(注:原文中的双引号应当改为单引号,以便代码可以正常工作)

我见过的最快的答案 :) - Ant's
等等! putchar("putchar"[3]); 这个语句是有效的吗?请明确说明,我是C语言的初学者!它实际上是做什么的? - Ant's
2
C语言的基本字符串是字符数组,"putchar"是一个数组,其中item[0]='p',item[1]='u',item[2]='t',item[3]='c'等等...这就是为什么"putchar"[3]是'c'。 - Hernán Eche
@JonPurdy:#有什么实际应用吗?;) - Ant's
1
考虑一个 assert(x) 宏,它断言表达式 x 为真,并在失败时使用 __LINE__ 打印 #x - Jon Purdy
显示剩余2条评论

2

这里得知:

函数宏定义在替换序列中接受两个特殊的运算符(#和##): 如果在替换序列中使用参数之前使用#运算符,则该参数将被替换为字符串字面值(就像被双引号括起来一样)。

#define str(x) #x
cout << str(test);

简单地说,它将"x"参数转化为字符串。在这种情况下,“test”成为一个包含“t”,“e”,“s”,“t”,“\0”的字符数组。

准确地说,test变成了“test”,它是一个由五个字符组成的数组,包括四个字母和末尾的空字符。 - Derek Ledbetter

2
哈希符号表示“字符串化”,所以d(x)展开为putchar("putchar"[3]),从而得到c

2
< p > # 是一个预处理器运算符,它将字面量转换为字符串。实际上,您的d宏会打印您字面量转换后的字符串的第四个char


2
有点残忍的否决...但是d宏实际上将其参数的第四个字符传递给由其参数命名的函数。 d(james)不会像您的答案所示打印'm'(除非当然,james是一个效果是打印'm'的函数;-)) - James Greenhalgh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接