Introduction to expressions in C++

There are two main parts to a C++ program: the expressions (like mathematical formulas) inside it and the structural glue or constructions that join these expressions together. Thus int main () { .... } is structure, and so are the semicolons you need to put nearly everywhere, but something like x + 1.0 / 1000 is an expression.

Thus expressions are a bit like the things you type into a calculator. Expressions are built from constants such as 1.0 and 1000, variable names such as x age height and operators such as + and /.

To understand expressions you need to understand types. In fact, every expression will have its own special type, and some expressions will evaluate to an int, some to a double, some to a char, and so on.

You will also find out that some operators behave differently on different types, and some operators have "side effects". For example, the = operator has the side effect of saving a value in a box for a variable.

This page is an introduction to expressions: things are deliberately kept very simple here. (And as a consequence there may be one or two very minor white lies, and a huge number of omissions.)

1. Constants and variables

Number constants are written in the way you'd expect, such as 123, -12313, 0.23424, -3455.8, 23.4E+34, -23.4E-4 and so on. (Recall the E means × 10 ? .) In particular it is a double constant if it has a decimal point or an E (or both!), and an int constant otherwise. If you want to write an integer as a double constant the best plan is to include .0 at the end. So for 123 as double, write 123.0.

Char constants use a single quote, string constants use double quotes. Thus 'a', '0', ' ' are valid chars and "", "3.14159", "a" are strings, and '3.14159' is an error.

Variables are just referred to by their name. Of course that name must be in scope, and the compiler will know what type of object the variable is (because you declared it earlier).

2. Binary operators

Most of the operators you need to know about are binary. That means they take the values of two subexpressions, and combine them to give a final answer. Those subexpressions are written to the left and right of the operator, and brackets may be used to ensure that operators are evaluated in the right order.

Things get a bit more complicated when we note that there are several operators for the same symbol. (This is the "overloading" that was mentioned earlier.) Thus + is both a binary operator of ints and a binary operator of doubles. For example, 123 + 23 takes two int values 123 and 23 and adds them, giving the int value 146. Similarly, 12.3 + 2.3 takes two double values 12.3 and 2.3 and adds them, giving the double value 14.6.

One needs to take care here when the types do not agree. For example, 123 + 2.3 takes an int value 123 and a double value 2.3. There is no int+double operator in C++ so what happens is that the int, 123, is first converted to a double, 123.0, prior to addition. The result is the double 125.3 .

The same rules apply to the other arithmetical operators, - * / %. Note that / is both an int operator (division discarding remainder) and a double operator. The % is "remainder on division" and is an int operator only.

These rules can have unexpected consequences for beginners.

Example.

Consider,

  • 10000 + 10000, 100000 + 100000, 1000000 + 1000000, 10000000 + 10000000, 100000000 + 100000000, etc.
  • 10000.0 + 10000.0, 100000.0 + 100000.0, 1000000.0 + 1000000.0, 10000000.0 + 10000000.0, 100000000.0 + 100000000.0, etc.
  • 1 / 4
  • 1.0 / 4

Copy these expressions into your C++ IDE and evaluate them on the computer. Did they give the value you expected?

See the examples associated with this web page for more details.

3. Examples

All of these are for you to look at and try out on your C++ IDE. Try to predict the outcome before you try it.

Example.

To demonstrate integer arithmetic, copy and compile the following.

// expr-ex1.cpp (click here to download)

#include <iostream>

using namespace std;

/* demonstrates int variables and the assignment operator. */
int main () {
  int n;
  int a; // idea: a==10^n multiply by 10 each time
  int b; // idea: b = a+a each time
  
  a = 1; // initialise
  n = 0; // initialise
  while (n < 20) {
    b = a + a;
    cout << "n==" << n << " 10^n==" << a << " 2*10^n==" << b << endl;
    a = 10*a;
    n = n+1;
  }
}

Example.

Here is essentially the same program, but using double arithmetic instead.

// expr-ex1double.cpp (click here to download)

#include <iostream>

using namespace std;

/* same as expr-ex1 but using double instead. */
int main () {
  int n;
  double a; // idea: a==10^n multiply by 10 each time
  double b; // idea: b = a+a each time
  
  a = 1; // initialise
  n = 0; // initialise
  while (n < 20) {
    b = a + a; // double + double is done in double arithmetic
    cout << "n==" << n << " 10^n==" << a << " 2*10^n==" << b << endl;
    a = 10*a; // int * double is done in double arithmetic
    n = n+1;
  }
}

Example.

Division of ints and doubles is illustrated by the following.

// expr-ex2.cpp (click here to download)

#include <iostream>

using namespace std;

/* All the different ways to divide 1 by 4... */
int main () {
  double d;
  int i;

  d = 1.0/4.0;
  cout << "d=1.0/4.0 gives " << d << endl;
  d = 1/4.0;
  cout << "d=1/4.0 gives " << d << endl;
  d = 1.0/4;
  cout << "d=1.0/4 gives " << d << endl;
  d = 1/4;
  cout << "d=1/4 gives " << d << endl;

  i = 1.0/4.0;
  cout << "i=1.0/4.0 gives " << i << endl;
  i = 1/4.0;
  cout << "i=1/4.0 gives " << i << endl;
  i = 1.0/4;
  cout << "i=1.0/4 gives " << i << endl;
  i = 1/4;
  cout << "i=1/4 gives " << i << endl;

}

Example.

The follwing is a variation on repeatedly multiplying and dividing by 10, using double.

// expr-ex3.cpp (click here to download)

#include <iostream>

using namespace std;

/* illustrates a problem with double and == or != */
int main () {
  int n;
  int k = 63;
  double a; // idea: a==10^n multiply by 10 each time
  
  a = 1; // initialise
  n = 0; // initialise
  while (n < k) {
    a = 10*a;
    n = n+1;
  }

  // now reverse the process...
  n = 0;
  while (a != 1.0) { // while a is not exactly 1.0
    a = a/10;
    n = n+1;
  }
  cout << "10^" << k << " was divided by ten " << n << " times to get to 1.0" << endl;
  
}

Example.

What do you think the result of the following program is?

// addrational.cpp (click here to download)

// A puzzle! what happens?
#include <iostream>

using namespace std;

int main() {
  double x = 1.0;
  x = x + 1/10;
  cout << "x = " << x << endl;
  return 0;
}

4. Operators with side-effects

A few operators are special, in that they do something (have a "side-effect") as well as returning a value. An example is = so the expression x = e evaluates e, stores the value in the variable x and returns the same answer as e. This means you can assign two variables x, y with the same value using x = y = e.

The << operator is somewhat similar: cout << e puts the value of e on cout and returns cout. That way, cout << e << f works as expected. Similarly cin >> e gets a value from the console input, puts it in e, and returns cin.

The ++ and -- operators are other useful operators with a side effect: x++ adds one to the variable x (and returns x's old value) and y-- subtracts one from the variable y (and returns y's old value).

5. More

Operators in C++ is a large topic, and experts need to be familiar with them. For further information on operators for this module, see this page.