The grammar of expressions implies an order of precedence for operators.
In an expression such as 6 + 3 * 5
,
should we evaluate 6 + (3 * 5)
or
(6 + 3) * 5
? The grammar will tell us,
but it is easier to understand and remember the order of
precedence which is derived from it. The operator with higher
precedence should have brackets placed around its immediate
operands, and so its value becomes an operand of the
lower-precedence operator.
If they have the same precedence, that group of operators will have an associativity that is left-to-right (the operands on the left should be bracketed) or right-to-left (the operands on the right should be bracketed).
Operators | Associativity | Grammar |
---|---|---|
[] -> . function() |
left-to-right | postfix-expression |
! ~ ++ -- + - & * (type) sizeof |
right-to-left | unary-expression/postfix-expression/cast-expression |
* / % |
left-to-right | multiplicative-expression |
+ - |
left-to-right | additive-expression |
<< >> |
left-to-right | shift-expression |
< <= > >= |
left-to-right | relational-expression |
== != |
left-to-right | equality-expression |
& |
left-to-right | AND-expression |
^ |
left-to-right | exclusive-OR-expression |
| |
left-to-right | inclusive-OR-expression |
&& |
left-to-right | logical-AND-expression |
|| |
left-to-right | logical-OR-expression |
?: |
right-to-left | conditional-expression |
= += -= *= /= %= <<= >>=
&= |= ^= |
right-to-left | assignment-expression |
, |
left-to-right | expression |
Note that the operators +
,
-
, *
and
&
in the second row are all unary, and
so are distinguishable from the identical operators in the
third, fourth and eighth rows.
Earlier entries in the table have higher precedence. We
can now see that the operator *
in the
third row has higher precedence than +
in the fourth, so 6 + 3 * 5
, is
equivalent to 6 + (3 * 5)
.
Binary operators +
and -
have the same precedence. To resolve an
expression such as a + b - c + d
, we
observe that they have left-to-right associativity, so the
expression is equivalent to ((a + b) - c) +
d
, rather than to a + (b - (c +
d))
.
Meanwhile, =
has right-to-left
associativity, so an expression like a = b =
c = d
is equivalent to a = (b = (c =
d))
rather than to ((a = b) = c) =
d
, which wouldn't make a lot of sense anyway, as
(a = b)
is not an l-value, so it can't be the first operand
of the middle =
.