By Stephen R. Davis

Variables and constants are useful only if you can use them to perform calculations. The term expression is C++ jargon for a calculation. You’ve already seen the simplest expression:

int n;                  // declaration
n = 1;                  // expression

Programmers combine variables, constants and operators to make expressions. An operator performs some arithmetic operation on its arguments. Most operators take two arguments — these are called binary operators. A few operators take a single argument — these are the unary operators.

All expressions return a value and a type.

Binary operators

A binary operator is an operator that takes two arguments. If you can say var1 op var2, then op must be a binary operator. The most common binary operators are the same simple operations that you learned in grade school. The common binary operators appear in the table.

Mathematical Operators in Order of Precedence
Precedence Operator Meaning
1 – (unary) Returns the negative of its argument
2 ++ (unary) Increment
2 — (unary) Decrement
3 * (binary) Multiplication
3 / (binary) Division
3 % (binary) Modulo
4 + (binary) Addition
4 – (binary) Subtraction
5 =, *=,%=,+=,-= (special) Assignment types

The simplest binary is the assignment operator noted by the equals sign. The assignment operator says, “Take the value on the right-hand side and store at the location on the left-hand side of the operator.”

Multiplication, division, addition, subtraction, and modulo are the operators used to perform arithmetic. They work just like the arithmetic operators you learned in grammar school, with the following special considerations:

  • Multiplication must always be expressly stated and is never implied as it is in algebra. Consider the following example:

    int n = 2;              // declare a variable
    int m = 2n;             // this generates an error

    The expression above does not assign m the value of 2 times n. Instead, C++ tries to interpret 2n as a variable name. Since variable names can’t start with a digit, it generates an error during the build step.

    What the programmer meant was:

    int n = 2;
    int m = 2 * n;          // this is OK
  • Integer division throws away the remainder. Thus, the following:

    int n = 13 / 7;         // assigns the value 1 to n

    Fourteen divided by 7 is 2. Thirteen divided by seven is 1.

  • The modulo operator returns the remainder after division (you might not remember modulo):

    int n = 13 % 7;         // sets n to 6

    Fourteen modulo seven is zero. Thirteen modulo seven is six.

Unraveling compound expressions

A single expression can include multiple operators:

int n = 5 + 100 + 32;

When all the operators are the same, C++ evaluates the expression from left to right:

5 + 100 + 32
105 + 32
137

When different operators are combined in a single expression, C++ uses a property called precedence. Precedence is the order that operators are evaluated in a compound expression. Consider the following example:

int n = 5 * 100 + 32;

What comes first, multiplication or addition? Or is this expression simply evaluated from left to right? Refer back to the table, which tells you that multiplication has a precedence of 3, which is higher than the precedence of addition which is 4 (smaller values have higher precedence). Thus multiplication occurs first:

5 * 100 + 32
500 + 32
532

The order of the operations is overruled by the precedence of the operators. As you can see

int n = 32 + 5 * 100;

generates the same result:

32 + 5 * 100
32 + 500
532

But what if you really want 5 times the sum of 100 plus 32? You can override the precedence of the operators by wrapping expressions that you want performed first in parentheses, as follows:

int n = 5 * (100 + 32);

Now the addition is performed before the multiplication:

5 * (100 + 32)
5 * 132
660

You can combine parentheses to make expressions as complicated as you like. C++ always starts with the deepest-nested parentheses it can find and works its way out.

(3 + 2) * ((100 / 20) + (50 / 5))
(3 + 2) * (5 + 10)
5 * 15
75

You can always divide complicated expressions using intermediate variables. The following is safer:

int factor = 3 + 2;
int principal = (100 / 20) + (50 / 5);
int total = factor * principal;

Assigning a name to intermediate values also allows the programmer to explain the parts of a complex equation — making it easier for the next programmer to understand.