为什么以下两个i
中j
和printf()
的输出有所不同?
#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
语句中显示所有j
,k
和printf()
的不同输出。是什么原因?
输出:
11 7 0
12 6 11
答案 0 :(得分:2)
k==MAX(i++,++j);
被翻译为:
k==(i++) > (++j) ? (i++) : (++j);
/* 2 1 3 : Precedance */
在您的案例中i = 10
和j = 5
,因此比较将是10
v / s 6
,这将是真实的,或1
与副作用 i
变为11
,j
变为6
。 (回想一下:宏不是函数)
作为k = 0
且不等于1
,k==(i++) > (++j)
将false
并且++j
将被执行。导致j
增加到7
。
在后一种情况下,变量的值没有修改。
我在两种情况下什么时候可以期待相同的输出?
即使您使用函数更改宏,您的参数也会产生副作用,这会导致11 6
的输出i j
,因此您使用++
运算符更改变量,don' t期望两个语句具有相同的值。
答案 1 :(得分:1)
让我们分析第一个printf()
假设您的代码中有=
而不是==
,
k==MAX(i++,++j);
将翻译转换为
k = (i++) > (++j) ? (i++): (++j)
评估时会更改i
,j
和k
的所有值。
即使你的意思是==
,如in the answer先生提到的那样Mohit Jain,你也会遇到类似的优先问题。
请查看operator precedence以便更好地理解。
让我们分析第二个printf()
在第二个printf()
语句中,您重新设置 i
,j
,k
的值,而不使用宏。因此,这些值将被打印出来。简单。
因此, TL; DR,在第一个printf()
之前,MACRO会更改i
,j
,k
的所有三个值。因此,对于所有三个变量值,第一个和第二个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;答案是因为i
和j
在设置其值和打印之间已经被修改,在第一种情况下,但不是在第二种情况下。