为了完整性(大脑转储):
这个巫术背后的术语叫做短路。让我们回顾一下您的代码,然后简要介绍一下为什么会发生这种情况。看着:
int main( void ) {
int x, y, z;
x = y = z = -1;
y = ++x && ++y && ++z;
printf( "x = %d, y = %d, z = %d, x, y, z );
return 0;
}
...我们开始逐行分解它。第一行:
int x, y, z;
... 声明三个整数x
,y
和z
. 它们被初始化为堆栈帧上的垃圾值,因为没有初始化(赋值运算符)。这一行其实无所谓,现在我们来看下一行:
x = y = z = -1;
...我们看到我们在同一行上执行多个任务。回想一下,赋值运算符将改变赋值运算符左侧的标识符(使用赋值运算符右侧的值)并返回 的值x
。这称为赋值重载。但同样,这并不重要——唯一要意识到的重要事情是x
,y
现在z
都是 -1。让我们看看下一行:
y = ++x && ++y && ++z;
......巫术尤达说。让我们添加括号以使首先评估哪个步骤更明显:
y = ( ( ++x ) && ++y && ++z );
...现在查看最里面的括号,我们看到它是前缀增量 of x
,这意味着我们将增加 of 的值x
然后返回它。我们注意到它x
最初是-1,现在增加后是0。这将解决如下:
y = ( 0 && ++y && ++z );
...现在重要的是要注意查看我们的真值表:
A | B | A && B
--------------
T | T | T
T | F | F
F | T | F
F | F | F
...对于AND
逻辑运算符,我们看到 F (AND) T, T (AND) F 都是 F。编译器会意识到这一点,并且在评估值是的连接 (AND) 时会短路false
——一个聪明的优化技术。然后它将解析为分配y
为 0(这是错误的)。回想一下,在 C 中,任何非零值都是true
,只有 0 是false
。该行将如下所示:
y = 0;
...现在看下一行:
printf( "x = %d, y = %d, z = %d, x, y, z );
...现在你应该很明显它会输出x = 0, y = 0, z = -1
.