C / C ++中等优先级操作数的计算顺序是什么?
例如,在以下代码中:
if ( scanf("%c", &ch_variable) && (ch_variable == '\n') )
我可以确定IF语句中的第一个表达式是在第二个之前执行的(即ch_variable的值是否是新扫描的一个)?
或者它是由编译器以某种方式决定的?如果是的话,这个决定是如何做出的?
BTW,我通常使用以下标志进行编译:
-std=c99 -O0 -pedantic -Wall -ansi
答案 0 :(得分:1)
我可以确定IF语句中的第一个表达式是在第二个之前执行的(即ch_variable比较的值是一个新扫描的值)吗?
是 - 首先评估第一个表达式(scanf
调用),如果scanf
调用返回0,那么第二个表达式将会发生更多 - 请参阅下面。这是短路评估。
更广泛的讨论。
Read about the operator precedence at cppreference.com
总结 - 运算符按照明确定义的相对优先级排列(例如,' *'具有比+
更高的优先级,根据数学用法),从左到右或从右到左的关联性(例如a + b + c
保持关联并评估为(a + b) + c
,但a = b = c
是右关联的,并评估为a = (b = c)
)。
在您的代码中:
if (scanf("%c", &ch_variable) && (ch_variable == '\n') )
(
和)
正如您所期望的那样 - 覆盖&&
和==
之间的任何隐含优先级(但在这种情况下,优先级相同)。因此&&
是无争议的,并且作为短路运算符,它确保将其左参数转换为布尔值(如果scanf
返回0
它被视为false
,否则为true
),那么当且仅当它true
确定它评估右侧参数时,并且仅当它们和&{ #39;如果if
语句运行以下语句或{}
语句块,则两者都为true。
答案 1 :(得分:1)
这与" priority"无关。 (运算符优先级),但是具有子表达式的评估顺序。
&&运算符是C中的一个特例,因为它保证了从左到右的评估顺序。左操作数和右操作数的评估之间存在一个序列点,这意味着将始终首先执行/评估左操作。
然而,很多C运营商都没有这个很好的保证。想象一下代码是这样的:
if ( (scanf("%c", &ch_variable)!=0) & (ch_variable == '\n') )
这是混淆代码,但它在逻辑上与原始代码完全相同。有一个例外:&
运算符的行为与C中的大多数运算符相同,这意味着无法保证左操作数将在右操作符之前得到评估。所以我的例子有可能在给出有效值之前评估ch_variable
,这是一个严重的错误。
这些子表达式的评估顺序是未指定的行为,这意味着编译器可以首先自由地评估任何一方。它不需要记录它将做什么,它甚至不需要在编辑之间一致地选择同一侧,或者甚至在整个程序中一致地选择同一侧。
这种语言是故意设计的,允许编译器以最佳方式优化代码,从个案到案例。
答案 2 :(得分:0)
是的,绝对是涉及&&
和||
的任何内容(除非您使用operator&&
或operator||
- 这是不使用这些运营商的主要原因之一)是“严格的短期切割” - 换句话说,如果可以确定结果的总体结果,则不评估其余部分,并且顺序是严格从左到右 - 始终按语言标准。 [当然,如果编译器可以 SURE 它完全安全,它可能会重新排序,但这是标准的“as-if”定义的一部分 - 如果编译器表现“as-if” “它正如标准所说的那样做”。
请注意:
if(scanf("%c", &ch_variable) && scanf("%c", &second_variable))
{
...
}
else
{
...
}
可能没有在else部分设置“second_variable”,所以此时使用它是不安全的。
我会使用scanf("%c", &ch_variable) > 0
代替 - 因为它可以在EOF返回-1,在你的情况下是true
,没有中间的0返回值......
答案 3 :(得分:0)
它保证在第二个表达式之前评估第一个表达式。
请参阅Is short-circuiting logical operators mandated? And evaluation order?以获取标准的引用。
请注意,如果重载&&
运算符,则整个表达式等效于函数调用。在这种情况下,将无条件地评估两个表达式(即,即使第一个表达式是某些" falsy" value ...)。
答案 4 :(得分:0)
在这种情况下定义了操作数被评估的顺序,它是从左到右。
这适用于C和C ++。
有关此内容的参考,请参阅C标准的第99页:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf。
因此,就评估顺序而言,您的代码将按照您的意愿执行。但它确实有一些其他问题;看到帖子对此的评论。