意外的输出printf语句

时间:2015-06-16 07:33:14

标签: c macros printf ternary-operator

为什么以下两个ijprintf()的输出有所不同?

#include <cstdio>
#define MAX(x,y) (x)>(y)?(x):(y)
int main()
{
    int i=10,j=5,k=0;
    k==MAX(i++,++j);
    printf("%d %d %d\n",i,j,k);
    i=10,j=5,k=0;
    k=MAX(i++,++j);
    printf("%d %d %d\n",i,j,k);
    return 0;
}

我认为只有k应该有所不同,但它会在i语句中显示所有jkprintf()的不同输出。是什么原因?

输出:

11 7 0
12 6 11

5 个答案:

答案 0 :(得分:2)

k==MAX(i++,++j);被翻译为:

  k==(i++) > (++j) ? (i++) : (++j);
/* 2       1       3  : Precedance */

在您的案例中i = 10j = 5,因此比较将是10 v / s 6,这将是真实的,或1副作用 i变为11j变为6。 (回想一下:宏不是函数)

作为k = 0且不等于1k==(i++) > (++j)false并且++j将被执行。导致j增加到7

在后一种情况下,变量的值没有修改。

我在两种情况下什么时候可以期待相同的输出? 即使您使用函数更改宏,您的参数也会产生副作用,这会导致11 6的输出i j,因此您使用++运算符更改变量,don' t期望两个语句具有相同的值。

答案 1 :(得分:1)

  • 让我们分析第一个printf()

    的输出
    1. 假设您的代码中有=而不是==

      k==MAX(i++,++j);
      

      翻译转换为

       k = (i++) > (++j) ? (i++): (++j)
      

      评估时会更改ijk的所有值。

    2. 即使你的意思是==,如in the answer先生提到的那样Mohit Jain,你也会遇到类似的优先问题。

    3. 请查看operator precedence以便更好地理解。

    4. 让我们分析第二个printf()

    5. 的输出

在第二个printf()语句中,您重新设置 ijk的值,而不使用宏。因此,这些值将被打印出来。简单。

因此, TL; DR,在第一个printf()之前,MACRO会更改ijk的所有三个值。因此,对于所有三个变量值,第一个和第二个printf()的输出都不同。

FWIW,如果您认为MACRO表现为三元条件表达式,则需要将MACRO定义更改为

#define MAX(x,y) ( (x)>(y) ? (x) : (y) )

避免MACRO扩展后运营商优先级问题。

答案 2 :(得分:1)

你有副作用。

MAX(i++,++j)

扩展为

(i++)>(j++)?(i++):(j++)

i在宏调用中被修改两次。

此外,您必须在宏定义中添加parens:

#define MAX(x,y) ((x)>(y)?(x):(y))

答案 3 :(得分:1)

i ++和++ j都增加i和j,因此在打印前更改它们的值。

答案 4 :(得分:0)

宏是红鲱鱼。 OP没有询问k但是&#34;为什么以下两个printf中的i和j的输出是不同的?&#34;答案是因为ij在设置其值和打印之间已经被修改,在第一种情况下,但不是在第二种情况下。