3.1 — Operator precedence and associativity

In mathematics, an operation is a mathematical calculation involving zero or more input values (called operands) that produces an output value. Common operations (such as addition) use special symbols (such as +) that denote the operation. These symbols are called operators. Operators in programming work the same way except the names may not always be a symbol. Operators work analogously to functions that take input parameters and return a value, except they are more concise. For example, 4 + 2 * 3 is much easier to read than add(4, mult(2, 3))!

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++, when the compiler encounters an expression, it must similarly analyze the expression and determine how it should be evaluated. To assist with this, 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 operator 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


  • Precedence level 1 is the highest precedence level, and level 17 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)
2 L->R ()
Function call
Uniform initialization (C++11)
Functional cast
Functional cast (C++11)
Array subscript
Member access from object
Member access from object ptr
Run-time type information
Cast away const
Run-time type-checked cast
Cast one type to another
Compile-time type-checked cast
type name(expression)
type name{expression}
typeid(type) or typeid(expression)
3 R->L +
Unary plus
Unary minus
Logical NOT
Bitwise NOT
C-style cast
Size in bytes
Address of
Dynamic memory allocation
Dynamic array allocation
Dynamic memory deletion
Dynamic array deletion
sizeof(type) or sizeof(expression)
new type
new type[expression]
delete pointer
delete[] pointer
4 L->R ->*
Member pointer selector
Member object selector
5 L->R *
expression * expression
expression / expression
expression % expression
6 L->R +
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 ==
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 R->L ?:
Conditional (see note below)
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
expression ? expression : expression
lvalue = expression
lvalue *= expression
lvalue /= expression
lvalue %= expression
lvalue += expression
lvalue -= expression
lvalue <<= expression
lvalue >>= expression
lvalue &= expression
lvalue |= expression
lvalue ^= expression
16 R->L throw Throw expression throw expression
17 L->R , Comma operator expression, expression

Note: The expression in the middle of the conditional operator ?: is evaluated as if it were parenthesized.

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 right now. 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.

That said, if you have an expression that uses operators of different types, it is a best practice to use parenthesis to explicitly disambiguate the order of evaluation.

Rule: If your expression uses different operators, use parenthesis to make it clear how the expression should evaluate, even if they are technically unnecessary.

How do I do exponents?

You’ll note that the ^ operator (commonly used to denote exponentiation in standard mathematical nomenclature) is a Bitwise XOR operation in C++. C++ does not include an exponent operator. To do exponents in C++, #include the <cmath> header, and use the pow() function:

Note that the parameters and return value of pow are of type double. Note that due to rounding errors in floating point numbers, the results of pow() may not be precise (slightly smaller or larger than what you’d expect).

If you want to do integer exponents, you’re best off just using your own function to do so, like this one (that uses the “exponentiation by squaring” algorithm for efficiency):

Don’t worry if you don’t understand all of the parts of this function yet. Just beware of overflowing your integer result, which can happen very quickly if either argument is large.


1) You know from everyday mathematics that expressions inside of parentheses 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 parentheses. 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;


1) Show Solution

3.2 -- Arithmetic operators
2.10 -- Chapter 2 comprehensive quiz

96 comments to 3.1 — Operator precedence and associativity

  • RAR

    Consider this snippet:

    According to the precedence table, the expression is evaluated as z = ((y++) + 5);
    Looks like value of z will be 7.

    But after these two lines are executed, the values are z = 6 and y = 2. I’m confused in this part. Thank you.

    • nascardriver

      Hi RAR!
      Your evaluation order is correct, what you missed (or wasn’t covered in this lesson) is the difference of i++ and ++i.
      Both will increase i by 1. i++ returns the old value of i, ++i returns the new value of i.
      Here’s an example


      So your code will evaluate as follows

  • prince

    you wrote in quiz solution that binary operator "="  has right to left associativity but in table you have shown it l->r i.e left to rigth associative.

  • Jim


    When (if ever) you get the time, I think it would be easier to read the tables if each column had the same number of rows. The number would be determined (manually) by the column needing separation from the previous and next row.

    For example, in Table above, the precedence 8 L->R needs only 1 row, but there are 4 operators, descriptions and patterns. Unfortunately, the descriptions need two rows, or at least the height of two rows, to see (without expanding the browser window to ~1800 pixels, with my font sizes). While I may be among the few who don’t use full-width windows, centering text vertically in a box/cell is often a source of mis-matched text from one column to the next. Even more so when there are 14+ lines of operators or descriptions. I’m sure these extra rows, not spanning multiple columns will cause havoc on your CSS.

    So, an item that causes ,ore than one line of text should be broken into as many rows as needed to display properly, even without enlarging the browser window. If that mean there are 28 rows for that part of the display, All the other columns should be that height also. If few rows are needed for those other columns, just hide the cell top & bottom.

    This way, each item on the left will display on the same horizontal position of the item on its right. The precedence column has the fewest items, so they can still be vertically centered, as you wish.

    Congratulations! You now know why tables are dead and CSS is so much better! Except when MS decides to do things differently. :deadbash:

  • Amir

    Hello! In the first table on this page there’s the operator *. The description should be "Refrence" it’s "Dereference"

    Thank you : )

  • Stephane

    Hi Alex, I think writing a thing like this :

    has an associativity from right to left because member_name belongs to class_name ans not class_name belongs to member_name; idem for namespaces and global scopes.

    • Alex

      Definitely not. The other choices are defensible. Microsoft considers :: to have no associativity, because what comes before the operator and what comes after is always treated as a single unit. Other reference material treats :: as having left to right associativity, since you can’t access an identifier without knowing what namespace it’s in (the namespace has to be known first).

  • Scott

    Hey there!
    I just wanted to say I’m going through your tutorials and I’m loving them! I also have a question about the Quiz part d, and this might be that I really don’t understand how those operators work yet… could that series of conditions be simplified to just b && c? If I’m following it right, once b && c is true, then the remaining questions are also true, right? This isn’t a question about the answer, I’m just wanting to know if I am following how that works. Thanks!

    • Alex

      > could that series of conditions be simplified to just b && c


      > If I’m following it right, once b && c is true, then the remaining questions are also true, right?

      Yes, but we can’t assume b && c will evaluate to true.

  • SotanahT

    Hey there!
    Seems to be an error:
    On answer a), you write that the "+" sign is left to right but on the sheet mention it’s right to left.
    EDIT: I was confused by the + for the unary plus, my bad

    Also I agree with Ole and Happilicious

    Beside these minus stuff, Great work so far

  • Andrew

    Hi everybody. I have a question, but there is something that is driving me crazy.

    How is this evaluated?

    while (exp)
    I’ve seen whiles with statements such as x=>10 or x<=50, but not with only a variable. How is this while triggered?

    • Alex

      exp is implicitly converted to a boolean value and that is evaluated. In general, a value of 0, 0.0, or nullptr will evaluate to false, and everything else will evaluate to true.

  • TOVK

    Great tutorials so far: simple & engaging. Currently on my first read-through. However I’d suggest compiling all the reference tables from all the different tutorial pages into a single (& overly long) reference page/glossary. One could use the CRTL + F search function to find the information that they are looking for. It’d be more convenient than searching the information from different pages & then keeping several tabs opened at the same time. It would be a good & supplementary addition to these tutorials and new programmers could keep the reference page open while debugging their code. Well, at least I would.

  • danny

    why doesn’t the single colon have a precedence?

  • Rayon

    I know that a few sentences in this program are not in English ,but i don’t think it matters that much because the error i keep getting is that sqrt was not declared.Do you know what the problem is?

    #include <iostream>
    using namespace std;

    int main()
        int a,b,c,D;
        float x1,x2;
        cout<<"Vnesi gi a, b i c od kvadratnata ravenka: ";
        if(D<0) cout<<"Ravenkata nema resenie za ovie koeficienti!";
        if(D==0) cout<<"Ravenkata ima edno resenie: "<<-b/2*a;
        if(D>0) {
            cout<<"Kvadratnata ravenka: "<<a<<"x^2+"<<b<<"x+"<<c<<"=0 ima dve resenija\nx1="<<x1<<"\nx2="<<x2;
        return 0;

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter