我是以下代码:
void main()
{
int k, x, y, z;
printf("\nExperiment 1:");
x = 0, y = 0, z = 0;
k = x++ || y++ && z++;
printf("\nx = %d, y = %d, z = %d and k = %d\n", x, y, z, k);
printf("\nExperiment 2:");
x = 1, y = 0, z = 0;
k = x++ || y++ && z++;
printf("\nx = %d, y = %d, z = %d and k = %d\n", x, y, z, k);
}
输出:
实验1: x = 1,y = 1,z = 0且k = 0
实验2: x = 2,y = 0,z = 0且k = 1
我所理解的是: 要使表达式为真,可以是“||”的左侧或右侧必须是非零的。它从左边开始。如果left不为零,则不会进一步评估。如果它为零,则从右侧开始。在右边,我们有'&&'。所以,我们再次从&&的左侧开始如果它为零,则表达式不能为真,并且不会继续。否则,它会评估'&&'
的右侧我的假设是运营商&&有更高的优先权。因此,它的两个论点都应该被评估,然后&&应该应用它,然后评估||。
的两个参数编译器是否自我优化?我已经使用了Visual Studio TC,并且禁用了优化。
答案 0 :(得分:9)
我认为这是由§6.5.14 Logical OR operator
(我的重点)
与按位|不同运算符, ||运营商保证 从左到右的评估;如果评估第二个操作数,则有 第一个和第二个的评估之间的序列点 操作数。 如果第一个操作数比较不等于0,则第二个操作数 操作数未被评估。
答案 1 :(得分:4)
所以表达式
k = x++ || y++ && z++;
被解释为(由于优先规则):
k = x++ || (y++ && z++);
在实验1中,我们有x = y = z = 0;
。
在实验2中,我们有x = 1, y = z = 0;
。
因此,右侧表达式在评估y++
后停止,因为它的值为0,因此布尔值不能成为真。