【问题标题】:How do you evaluate z = x- - == y + 1;你如何评估 z = x- - == y + 1;
【发布时间】:2021-09-13 16:53:33
【问题描述】:

考虑到

int w = 1;
int x = 6;
int y = 5;
int z = 0;
 
z = !z || !x && !y;
printf("%d\n", z);

z = x-- == y + 1;
printf("%d\n", z);

如果 x-- 为 5 且 y+1 为 6,有人能解释一下下面的行如何计算为 1 吗?

z = x-- == y + 1;

【问题讨论】:

  • x-- 是 6。--x 是 5。
  • 您将x----x 混淆了。虽然两个表达式都将x 减一,但前者的计算结果为xold 值,而后者的计算结果为xnew 值。因此,在您的情况下,x-- 的计算结果为 6,而 x 的值为 5

标签: c decrement postfix-operator equality-operator


【解决方案1】:

表达式x-- 被评估为x 的值之前被递减。

所以x-- == y + 16 == 5 + 1 相同,这是真的,那么值1 被分配给z

【讨论】:

    【解决方案2】:

    表达式

    z = x-- == y + 1
    

    将被解析为

    z = ((x--) == (y + 1))
    

    IOW,您正在将x--结果y + 1结果 进行比较,并将比较结果分配给z

    x--的结果是x的当前值;副作用是x 递减。所以,给定

    x == 6
    y == 5
    

    然后

    x--            == 6
    y + 1          == 6
    (x-- == y + 1) == 1
    

    所以1 被分配给z;在此评估之后,x 将等于 5

    请注意,在这种情况下,C 不会强制从左到右求值 - y + 1 可以在 x-- 之前求值。另请注意,-- 运算符对x 的副作用不必在评估后立即应用 - 整个事情可以评估为

    t1 <- y + 1
    t2 <- x
     z <- t2 == t1
     x <- x - 1
    

    t1 <- x
    t2 <- y + 1
     x <- x - 1
     z <- t1 == t2
    

    或任何其他顺序。对x 的更新和对z 的分配可以按任何顺序进行,甚至可以同时进行(交错或并行)。

    虽然惯用的 C 语言经常有点让人头疼,但这有点太过分了。作为学习运算符优先级和副作用的学术练习,它没关系(不是很好),但是在生产代码中这样做的任何人都可能会在代码审查中对此感到悲伤。如果没有别的,它不能很好地扫描 - 只需添加一些括号(就像我在上面所做的那样)将大大有助于提高可读性。

    【讨论】:

      【解决方案3】:

      来自 C 标准(6.5.2.4 后缀递增和递减运算符)

      2 后缀 ++ 运算符的结果是操作数的值。 作为副作用,操作数对象的值递增(即 即,将相应类型的值 1 添加到其中)。

      3 后缀 -- 运算符类似于后缀 ++ 运算符, 除了操作数的值递减(即 从中减去相应类型的值 1)

      因此在这个表达式语句中

      z = x-- == y + 1;
      

      可以等效地重写为

      z = ( x-- ) == ( y + 1 );
      

      后缀递减表达式x--的值是变量x递减前的值。即表达式的值等于6

      表达式y + 1 的值也等于6,因为y 的值等于5

      最后(C 标准,6.5.9 等式运算符)

      3 ==(等于)和 !=(不等于)运算符类似于 关系运算符,但优先级较低。108) 每个 如果指定的关系为真,则运算符的数量为 1,如果指定的关系为真,则为 0 它是假的。 结果的类型为 int。对于任何一对操作数, 其中一个关系是正确的

      所以表达式x-- 的值等于表达式y + 1 的值,那么变量z 的值就是1

      您可以通过以下方式保持后缀减量运算符获得预期的结果

      z = ( x--, x == y + 1 );
      

      通过插入逗号运算符。在这种情况下,在逗号运算符之后有一个序列点,这意味着在逗号运算符的第二个操作数中 x == y + 1 x 已经等于 5。

      另一方面,如果你会写出这样的表达式

      z = --x == y + 1;
      

      这里使用一元递减运算符而不是后缀递减运算符 -- 那么表达式 --x 的值将等于5 (一元递减运算符的值是其操作数递减后的值)。在这种情况下,变量 z 的值是 0,因为 5 不等于 6(表达式 y + 1 的值)。

      【讨论】:

        猜你喜欢
        • 2011-11-08
        • 2020-09-05
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        相关资源
        最近更新 更多