In order to properly evaluate an expression such as `4 + 2 * 3`

, we must understand both what the operators do, and the correct order to apply them. The order in which operators are evaluated in a compound expression is called **operator precedence**. Using normal mathematical precedence rules (which state that multiplication is resolved before addition), we know that the above expression should evaluate as `4 + (2 * 3)`

to produce the value 10.

In C++, all operators are assigned a level of precedence. Those with the highest precedence are evaluated first. You can see in the table below that multiplication and division (precedence level 5) have a higher precedence than addition and subtraction (precedence level 6). The compiler uses these levels to determine how to evaluate expressions it encounters.

Thus, 4 + 2 * 3 evaluates as 4 + (2 * 3) because multiplication has a higher level of precedence than addition.

If two operators with the same precedence level are adjacent to each other in an expression, the **associativity rules** tell the compiler whether to evaluate the operators from left to right or from right to left. For example, in the expression `3 * 4 / 2`

, the multiplication and division operators are both precedence level 5. Level 5 has an associativity of left to right, so the expression is resolved from left to right: `(3 * 4) / 2 = 6`

.

**Table of operators**

Notes:

- Precedence level 1 is the highest precedence level, and level 18 is the lowest. Operators with a higher precedence level get evaluated first.
- L->R means left to right associativity.
- R->L means right to left associativity.

Prec/Ass | Operator | Description | Pattern |
---|---|---|---|

1 None |
:: :: |
Global scope (unary) Class scope (binary) |
::name class_name::member_name |

2 L->R |
() () () type() [] . -> ++ –– typeid const_cast dynamic_cast reinterpret_cast static_cast |
Parenthesis Function call Initialization Value construction Array subscript Member access from object Member access from object ptr Post-increment Post-decrement Run-time type information Cast away const Run-time type-checked cast Cast one type to another Compile-time type-checked cast |
(expression) function_name(parameters) type name(expression) type(expression) pointer[expression] object.member_name object_pointer->member_name lvalue++ lvalue–– typeid(type) or typeid(expression) const_cast<type>(expression) dynamic_cast<type>(expression) reinterpret_cast<type>(expression) static_cast<type>(expression) |

3 R->L |
+ - ++ –– ! ~ (type) sizeof & * new new[] delete delete[] |
Unary plus Unary minus Pre-increment Pre-decrement Logical NOT Bitwise NOT C-style cast Size in bytes Address of Dereference Dynamic memory allocation Dynamic array allocation Dynamic memory deletion Dynamic array deletion |
+expression -expression ++lvalue ––lvalue !expression ~expression (type)expression sizeof(type) or sizeof(expression) &lvalue *expression new type new type[expression] delete pointer delete[] pointer |

4 L->R |
->* .* |
Member pointer selector Member object selector |
object_pointer->*pointer_to_member object.*pointer_to_member |

5 L->R |
* / % |
Multiplication Division Modulus |
expression * expression expression / expression expression % expression |

6 L->R |
+ -- |
Addition Subtraction |
expression + expression expression -- expression |

7 L->R |
<< >> |
Bitwise shift left Bitwise shift right |
expression << expression expression >> expression |

8 L->R |
< <= > >= |
Comparison less than Comparison less than or equals Comparison greater than Comparison greater than or equals |
expression < expression expression <= expression expression > expression expression >= expression |

9 L->R |
== != |
Equality Inequality |
expression == expression expression != expression |

10 L->R | & | Bitwise AND | expression & expression |

11 L->R | ^ | Bitwise XOR | expression ^ expression |

12 L->R | | | Bitwise OR | expression | expression |

13 L->R | && | Logical AND | expression && expression |

14 L->R | || | Logical OR | expression || expression |

15 L->R | ?: | Conditional | expression ? expression : expression |

16 R->L |
= *= /= %= += -= <<= >>= &= |= ^= |
Assignment Multiplication assignment Division assignment Modulus assignment Addition assignment Subtraction assignment Bitwise shift left assignment Bitwise shift right assignment Bitwise AND assignment Bitwise OR assignment Bitwise XOR assignment |
lvalue = expression lvalue *= expression lvalue /= expression lvalue %= expression lvalue += expression lvalue -= expression lvalue <<= expression lvalue >>= expression lvalue &= expression lvalue |= expression lvalue ^= expression |

17 R->L | throw | Throw expression | throw expression |

18 L->R | , | Comma operator | expression, expression |

A few operators you should already recognize: +, -, *, /, (), =, <, >, <=, and >=. These arithmetic and relational operators have the same meaning in C++ as they do in every-day usage.

However, unless you have experience with another programming language, it’s likely the majority of the operators in this table will be incomprehensible to you at this point in time. That’s expected at this point. We’ll cover many of them in this chapter, and the rest will be introduced as there is a need for them.

The above table is primarily meant to be a reference chart that you can refer back to in the future to resolve any precedence or associativity questions you have.

**Quiz**

1) You know from everyday mathematics that expressions inside of parenthesis get evaluated first. For example, in the expression `(2 + 3) * 4`

, the `(2 + 3)`

part is evaluated first.

For this exercise, you are given a set of expressions that have no parenthesis. Using the operator precedence and associativity rules in the table above, add parentheses to each expression to make it clear how the compiler will evaluate the expression.

Hint: Use the pattern column in the table above to determine whether the operator is unary (has one operand) or binary (has two operands). Review section 1.5 -- A first look at operators if you need a refresher on what unary and binary operators are.

Sample problem: x = 2 + 3 % 4
Binary operator % has higher precedence than operator + or operator =, so it gets evaluated first: x = 2 + (3 % 4) Binary operator + has a higher precedence than operator =, so it gets evaluated next: Final answer: x = (2 + (3 % 4)) We now no longer need the table above to understand how this expression will evaluate. |

a) x = 3 + 4 + 5;

b) x = y = z;

c) z *= ++y + 5;

d) a || b && c || d;

**Solutions**

3.2 -- Arithmetic operators |

Index |

2.10 -- Chapter 2 comprehensive quiz |

Just a suggestion towards readability and clarity. The R->L and L->R could maybe be changed into R -> L and R <- L ?

just a suggestion; if you could make the chart in to an image file as well so people could save it and pull it up at any time it might be easier for referencing in the future.

Hey Alex,

I cannot seem to find the exponent operator, ^. Am I missing it, or was it not included.

Thanks

Wintur

Strangely enough, C++ does not include an exponent operator. You have to use the pow() function.

pow(base, exponent) will return the results of base.

^{exponent}. To access the pow() function, you need to #includeThe quiz is really unclear in this one. I don’t understand even a bit of it.

I’ve updated the quiz question and answer to try and make it more comprehensible. Let me know if it makes more sense now.

Hello Alex,

Thank you for this very well made tutorial.

I’d like to suggest you to put 3.2 (arithmetic operators) before 3.1 (operator precedence and associativity), I think it will be easier to understand the quizz as unary arithmetic operators (+x and -x) has higher precedence than binary operators (x + y and x -- y) which make this a bit confusing.

Hi there, Alex!

Am I getting right that "+" operator (#6 Table) would be evaluated before "*" operator (#5 in Table) due to precedence level?

But mathematically "*" should be done first…

No, operator* is evaluated before operator+. I’ll try to make this more clear in the table.