开发者

precendence & order of evaluation [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. 开发者_运维百科 Closed 10 years ago.

i am confused with the precedence and order of evaluation.pls explain me with an example


Here's a secret: I don't bother learning precedence rules. They are too easy to get wrong, and it makes the next person to look at the code think too much. To paraphrase: assume the person who maintains your code is an axe-wielding psycho who knows where you live. Be nice too them.

So rather than:

x = a + b * c / d;

I would use:

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

Or perhaps better (subjective), break it down into separate statements The trickier question, perhaps, is what happens in "clever" lines of code that has side-effects on expressions later in the line:

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

Such things should be used sparingly, and you should try to know what behaviour is defined and what is explicitly undefined but works (or fails) depending on the compiler you use.


Precedence specifies how an expression should logically be evaluated. For example, precedence says that in the expression

x + y * z

the expression must be evaluated as x + (y * z ).

However, C makes little attempt to say what must be evaluated first. In the example above, x could be evaluated first, then (y * z). Or, (y * z) could be evaluated, followed by x. There are some exceptions to this - for example the && and || operators specify a particular order, but in general it's wise not to rely on ordering.


Precedence defines the order in which operators are applied: for example, in the expression a * b + c / d - e, the '*' and '/' operators have higher precedence than the '+' and '-' operators, so the expression is evaluated as (a * b) + (c / d) - e; that is, the result of a * b is added to the result of c / d, and e is subtracted from that sum.

Order of evaluation refers to the order in which subexpressions are evaluated. Going by the previous example of a * b + c / d - e, the compiler may decide to evaluate c / d before evaluating a * b; IOW, in most cases, there's no guarantee that evaluation proceeds from left to right. If we change the variables to functions, i.e., a() * b() + c() / d() - e(), there's no guarantee that a() is called before b(), or that b() is called before c(), etc. The compiler may decide to call e() first, then c(), then d()., etc. All that's guaranteed is that the result of a() * b() will be added to the result of c() / d(), and that e() will be subtracted from that sum, regardless of the order in which a(), b(), c(), d(), and e() are called. Some operators such as the comma operator and the logical && and || operators force a partial order of evaluation; given the expression a() == b() && c() == d(), the && operator forces a() == b() to be evaluated before c() == d(), although it does not force a() to be called before b().


think back to early grade school math.

What is 4 + 3 * 2?
is it 14 or 10?

Of course, it is 10, because the addition operator has a lower precedence than the multiplication operator and so 4 + 3 * 2 ALWAYS means 4 + (3 * 2).

Order of operations is just the order which you evaluate sub-expressions based on their operators.

Parentheses, Exponents, Division, Multiplication, Addition, Subtraction. Obviously in programming (and of course math too) there are many more operators than that, but I've never heard order of operations used outside of basic fundamental maths.

Just wait until you find out about left-association and right-association in operators.


Let's say you have three functions:

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

Then the following function call:

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

Will print the strings Hi!, I am in b, c in an unspecified order (each with a newline), followed by The answer to life, universe and everything is: 42., followed by a newline.

Precedence tells us that * has higher precedence than +, so a() * b() + c() will be interpreted as (a() * b()) + c(), and not a() * (b() + c()). Order of evaluation, on the other hand, would have implied the order of calls to a(), b(), and c(). Here, they can be evaluated in any order. The compiler can, for example, call c() first, then b(), and then a(), storing the intermediate values, and then calculate the expression according to precedence rules.

Of course, the compiler has to evaluate a() and b() both to calculate the sum, but it can do so after evaluating c(), and can evaluate b() before a().


yes off course i struck up with this operators(&& ||) only.. ++ operator has higher precedence than logical AND(&&) and logical OR(||). So in expression

m=++i&&++j||++k;

What i thought is variable i,j and k will be incremented then logical operations will be evaluated..But in actual it is not happened.variable k is not incremented..

Logical OR's Lvalue has been TRUE so it never considered its R values execution... Hence variable k is not incremented..But what happened to the precedence of the ++ operator..Why Logical operator evaluated first, being less precedence than increment operator.


The following table from C Programming Language, by Kernighan and Ritchie, shows the precedence hierarchy in C. The top line has the highest precedence.

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

Example: http://www.careercampus.net/resources/data_and_c_next1.htm


Here's a simple way to remember it all:

Plus and minus are very strong in C, despite what they are in math. They are almost as strong as * and / (which are, of course, stronger, like in mathematics).

Logical && and || are weaker than comparisons, so that you could ask if(a>5 && b<6) without brackets. However, bitwise & | are near logical ones, for some reason, so if((a&b) > 5) requires braces. This is the only illogical place. AND is always stronger than OR, due to boolean algebra semantics (AND is perceived like multiplication).

Between comparisons and + - we have the BIT Shifts. They belong near arithmetical ops, not with bitwise ^ & |. So, cout << a & b is broken.

The rest is obvious. Full table is here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜