#define中定义的最大值无法正常工作

时间:2015-02-11 14:42:55

标签: c++ c

我编写的程序如下:

#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

有人可以解释为什么会这样吗?

5 个答案:

答案 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。这里没有累加。)