3

这个 C 程序的输出应该是什么?

#include<stdio.h>
int main(){
  int x,y,z;
  x=y=z=1;
  z = ++x || ++y && ++z;
  printf("x=%d y=%d z=%d\n",x,y,z);
  return 0;
}

给定的输出是: x=2 y=1 z=1
我理解 x 的输出,但看不到 y 和 z 值如何不增加。

4

2 回答 2

12

这是短路评估的结果。

该表达式的++x计算结果为2,并且编译器知道无论是什么,它2 || anything总是计算为("true") 。因此,它不会进行评估,并且值不会改变。1anythinganythingyz

如果你尝试

x=-1;
y=z=1;

您将看到这一点y并将其递增,因为编译器必须评估 OR 的右侧以确定表达式的结果。z

编辑: asaerl 首先在评论中回答了您的后续问题,所以我将稍微扩展他的正确答案。

运算符优先级决定了组成表达式的部分如何绑定在一起。因为 AND 的优先级高于 OR,编译器知道你写了

++x || (++y && ++z)

代替

(++x || ++y) && ++z

这使它的任务是在 和 之间进行++xOR ++y && ++z。此时,通常可以自由选择是否“更喜欢”首先评估一个或另一个表达式——根据标准——并且您通常不能依赖特定的顺序。此顺序与运算符优先级无关。

然而,特别||&&标准要求评估总是从左到右进行,以便短路可以工作,如果评估 lhs 的结果表明,开发人员可以依赖不评估的 rhs 表达式。

于 2012-05-03T13:48:51.310 回答
1

在 C 中,除 0 以外的任何事物都被视为真,而对 || 的评估 从左到右开始。

因此编译器将检查第一个左操作数,如果为真,则编译器不会检查其他操作数。前任。一个 || B - 在这种情况下,如果 A 为真,那么编译器将只返回真,并且不会检查 B 是真还是假。但是如果 A 为假,那么它将检查 B 并相应地返回,这意味着如果 B 为真,则返回真,如果 B 为假,则返回假。

在您的程序中,编译器首先将检查 ++x(ie 2) 并且在 C 中除 0 以外的任何内容都为真。因此它不会检查/增加其他表达式。

于 2014-09-11T13:49:41.163 回答