Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.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_Operators_Operator Precedence - Fatal编程技术网

C &&;结束||

C &&;结束||,c,operators,operator-precedence,C,Operators,Operator Precedence,据我所知,逻辑运算符&&的优先级高于|。在运行代码时: #include <stdio.h> int main() { int i = 1, j =1, k = 1; printf("%d\n",++i || ++j && ++k); printf("%d %d %d",i,j,k); return 0; } 只有当++i | |++j&&++k的计算方式如下时,这才可能: (++i) || (++j && ++

据我所知,逻辑运算符
&&
的优先级高于
|
。在运行代码时:

#include <stdio.h>

int main()
{
    int i = 1, j =1, k = 1;

    printf("%d\n",++i || ++j && ++k);
    printf("%d %d %d",i,j,k);

    return 0;
}

只有当
++i | |++j&&++k
的计算方式如下时,这才可能:

(++i) || (++j && ++k)
但是,根据运算符优先级规则,它应评估为:

(++i || ++j) && (++k)
因此,输出应为:

1
2 1 2
这是怎么回事

注意:根据我的理解,我认为优先级较高的运算符的计算如下(如果它是左关联的):
1.计算其左表达式的值
2.然后计算其正确的表达式(如果需要)


我错了吗?

运算符-
|
如果其第一个操作数的计算结果为true(非零),则不计算其第二个操作数

对于
&&
也是如此,如果第一个操作数为false,则不使用第二个操作数。这是一种可能的优化,因为任何布尔值或true都是true,类似地,任何布尔值和false都是false


好吧,你把优先级和求值顺序搞混了。这里没有任何矛盾之处:

++i || ++j && ++k
分组为

(++i) || (++j && ++k)
因为
&
具有更高的优先级。但是OR操作的LHS为真,因此整个RHS及其AND操作被丢弃,不进行评估



在编辑中注意:是的,您错了:运算符优先级仍然与求值顺序不同。它只是分组。

首先,正如您自己所说,
&&
具有更高的优先级,这意味着操作数分组应该是

 (++i) || (++j && ++k)
我不清楚你为什么说“根据运算符优先级”应该是
(++i | |++j)&&(++k)
。这与你自己说的恰恰相反

其次,运算符优先级与求值顺序完全无关。运算符优先级指示运算符及其操作数之间的分组(即运算符优先级表示哪个操作数属于哪个运算符)

同时,评估的顺序是一个完全不同的故事。它要么未定义,要么由完全不同的规则集定义。对于
|
&&
运算符,评估顺序确实定义为从左到右(尽可能提前完成)

因此,运算符优先级规则告诉您分组应该是

 (++i) || ((++j) && (++k))
现在,评估规则的顺序告诉你,首先我们评估
++i
,然后(如果必要)我们评估
++j
,然后(如果必要)我们评估
++k
,然后我们评估
&
,最后我们评估
|
你说:


只有当
++i | |++j&&++k
的计算方式如下时,这才可能:

(++i) || (++j && ++k)
a + (b * c) - (d / e)
i || (j && k)
但是,根据运算符优先级规则,它应评估为:

(++i || ++j) && (++k)
第一个分组是正确的,因为
&&
的优先级高于
|
的优先级。然后表达式作为一个整体计算
|
的LHS,其副作用是将
i
递增,计算结果为true。这意味着根本不计算
|
&&&
表达式)的RHS,因为不需要它来确定整个表达式的真实性

因此,编译器是正确的;你在某种程度上误解了优先权


为什么第一个分组是正确的?根据第一个分组,
|
的优先级高于
&&
。我怎么了

你似乎不理解优先级,或者你不理解优先级与评估顺序的相互作用。第一个分组赋予
和&
更高的优先级

如果您有
a+b*c
,其中
*
的优先级高于
+
,那么它将被评估为
a+(b*c)
,不是吗?将
+
更改为
|
并将
*
更改为
&&
,表达式同构且解释类似


算术表达式和逻辑表达式之间的最大区别在于,逻辑表达式的操作数必须从左到右求值,而算术表达式的操作数不需要从左到右求值;编译器可以在计算
a
之前计算
b*c
(但在进行加法之前必须计算
b*c
)。相反,在逻辑表达式(
a | | b和&c
)中,编译器必须在计算
b和&c
之前计算
a
,当
a
结果为真时,它不能计算
b
c
,更不用说
b和&c
,因为您误解了优先级,让我们用一个数学例子来澄清它。乘法和除法的优先级高于加法和减法。这意味着这个表达式:

a + b * c - d / e
i || j && k
可以这样写:

(++i) || (++j && ++k)
a + (b * c) - (d / e)
i || (j && k)
由于您正确地说明了
&&
的优先级高于
| |
,因此此表达式:

a + b * c - d / e
i || j && k
可以这样写:

(++i) || (++j && ++k)
a + (b * c) - (d / e)
i || (j && k)
如果有帮助的话,您可以将其视为“具有最高优先级的操作首先被括号括起来”


(但是,优先级与求值不同-如果
i
为真,那么
(j&&k)
将永远不会被求值。)

请再次阅读我的问题,我不是在问这个问题。我说的是运算符优先级。请阅读我的第一行。@haccks我知道。你把运算符优先级和求值顺序搞混了。耶……是的。我对它感到困惑。@haccks因为| | |短路它从不在它的右边做任何操作。用i=-1试试,我认为这是一个有点缺陷的问题,如果你需要明确说明优先顺序,用括号表示你想要的优先顺序。不要让语言或编译器来决定。让你的公司