优先权;评估顺序

时间:2009-12-28 11:47:28

标签: c

我对评估的优先顺序和顺序感到困惑。请用一个例子来解释我

8 个答案:

答案 0 :(得分:5)

这是一个秘密:我不打扰学习优先规则。它们太容易出错了,它让下一个看待代码的人思考得太多了。换句话说:假设维护你的代码的人是一个挥舞着斧头的心理学家,他知道你住在哪里。他们也很好。

所以而不是:

x = a + b * c / d;

我会用:

x = a + ((b * c) / d);

或者更好(主观),将其分解为单独的陈述或许,更棘手的问题是在“聪明”的代码行中发生的事情,这些代码行在后面的行中对表达式有副作用:

x = Func(z) * a[i++] + i; // where Func(z) somehow mutates i
                          // (or even worse when using "conditional" etc)

应该谨慎使用这些东西,你应该尝试知道什么行为是定义的,什么是明确的未定义但是工作(或失败)取决于你使用的编译器。

答案 1 :(得分:4)

Precedence指定如何在逻辑上评估表达式。例如,优先级表示在表达式

x + y * z

表达式必须计算为x +(y * z)。

但是,C很少尝试说出必须首先评估的内容。在上面的例子中,可以首先评估x,然后(y * z)。或者,可以评估(y * z),然后是x。这有一些例外 - 例如&&和||运营商指定一个特定的订单,但一般来说,不依赖订购是明智的。

答案 2 :(得分:4)

优先级定义运算符的应用顺序:例如,在表达式a * b + c / d - e中,'*'和'/'运算符的优先级高于'+'和' - '运算符,因此表达式被计算为(a * b) + (c / d) - e;也就是说,a * b的结果会添加到c / d的结果中,并从该总和中减去e

评估顺序是指评估子表达式的顺序。按照前面的a * b + c / d - e示例,编译器可能会在评估c / d之前决定评估a * b ; IOW,在大多数情况下,无法保证评估从左到右进行。如果我们将变量更改为函数,即a() * b() + c() / d() - e(),则无法保证在a()之前调用b(),或者在b()之前调用c(),编译器可能决定先调用e(),然后调用c(),然后调用d()。等等。所有保证的是a() * b()的结果将被添加到c() / d()的结果,并且将从该总和中减去e(),无论调用(),b(),c(),d()和e()的顺序如何。一些运算符(如逗号运算符和逻辑&&||运算符强制执行部分评估顺序;给定a() == b() && c() == d()表达式,&&运算符强制a() == b()c() == d()之前进行评估,但它不会强制在a()之前调用b() }。

答案 3 :(得分:2)

回想起小学早期的数学。

什么是4 + 3 * 2?
是14还是10?

当然,它是10,因为加法运算符的优先级低于乘法运算符,所以4 + 3 * 2 ALWAYS意味着4 +(3 * 2)。

操作顺序就是您根据运算符计算子表达式的顺序。

括号,指数,除法,乘法,加法,减法。在编程中(当然还有数学)显然还有很多运算符,但是我从未听过基本基础数学之外的运算顺序。

等到你发现运营商中的左关联和右关联之后。

答案 4 :(得分:1)

假设您有三个功能:

int a(void) { return printf("Hi!\n"); }
int b(void) { return printf("I am in b\n"); }
int c(void) { return printf("c\n") }

然后调用以下函数:

printf("The answer to life, universe and everything is: %d.\n",
    a() * b() + c());

将以未指定的顺序(每个都带有换行符)打印字符串Hi!I am in bc,然后是The answer to life, universe and everything is: 42.,然后换行。

优先顺序告诉我们*的优先级高于+,因此a() * b() + c()将被解释为(a() * b()) + c(),而不是a() * (b() + c())。另一方面,评估顺序意味着调用a()b()c()的顺序。在这里,可以按任何顺序评估它们。例如,编译器可以首先调用c(),然后调用b(),然后调用a(),存储中间值,然后根据优先级规则计算表达式。

当然,编译器必须评估a()b()两者来计算总和,但是在评估c()之后它可以这样做,并且可以在之前评估b() a()

答案 5 :(得分:0)

是的,当然我只使用这个操作符(&& ||)。 ++运算符的优先级高于逻辑AND(&&)和逻辑OR(||)。所以在表达中

M = ++ I&安培;&安培; ++Ĵ|| ++ K表;

我认为变量i,j和k将递增,然后将评估逻辑运算。但实际上它没有发生。变量k没有递增..

Logical OR的Lvalue为TRUE,所以从未考虑过它的R值执行... 因此变量k不会递增。但是++运算符的优先级发生了什么。为什么逻辑运算符首先求值,优先级小于递增运算符。

答案 6 :(得分:0)

这是一个记住这一切的简单方法:

C中的加减非常强,尽管他们在数学方面有所作为。它们几乎与*和/一样强(当然,它们更强,就像在数学中一样)。

Logical&&和||比较比较弱,因此您可以询问是否(a> 5&& b< 6)没有括号。然而,按位& |由于某种原因,它们接近逻辑,所以如果((a& b)> 5)需要大括号。这是唯一不合逻辑的地方。由于布尔代数语义(AND被认为是乘法),因此AND总是强于OR。

在比较和+之间 - 我们有BIT班次。它们属于算术运算,而不是逐位运算。 |。所以,cout<< a& b坏了。

其余的很明显。全表为here

答案 7 :(得分:0)

Kernighan和Ritchie的C Programming Language下表显示了C中的优先级层次结构。顶行具有最高优先级。

Operators                                  Associativity
( [ - .                                    Left to right
! - ++  -{-  + *  &  (type-cast)  sizeof   Right to left
(in the above line, +, - and * are the unary forms)
*  / %                                     Left to right
+  -                                       Left to right
<<  >>                                     Left to right
<  <=  >  >=                               Left to right
==  !=                                     Left to right
&                                          Left to right
^                                          Left to right
|                                          Left to right
&&                                         Left to right
||                                         Left to right
?:                                         Left to right
=  +=  -=  *=  /=  %=  &=  ^=  |=  <<= >>= Right to left
,                                          Left to right

实施例: http://www.careercampus.net/resources/data_and_c_next1.htm