微信搜索:编程笔记本
微信搜索:编程笔记本
微信搜索:编程笔记本
点击上方蓝字关注我,我们一起学编程
欢迎小伙伴们分享、转载、私信、赞赏
今天来研究一个看似简单、实则不那么简单的问题:**定义一个求两数较小值的宏。**下面我将以百分制的方式为各种写法打分。
一、【青铜选手】得分:1分
#define MIN(x, y) x < y ? x : y
为什么给得这么低呢?我们来看看下面的例子:
#include <stdio.h>
#define MIN(x, y) x < y ? x : y
int main()
{
int sum = 2 + MIN(3, 4);
printf("sum is %d.\n", sum);
return 0;
}
理论上,sum
的值应该为 5
才对。但是上面这种写法得到的结果是什么呢?我们先运行一下,看看结果:
➜ $ gcc test.c -o test
➜ $ ./test
sum is 4.
是不是很奇怪?怎么变出个 4
出来了?对于宏的问题,一种很好的方式是检查预处理后的代码,查看宏到底展开成了什么样子。下面的代码是使用 gcc -E test.c -o test.i
得到的预处理文件:
// 与本文无关的代码已略去
int main()
{
int sum = 2 + 3 < 4 ? 3 : 4;
printf("sum is %d.\n", sum);
return 0;
}
可以看到,此处的宏是直接展开的。这就导致了一个问题:展开后的宏会与上下文发生直接联系,在遇到运算符优先级等问题时,会产生各种错误。
本例中,2 + MIN(3, 4)
被展开成了 2 + 3 < 4 ? 3 : 4
。由于 +
运算符的优先级大于 <
运算符的优先级,所以这一句又被解释为 (2 + 3) < 4 ? 3 : 4
。所以,最终的运算结果为 4
。