【发布时间】:2013-05-17 11:57:53
【问题描述】:
我有以下代码:
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 编译器。
【问题讨论】:
-
顺便说一句,这些不是“如果条件”。它们只是表达式,使用布尔运算符和后自增运算符。
-
仅仅因为 && 具有更严格的优先级并不意味着
k = x++ || (y++ && z++)将在 || 之前执行 &&。这称为短路并且众所周知。你甚至自己提到它。想象一下:k = x++ || f(&y,&z)其中 f() 返回(*y)++ && (*z)++。它在功能上等同于您的代码。 -
@Matthias:确实;
++的优先级甚至高于&&;我们不希望仅仅因为优先级而在其他所有事情之前发生后递增...... -
你在哪里收到
void main()?在几乎所有情况下都应该是int main(void)。 -
只是为了强化概念,措辞略有不同:优先级仅控制运算符和操作数的分组。它不控制评估顺序。
标签: c operator-precedence