求解复合赋值表达式

时间:2017-05-27 04:23:21

标签: c

好的,我知道表达式的输出(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;
}

3 个答案:

答案 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 + 2x10的原因是加法的优先级高于赋值,因此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)的简写,如果10x开始,则评估为2

PRINTX;
x *= y = z = 4;

在此之后,y == z并且两者都设置为4;并且x10之前值的4倍,因此40

PRINTX;
x = y == z;

比较yz;它们相等,因此x被分配1(比较始终评估为01)。

PRINTX;
x == ( y = z );

这会将z分配给y(将值保持为4);名义上,这与x进行比较,但编译器可以忽略比较。因此,x保持不变,仍为1