我对评估的优先顺序和顺序感到困惑。请用一个例子来解释我
答案 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 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()
之后它可以这样做,并且可以在之前评估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