我编写的程序如下:
#include<cstdio>
#define max(a,b) a>b?a:b
using namespace std;
int main()
{
int sum=0,i,k;
for(i=0;i<5;i++)
{
sum=sum+max(i,3);
}
printf("%d\n",sum);
return 0;
}
我得到了输出:4
但是,当我将max(i,3
)存储在变量k
中,然后添加到sum
时,我得到了正确的输出:
#include<cstdio>
#define max(a,b) a>b?a:b
using namespace std;
int main()
{
int sum=0,i,k;
for(i=0;i<5;i++)
{
k=max(i,3);
sum=sum+k;
}
printf("%d\n",sum);
return 0;
}
输出:16
有人可以解释为什么会这样吗?
答案 0 :(得分:5)
hash-define宏是字符串扩展,而不是“语言”。
sum=sum+max(i,3);
扩展为:
sum=sum+i>3?i:3;
如果你写的那个没有()围绕它,你应该得到错误的答案。试试这个:
#define max(a,b) (a>b?a:b)
但仍有很多情况会失败。正如其他人指出的更好的宏是:
#define max(a,b) ((a)>(b)?(a):(b))
但是在很多情况下它会仍然失败,例如带有副作用的参数被评估两次。在可能的情况下避免使用宏并做类似的事情会好得多:
template <typename T> T max(T a, T b) { return a>b?a:b; }
或者,事实上,使用已经为你编写的std :: max和std :: min!
答案 1 :(得分:3)
这一行:
sum=sum+max(i,3);
扩展为:
sum = sum + i > 3 ? i : 3;
当设置parens以使其更清楚时:
sum = (sum + i) > 3 ? i : 3;
因此,在5遍循环中,表达式为:
sum = (0 + 0) > 3 ? 0 : 3; // Result, sum = 3
sum = (3 + 1) > 3 ? 1 : 3; // Result: sum = 3
sum = (3 + 2) > 3 ? 2 : 3; // Result: sum = 3
sum = (3 + 3) > 3 ? 3 : 3; // Result: sum = 3
sum = (3 + 4) > 3 ? 4 : 3; // Result: sum = 4
那就是你答案的来源。
解决此问题的传统方法是将#define
更改为:
#define max(a,b) (((a)>(b))?(a):(b))
但即使这有一些陷阱。
答案 2 :(得分:2)
我认为您遇到运算符优先级问题,您必须记住,定义将导致源代码中的文本替换。您应该将您的定义更改为
#define max(a,b) ((a) > (b) ? (a) : (b))
答案 3 :(得分:1)
预处理器的输出(使用-E
标志查看)将是:
sum = sum+i>3?i:3;
与
相同sum = (sum+i)>3?i:3;
这不是您的意思,因为+
的高于的优先级高于>
。你应该使用:
#define max(a,b) (a>b?a:b)
代替。
答案 4 :(得分:1)
替换行sum=sum+max(i,3);
中的宏会提供以下格式:
sum=sum+i>3?i:3 ;
要求sum + i
大于3
而不是相应地分配总和的值。因此,你有4,因为每次在循环内发生新的赋值。使用Andrew建议的模板方法。
(循环每次评估条件(sum + i) > 3 ? i : 3
。这里没有累加。)