我对评估的优先顺序和顺序感到困惑。请用一个例子来解释我优先次序和评估顺序
回答
回想一下早期的小学数学。
什么是4 + 3 * 2?
是14还是10?
当然,它是10,因为加法运算符比乘法运算符的优先级低,所以4 + 3 * 2总是意味着4 +(3 * 2)。
操作顺序只是您根据其操作符来评估子表达式的顺序。
括号,指数,除法,乘法,加法,减法。很显然,在编程中(当然也有数学)还有更多的操作符,但我从来没有听说过基本基础数学以外的操作顺序。
只需等到您了解运营商中的左关联和右关联即可。
优先级指定如何在逻辑上评估表达式。例如,优先级说,在表达
X + Y * Z
表达式必须为x +(Y * Z)进行评估。
但是,C没有尝试说出必须首先评估什么。在上面的例子中,可以先评估x,然后(y * z)。或者,可以评估(y * z),然后是x。有一些例外 - 例如& &和||操作员指定特定的顺序,但总的来说,不依赖于顺序是明智的。
这是一个秘密:我不打扰学习优先规则。他们很容易出错,并且让下一个看代码的人觉得太多了。解释:假设维护你的代码的人是一位斧头精神病患者,他知道你住在哪里。他们也很好。
因此,而不是:
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的概念以获得正确的建议。 对于CS课程学习这个概念很重要,但更好的是在现实生活场景中添加括号。 – Jack 2009-12-28 12:27:48
是关当然,我打了这个运营商(& & ||)仅.. ++运算符具有比逻辑与更高的优先级(& &)和逻辑OR(||)。所以在表达式中
m = ++ i & & ++ j || ++ k;
我以为是变量i,j和k将递增,然后逻辑运算将实际被evaluated..But它不是happened.variable k不是递增..
逻辑OR的左值已经TRUE所以它从来没有考虑过它的R值执行... 因此变量k不会递增。但是++运算符的优先级发生了什么......为什么逻辑运算符首先计算,比增量运算符优先级低。
&&和||运营商是不寻常的,因为他们指定了评估顺序 - 他们总是从左到右进行评估。优先级对评估顺序没有影响。 – 2009-12-28 12:22:56
即使这与问题无关,请注意您的术语:++ i && ++ j不是左值。左值是可以分配给的值(可以显示在赋值运算符的左侧),而不是任何运算符左侧出现的值。 – Gorpik 2009-12-28 12:37:00
||和&&是'序列点'。这意味着所有的副作用都必须先解决任何副作用。 “短路评估”是另一个话题。 – 2010-07-28 10:06:29
这里有一个简单的方法来记住这一切:
加号和减号是非常强大的C,尽管他们在数学的东西。它们几乎和*和/(当然,它们更强大,就像数学一样)强大。
逻辑& &和||比比较弱,这样你就可以问,如果(> 5 & & b < 6)没有括号。但是,按位& | (由于某种原因),因此如果((b)> 5)需要大括号。这是唯一不合逻辑的地方。由于布尔代数语义(AND被认为是乘法),AND总是比OR更强。
比较和+之间 - 我们有位移位。它们属于近似的算术运算,而不是按位运算。所以,cout < < a & b已损坏。
其余部分是显而易见的。全表是here。
从C语言程序设计下表,由Kernighan和Ritchie,示出了优先级的层次结构中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
优先定义了运营商的应用顺序:例如,在表达式a * b + c/d - e
中,“*”和“/”运算符具有比更高的优先级的' +'和' - '运算符,因此表达式评估为(a * b) + (c/d) - e
;即将a * b
的结果添加到c/d
的结果中,并从该总和中扣除e
。
评估顺序指的是评估子表达的顺序。由a * b + c/d - e
前面的例子中去,编译器可以决定评估a * b
之前评估c/d
; IOW在大多数情况下不能保证评估从左到右进行。如果我们改变的变量函数,即a() * b() + c()/d() - e()
,有没有保证a()
被b()
之前调用,或b()
被c()
之前调用等编译器可以决定调用e()
,再c()
,然后d()
。等所有的保证是a() * b()
的结果将被添加到c()/d()
的结果中,并且e()
将从该总和中被减去,而不管a(),b(),c(),d(),和e()被调用。某些运营商(如逗号运算符)和逻辑运算符&&
和||
强制执行部分评估顺序;给定表达式a() == b() && c() == d()
,&&
操作员力a() == b()
在c() == d()
之前被评估,但它不强制a()
在b()
之前被呼叫。
比方说,你有三个功能:
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 b
,c
(每一个换行符),然后是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()
后也这样做,并能a()
之前评估b()
。
- 1. 运算符优先顺序和评估混淆
- 2. 评估顺序
- 3. 评估顺序>>和[++]
- 4. C++评估顺序
- 5. C具有操作员关联性和优先级的功能评估顺序
- 6. Java优先顺序
- 7. CSS优先顺序
- 8. CSS优先顺序
- 9. 减法 - 评估顺序
- 10. 表达式评估顺序
- 11. 红宝石评估顺序
- 12. eval函数 - 评估顺序
- 13. Clojure递归评估顺序
- 14. cataM的评估顺序
- 15. 评估顺序调用
- 16. C++中的评估顺序
- 17. JavaScript中的评估顺序
- 18. find中的评估顺序
- 19. 评估示例的顺序
- 20. Python代码评估顺序?
- 21. Python中的评估顺序
- 22. 优先功能和评估K&R
- 23. 评估顺序和运算符<<
- 24. Group JSR 303中的评估顺序和顺序
- 25. 关于优先顺序(C++)
- 26. 路由优先级顺序
- 27. 一元++优先顺序
- 28. ||之间的优先顺序和&& - java的
- 29. 野牛规范和优先顺序
- 30. 路线优先顺序表3和4
你的问题是什么? – qrdl 2009-12-28 11:52:00
我认为他正在努力处理运营商优先级 – 2009-12-28 11:55:26