好的,我知道表达式的输出(x * = y = z = 4;)是40;但是我们到底得到了40分?你能不能一步一步地告诉我。
我认为优先顺序是从右到左所以(2 * 4)=(z = 4),我不明白
#include <stdio.h>
#define PRINTX printf("%d\n",x)
int main (void){
int x = 2, y, z;
x *= 3 + 2;
PRINTX;
x *= y = z = 4;
PRINTX;
x = y == z;
PRINTX;
x == ( y = z );
PRINTX;
return 0;
}
答案 0 :(得分:4)
不,这里可以评估作业的唯一方法是从右到左。
首先请注意,x *= 99
例如是x = x * 99
的简写。
说完了,
x *= y = z = 4;
相当于
z = 4;
y = z;
x *= y; // This is shorthand for x = x * 4
考虑如果你试图以相反的方式评估会发生什么:
// y is unininitialized
x *= y;
y = z;
z = 4;
它会失败。
真的,
// x = 2
int x = 2, y, z;
// x = x * (3 + 2) = x * 5 = 2 * 5 = 10
x *= 3 + 2;
// x = x * 4 = 10 * 4 = 40
x *= y = z = 4;
这可以改写为
int x, y, z;
x = 2; // x = 2
x = x * (3 + 2); // This is 2 * 5, so x = 10 after this
z = 4; // z = 4
y = z; // y = 4
x = x * y; // x = 10 * 4 = 40
这就是你最终获得40分的结果。
答案 1 :(得分:3)
所有赋值运算符具有相同的优先级和从右到左的关联性(这会影响在表达式中存在多个具有相同优先级的运算符时发生的情况)。
这意味着x *= y = z = 4
相当于x *= (y = (z = 4))
。必须首先评估z = 4
(将z
分配给4
,并给出4
的结果。然后,作业y = ...
会将值y
赋予4
的值,并生成4
的结果。然后,作业x *= ...
将x
(其值10
)乘以4
,结果为40
。
(x *= 3 + 2
给x
值10
的原因是加法的优先级高于赋值,因此x *= 3+2
等同于x *= (3 + 2)
而不是(x *= 3) + 2
{1}}。)
如果赋值运算符是从左到右的关联,x *= y = z = 4
将等同于(((x *= y) = y) = z) = 4
,它将无法编译。
答案 2 :(得分:2)
你有:
int x = 2, y, z;
x *= 3 + 2;
这是x = x * (3 + 2)
的简写,如果10
从x
开始,则评估为2
。
PRINTX;
x *= y = z = 4;
在此之后,y == z
并且两者都设置为4
;并且x
是10
之前值的4倍,因此40
。
PRINTX;
x = y == z;
比较y
和z
;它们相等,因此x
被分配1
(比较始终评估为0
或1
)。
PRINTX;
x == ( y = z );
这会将z
分配给y
(将值保持为4
);名义上,这与x
进行比较,但编译器可以忽略比较。因此,x
保持不变,仍为1
。