Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是在'中忽略的运算符的优先级;如果';条件_C_Operator Precedence - Fatal编程技术网

C 是在'中忽略的运算符的优先级;如果';条件

C 是在'中忽略的运算符的优先级;如果';条件,c,operator-precedence,C,Operator Precedence,我有以下代码: 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++

我有以下代码:

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编译器禁用了优化功能。

我认为C11中的逻辑OR运算符
§6.5.14(我的重点)已经涵盖了这一点

与按位|运算符不同,运算符保证 从左到右的评估;如果对第二个操作数求值,则 第一次和第二次评估之间的序列点 操作数如果第一个操作数比较不等于0,则第二个操作数 未计算操作数。

那么这个表达呢

k = x++ || y++ && z++;
被解释为(由于先前的规则):

在实验1中,我们得到了
x=y=z=0

在实验2中,我们得到了
x=1,y=z=0


因此,右侧表达式在求值
y++
后停止,因为其值为0,因此布尔值不能为真。

顺便说一下,这些不是“if条件”。它们只是表达式,使用布尔运算符和后增量运算符。仅仅因为&&具有更严格的优先级并不意味着
k=x++| |(y++&&z++)
将在| |之前执行&&。这被称为短路,这是众所周知的。你自己也提到过。想象一下:
k=x++|f(&y,&z)
其中f()返回
(*y)+&(*z)+
。它在功能上等同于您的代码。@Matthias:的确<代码>+
的优先级甚至高于
&&
;我们不希望仅仅因为优先级的原因,后增量会先于其他任何事情发生……您从哪里获取了
void main()
?在几乎所有情况下,它都应该是
intmain(void)
。只是为了用稍微不同的措辞来强化这个概念:优先级仅控制运算符和操作数的分组。它不控制评估的顺序。
k = x++ || (y++ && z++);