1.5 — A first look at operators

Revisiting expressions

In lesson 1.1 -- Structure of a program, we had defined an expression as “A mathematical entity that evaluates to a value”. However, the term mathematical entity is somewhat vague. More precisely, an expression is a combination of literals, variables, functions, and operators that evaluates to a value.


A literal is a fixed value that has been inserted (hardcoded) directly into the source code, such as 5, or 3.14159. Literals always evaluate to themselves. Here’s an example that uses literals:

Literals, variables, and function calls that return values are all known as operands. Operands supply the data that the expression works with. We just introduced literals, which evaluate to themselves. Variables evaluate to the values they hold. Functions evaluate to produce a value of the function’s return type (unless the return type is void).


The last piece of the expressions puzzle is operators. Operators tell the expression how to combine one or more operands to produce a new result. For example, in the expression “3 + 4”, the + is the plus operator. The + operator tells how to combine the operands 3 and 4 to produce a new value (7).

You are likely already quite familiar with standard arithmetic operators from common usage in math, including addition (+), subtraction (-), multiplication (*), and division (/). Assignment (=) is an operator as well. Some operators use more than one symbol, such as the equality operator (==), which allows us to compare two values to see if they are equal.

Note: One of the most common mistakes that new programmers make is to confuse the assignment operator (=) with the equality operator (==). Assignment (=) is used to assign a value to a variable. Equality (==) is used to test whether two operands are equal in value. We’ll cover the equality operator in more detail later.

Operators come in three types:

Unary operators act on one operand. An example of a unary operator is the - operator. In the expression -5, the - operator is only being applied to one operand (5) to produce a new value (-5).

Binary operators act on two operands (known as left and right). An example of a binary operator is the + operator. In the expression 3 + 4, the + operator is working with a left operand (3) and a right operand (4) to produce a new value (7).

Ternary operators act on three operands. There is only one of these in C++, which we’ll cover later.

Also note that some operators have more than one meaning. For example, the - operator has two contexts. It can be used in unary form to invert a number’s sign (eg. to convert 5 to -5, or vice versa), or it can be used in binary form to do arithmetic subtraction (eg. 4 - 3).


This is just the tip of the iceberg in terms of operators. We will take an in-depth look at operators in more detail in a future section.

1.6 -- Whitespace and basic formatting
1.4d -- A first look at local scope

70 comments to 1.5 — A first look at operators

  • Arush

    Hey Alex,

    Just wanted to tell you that lesson 1.6 seems to not exist. Either that or it’s giving me a 404 error. Is there an alternate way to get to it?

    Thank you.

  • My dear c++ Teacher,
    Please add std::endl at the end of lines 6 and 7. I mean that

    With regards and friendship.

  • Tanya

    {    int a,b;
        float x;
            return 0;   }

    I put the value of a = 10 and b=8, and the answer is given as 1. Why?

  • Andrew

    Alex, you are the man!!

    Quick question - in the code snippet in this lesson, would it be prudent to put "return 0;" before "}" just to be consistent with your style in previous lessons?

    Just a thought - don’t know if it has any merit.


  • manuel okeke

  • My dear c++ Teacher,
    Please let me comment that at the end of 6th line, "std::endl" should be added, as follows:

    With regards and friendship.

    • Alex

      To have nice output, I agree we’d want to output std::endl. But the point of this lesson is to talk about literals, so I’m trying to keep the example as simple and focused as possible.

  • Matt

    Possible typo under "Operators":

    "Note: One of the most common mistakes the new programmers make is to confuse the assignment operator (=) with the equality operator (==)."

    I think maybe you meant to write "that new programmers" instead of "the new programmers".

  • Alfred O.

    Hey Alex, I’m curious about a few things I’m wondering you could tell me about, concerning expressions. The question itself isn’t too bad, it’s just difficult to word clearly and brief. After some research, I had come to this conclusion:

    When an expression evaluates, a temporary object (often called a "temporary") is created to hold the result. This object exists until the end of the full expression, and then it is discarded. If nothing is done with the result of an expression (i.e., the expression has no side effect) it is generally considered a waste.

    ^ Not entirely sure if this is true. This is how I envision an expression evaluating:

    int x = 0, y = 10, z = 15;
    x = y + z;

    1. x, y, and z "evaluate" but the order of such is not specified. A temporary object is created to hold each of their values.
    2. y (10) and z (15) evaluate to 25, another temporary object is created to hold this value.
    3. 25 is copied into x.
    4. All temporaries are destroyed, in the reverse order they were created in, when the statement (or expression?) ends. More specifically, a "destructor" is called for them, much like the destructor of a class object when it goes out of scope.

    It’s possible only one temporary is made, or none. I don’t actually know what the truth is, so I come to you 🙂 I had drawn the conclusion that ALL expressions discard their values in the end (the temporaries created) whether or not their result is used, but I could be-and probably am-wrong about that, too. This might at least explain why an l-value reference cannot bind to something like 5 + 5, but an r-value reference can, one of the reasons I was curious about how expressions are carried out by the machine.

    • Alex

      You’re on the right track. Expressions do create temporary values that are discarded if nothing is done with them. However, expressions do have specific orders in which they are evaluated -- we cover this in lesson 3.1.

      In the above case, y + z are evaluated first, producing temporary rvalue 25. Then operator= is called, and that value of 25 is assigned to variable x. Done.

      • Alfred O.

        Ah! I meant the operands themselves may not evaluate in a specified order (well, I mean not specified by the C++ language, so it is left up to the designers of the compiler itself to decide, or maybe the compiler chooses based on what is more efficient).

        I read something out of curiosity, which led to one thing, which led to another thing, and now I’m so far off my tracks I can’t remember how I got where I’m at, or where I was. I believe it was a wikipedia article on "Sequence Points," something I saw and took note of. According to that, all operands of expressions, and arguments of functions-which I guess could be thought of as arguments of the function call operator ()-aren’t guaranteed to evaluate in any specific order. Which is probably why something like:

        function(i = 5 + x, x = i++, ++y = y - x * i); // Who knows what the heck you’ll get???
        index[i++] = ++i; // I wouldn’t dare to do this anyway

        Some places call it "Order of Evaluation" instead of "Sequence Points." And even more confusing, I stumbled across this article while researching it:

        Looks like they’re trying to change this issue in C++17. If they do, I’ll have to get used to that right after learning about it, LOL. I guess it’s better they keep improving C++, it’s probably worth the headache.

        P.S. When the assignment operator = assigns a value, is this value copied into the variable, or is it "bound" like a reference? Or is the temporary value created by evaluation always discarded, regardless of what happens at the end of an expression?

        Also, thank you for responding to me. And thank you for this web site! It’s made learning the language so much easier. I bought a few of the recommended books (recommended from Stack Oveflow) and they don’t really go out of their way to explain much. After going through a few chapters on this site, and THEN reading the book (not all of it, but one day), the book makes perfect sense, so that tells you a whole lot about how good this site is.

        • Alex

          Don’t worry about sequence points for now. As long as you avoid using a variable with side effects applied more than once in a single expression, you’ll be fine. I cover side effects in more detail in chapter 3.

          When you use assignment, the value is copied. C++ does support references as well -- we also talk about those in chapter 6.

          Any temporary values from expressions are discarded at the end of the expression. Whether you copy those values to a variable (via assignment or initialization) is your choice. We talk more about initialization and assignment in chapter 2.

          I think it’s great that you’re going off the rails and doing your own explorations. Just note that a LOT of your questions are probably covered in future lessons, so keep reading!

          The reason this site exists is because I found most books to be very difficult to understand if you didn’t already know what they were talking about. I try to assume you don’t know anything here. Additionally, this site has gone through a lot of refinement based on reader questions, thoughts, and feedback. That’s one advantage an online site has over a book!

  • Alfred O.

    Alex, can you explain what a "Primary Expression" is? It’s a term I’ve started to run into since taking a break from learning C++. I come back, and now I’m seeing "Primary Expression," "Postfix Expression," and "l-value" and "r-value" has been appended with "x-value," "gl-value," and "pr-value." It’s like I fell through a hole in time-space and woke up in a different dimension. What the heck does all this new stuff mean? Things used to be so simple!

    • Alex

      Yeah, C++11 kind of made a mess of things due to move semantics. From

      a glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function
      a prvalue is an expression whose evaluation either computes the value of the operand of an operator (such prvalue has no result object), or initializes an object or a bit-field (such prvalue is said to have a result object). All class and array prvalues have a result object even if it is discarded.
      an xvalue is a glvalue that denotes an object or bit-field whose resources can be reused
      an lvalue is a glvalue that is not an xvalue.
      an rvalue is a prvalue or an xvalue.

      There are a bunch of examples of each on that page.

      But honestly, I wouldn’t sweat about any of them right now except lvalue and rvalue. You can learn about glvalues, prvalues, and xvalues if and when they become useful in some context that’s relevant to something you need to know.

  • Sam

    Thanks for the tutorial. Very useful!

  • Tristan Gybels

    Hey, Alex!

    Try to make a book of this!
    I would buy this big time! I’m sure you’ll make some big money with it 😉
    You only have to cut ‘n paste everything.

Leave a Comment

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