编程实践一书说:
函数宏最严重的问题之一是参数 在定义中出现不止一次可能会被评估不止一次;如果 调用中的参数包含一个带副作用的表达式,结果是一个微妙的bug。 此代码尝试从以下位置实现一个字符测试:
#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
请注意,参数c在宏的主体中出现两次。如果我叫晚餐 在这样的背景下,
while (isupper(c = getchar()))
然后每当输入字符大于或等于A时,它就会出现 丢弃并读取另一个字符以对Z进行测试。
我不明白如何将一个更大的&gt; = A字符丢弃。
答案 0 :(得分:6)
由于宏定义在实际编译之前以文本方式扩展到程序中,
isupper(c = getchar())
将扩展为
((c = getchar()) >= 'A' && (c = getchar()) <= 'Z')
通过&&
的短路规则调用getchar
两次iff它第一次返回>= 'A'
并分配c
第二次调用返回的值。 / p>