Shortcut to remember the Order of Evaluation and Precedence of Operators in C
Do like the pros: add parentheses when you are unsure. Then you don't have to remember, plus the code will be easier to read.
There is a shortcut to remember C operator Precedence.
PUMA IS REBL ( spell "REBL" as if "REBEL").
"I" in IS does not represent any operator and used for completion of the sentence.
(Note: all operators with associativity not specified is left to right).
P - Primary
U - Unary
M - Multiplicative
A - Additive
S- Shift
R- Relational
E- Equality
B- BitWise ( & > ^ > |)
L- Logical ( logical && > logical ||)
and the last three operators are
T- Ternary
A- Assignment
C- Comma
(TACO as in (https://en.wikipedia.org/wiki/Taco) T for Ternary, A for assignment and Co for Comma).
for Associativity All except Unary, Assignment and Ternary are Left to Right (AUTO rides in the right, ie Assignment, Unary and Ternary are right to left).
it is advised to see the comments For more information.
First of all, expressions of the form a++ + ++a
, ++a + a++
, etc., result in undefined behavior; any result is possible. From the language standard (n1256):
6.5 Expressions
...
2 Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.72) Furthermore, the prior value shall be read only to determine the value to be stored.73)
...
72) A floating-point status flag is not an object and can be set more than once within an expression.
73) This paragraph renders undefined statement expressions such asi = ++i + 1; a[i++] = i;while allowingi = i + 1; a[i] = i;
So, don't do that.
A well-defined expression like x = a++ + ++b
will be parsed as x = ((a++) + (++b))
; both forms of the ++
operator have higher precedence than addition, and addition has higher precedence than assignment. The result of the expression will be the same as x = a + (b + 1)
.
Secondly, remember that the ++
and --
operators have a result and a side effect, as shown below:
Expression Result Side effect ---------- ------ ----------- i++ i i = i + 1 ++i i + 1 i = i + 1 i-- i i = i - 1 --i i - 1 i = i - 1
Important note to remember: the side effect doesn't have to be applied immediately after the expression is evaluated; it only has to be applied before the next sequence point. It's possible for x = a++ + ++b
to be evaluated as follows:
t1 = a;
t2 = b + 1;
x = t1 + t2;
b = b + 1;
a = a + 1;
In this case, the updates to a
and b
are deferred until after the addition and assignment to x
.
As far as precedence is concerned, here is the general order from high to low:
- Postfix operators (all have the same precedence, so sequences of operators will be evaluated left-to-right)
- array subscript operator
[]
- function call operator
()
- component selection operators
.
and->
- postfix
++
and--
- array subscript operator
- Unary operators (all have the same precedence, so sequences of operators will be evaluated left-to-right)
- prefix
++
and--
sizeof
- bitwise negation operator
~
- logical negation operator
!
- unary sign operators
-
and+
- address-of operator
&
- dereference operator
*
- prefix
- Cast expressions
(
type name)
- Multiplicative operators
*
,/
,%
- Additive operators
+
and-
- Shift operators
<<
and>>
- Relational operators
<
,>
,<=
,>=
- Equality operators
==
and!=
- Bitwise AND
&
- Bitwise XOR
^
- Bitwise OR
|
- Logical AND
&&
- Logical OR
||
- Conditional operator
?:
- Assignment operators
=
,+=
.-=
,*=
,/=
,%=
,<<=
,>>=
,&=
,^=
,|=
- Sequential (comma) operator
,
So, expressions like *x++
are parsed as *(x++)
, since the postfix ++
has higher precedence than the unary *
. Similarly, sizeof x + 1
is parsed as (sizeof x) + 1
, since sizeof
has higher precedence than addition. An expression like p++->x
is parsed as (p++)->x
; both postfix ++
and ->
operators have the same precedence, so they're parsed from left to right.
This is about as short as shortcuts get; when in doubt, use parentheses.