C中等优先级操作数的计算顺序

时间:2014-08-07 08:45:39

标签: c++ c

C / C ++中等优先级操作数的计算顺序是什么?

例如,在以下代码中:

if ( scanf("%c", &ch_variable) && (ch_variable == '\n') )

我可以确定IF语句中的第一个表达式是在第二个之前执行的(即ch_variable的值是否是新扫描的一个)?

或者它是由编译器以某种方式决定的?如果是的话,这个决定是如何做出的?

BTW,我通常使用以下标志进行编译:

-std=c99 -O0 -pedantic -Wall -ansi

5 个答案:

答案 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

因此,就评估顺序而言,您的代码将按照您的意愿执行。但它确实有一些其他问题;看到帖子对此的评论。