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

max defined in #define not working properly

本文关键字:常工作 工作 #define 定义 最大值      更新时间:2023-10-16

我把程序写成如下:

#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("%dn",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("%dn",sum);
   return 0;
}

输出 : 16

有人可以解释为什么会发生这种情况吗?

哈希定义宏是一个字符串扩展,而不是"语言"的东西。

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!

这一行:

sum=sum+max(i,3);

扩展到:

sum = sum + i > 3 ? i : 3;

当设置括号以使其更清晰时,是:

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))

但即使这样也有一些陷阱。

我认为您遇到了运算符优先级问题,您必须记住,定义将导致源代码中的文本替换。您应该将定义更改为

#define max(a,b) ((a) > (b) ? (a) : (b))

preposetor的输出(使用 -E 标志查看(将为:

sum = sum+i>3?i:3;

这与

sum = (sum+i)>3?i:3;

这不是你的意思,因为+的优先级高于>.您应该使用:

#define max(a,b) (a>b?a:b)

相反。

替换行中的宏 sum=sum+max(i,3); 给出以下形式:

sum=sum+i>3?i:3 ;

它要求如果sum + i大于3则相应地分配 sum 的值。因此,你有 4 个,因为每次新任务发生在循环内。使用安德鲁建议的模板方法。

(循环每次都会(sum + i) > 3 ? i : 3评估条件。此处没有累积添加。