Chapter 8 C++ Variables, Types and Operators

In this and subsequent chapters, we will use C++ snippets throughout. Recall that snippets are segments of C++ programs, and so cannot be run on their own. If you wish to execute them on your computer, you will need to write a full C++ program, including the #incude statements, namespace declaration and main function, and then add the snippet inside the main function. To see a full C++ program, refer to the Hello, world! program in the previous chapter.

In this chapter, we will cover the concepts of variables, types and operators as we did in Python. Because these concepts are essentially the same as Python’s (aside from some of the specifics), we will not dwell too long on them here. We will start with a discussion of variables and their types, and identify how they differ from what we’ve seen in Python. We will quickly recap operators, for which everything is roughly the same.

8.1 Variables

As in Python, C++ supports the concept of a variable. A variable is used to store (“remember”) a particular value in memory, to which we can then refer to perform computation. A variable is identified by its name, which consists of a series of one or more of letters, digits or underscores. Variables should be given meaningful names to aid in readability—short names can indeed be meaningful, while overly long names can annoy. In C++, a name must start with a letter, and it may contain letters, digits and underscores. Note that just like Python, C++ is case-sensitive, and so a variable with name x is different from a variable with name X. There are certain C++ keywords which cannot be used as variable names, and are listed below.

A list of keywords. Note that the list may vary depending on which version of is being used.
asm else new this
auto enum operator throw
bool explicit private true
break export protected try
case extern public typedef
catch false register typeid
char float reinterpret_cast typename
class for return union
const friend short unsigned
const_cast goto signed using
continue if sizeof virtual
default inline static void
delete int static_cast volatile
do long struct wchar_t
double mutable switch while
dynamic_cast namespace template

Question! Which of the following names are valid C++ variable names? For invalid names, why are they invalid?

  1. x
  2. number_of_people
  3. total-amount
  4. NAME
  5. class
  6. 2pac
  7. pac2
  8. FroggyFresh
  9. return
  10. FalsE
  11. false

Finally, though not required, C++ convention is to use camel-case for variable names—camel-case means that if a variable name consists of multiple words, then the first word starts with a small letter, and all other words begin with capitals. For example, totalAmount and numberOfPeople are instances of camel-case.

8.2 Types

In C++, each variable has an associated type, which tells the compiler what kind of data the variable will store. This allows the compiler to reserve the appropriate amount of memory. While variables in Python also had types, we were free to change the types throughout the program. This is why we refer to Python as a dynamically-typed language. By contrast, C++ is statically-typed, which means that once a variable has a particular type, it can never change.

For example, the following Python code is perfectly legal:

x = 0
print(type(x))  # prints <class 'int'>
x = "Hello"  # the variable type changes!
print(type(x))  # prints <class 'int'>

If we were to try a similar thing in C++, the compiler would give us an error. For example

int x = 0;
// to use typeid, you must include <typeinfo>
cout << typeid(x).name() << endl;  // prints i(nt)
x = "Hello";  //not allowed to change from integer to string!
cout << typeid(x).name() << endl;

produces the compilation error:

error: invalid conversion from ‘const char*’ to ‘int’

C++ provides a set of built-in types, and offers users the ability to define new types themselves (user-defined types). Some of the more important built-in types include int (integer), double (real number), char (a single character) and bool (a boolean: either true or false). string, which stores text, is technically not a built-in data type (i.e. it is not part of the core language), but is universally supported and can almost be treated as such.

The table below lists the set of most-commonly used C++ types. Note that C++ has different types for strings, and chars, which simply represent a single character. For strings, we use double quotation marks, but for characters we use single quotation marks.

A table of common C++ types.
Name Keyword Kind Values allowed Example l iterals Python Equivalent
Boolean bool Built-in True/False true, false bool
Character char Built-in A single character ’a’, ’9’, ’\n’ str
Integer int (also short/long) Built-in Integers within some range 0, -1, int
Floating-point double (also float) Built-in Real-valued numbers in a range with some precision 1.2, -0.6 float
String string Standard library Sequence of characters "SaltBae", "Hi\nthere" str

A couple of additional points about C++ data types. There are a number of integer data types, but the one we will use most often is int. A variable of type int is guaranteed to be able to store a 16-bit integer, but on most modern machines will store a 32-bit one. There is also long long, which is guaranteed to be at least 64 bits and should be used to store very large numbers. For decimal numbers, we will always use double, which is normally a 64-bit number. C++ provides float, which is usually half the size of double and only takes up 32 bits, but because memory is no longer a concern, we will simply stick with double everywhere.

Finally, we can convert data types from one to another using casting. Note that this generally applies to numerical types—we cannot cast a string to an integer, for example. Some examples are given below

int x = 1; // x is an integer with value 1
double y = (double) x; // x is cast to a double. y has a value of 1.0
double z = 2.5
x = (int) z; // z is cast to an int. x now has a value of 2

8.3 Creating Variables with Values

8.3.1 Declaration

The very first time a variable is introduced into a C++ program, we must specify its type. We only define the type this first type, and then afterwards simply refer to the variable by its name. Creating a variable with a name and type is called declaration. Some examples of variable declarations are below:

int x;
double y; 
string someMeaningfulName;

Note that by declaring a variable, we have not yet given it a value. We have simply told the compiler that it must assign memory to hold such a variable. Because we have not given the above variables values, they are said to be uninitialised, with unknown or undefined values.

8.3.2 Initialisation

If we wish to create a variable and give it a value, we can do so using initialisation. Initialisation simply refers to the case where we assign a value to a variable at the point of declaration. Note that initialisation is optional—we could declare a variable, and then only much later in the program give it a value. Examples of variable initialisation are below:

int x = 42; 
double y = 2.45824406892; 
string someMeaningfulName = "Pogba's Haircuts";

8.3.3 Assignment

After having declared (and potentially initialised) a variable, we are able to later set its value through assignment, which works in the exact same way as Python. Here we simply use the = sign to assign the value of the right-hand side to the variable on the left. Below are examples of variable assignment:

int x;
x = 42; // happens after declaration -> assignment
int y = 23;
x = y;

It is important to note in all cases that, just as in Python, we must declare a variable before we use it. In the snippet below, we would encounter a compilation error because we have tried to use y before it has been declared.

int x = y + 2; //What is y?! 
int y = 20; //Too late! We needed it for the previous line

It is also very important that we do not work with uninitialised variables. This is a major source of errors and they can take a long time to track down. In the example below, the compiler would not issue an error because the code is valid, but it likely would not work as we expect because y’s value is undefined.

int y; int x = y + 2; //y has an undefined value. What's undefined + 2?!
int y = 20; //Too late! We needed it for the previous line

8.4 Operators

The operators provided by C++ are exactly those offered by Python, and identical precedence rules apply. One very important thing to note is that we must be very careful of integer division, which occurs when the division operator is applied to two integers and produces an integer as a result. If this is undesirable, at least one of the two operands must be a double or float. The following table contains a list of built-in operators, and is followed by some examples of them in practice.

C++ operators applied to different data types. If there is no entry in the table, then the operator cannot be applied to that type.
bool char int double string
assignment = = = = =
addition + +
concatenation +
subtraction - -
multiplication * *
division / /
remainder (modulo) %
increment (add) by 1 ++ ++
decrement (subtract) by 1
increment by n +=n +=n
add s to end +=s
decrement by n -=n -=n
multiply and assign *=n *=n
divide and assign /=n /=n
remainder and assign %=n
equals == == == == ==
not equal != != != != !=
greater than > > > > >
greater than or equal >= >= >= >= >=
less than < < < < <
less than or equal <= <= <= <= <=
negation !
unary minus - -
logical or ||
logical and &&
bool b = true; //b assigned to true
string s = "Hello" //s assigned to Hello
s = s + " world" //s assigned to Hello world (concat)
int x = 5;
x++; //increment, x now equals 6
int y = 7;
bool isEqual = (x == y); // isEqual contains false
int rem = y % x; //rem is the remainder of y divided by x
double z = y; //assign z the current value of y
z *= 3; //equivalent to z = z * 3;
double p = 9.0 / 2; //p is 4.5
double q = 9 / 2;  // integer division!! q is 4

8.4.1 Logical Operators

The C++ logical operators are exactly those in Python. However, there are a couple of differences in syntax. To perform the logical or operation in C++, we must write ||, and to perform logical and we must write &&. As in Python, both && and || are short-circuit operators, meaning that if the expression can be determined after evaluating the first condition, the remaining conditions are not evaluated.

One final difference between the two languages can be seen in the following example. Imagine we wanted to calculate whether a mark was between 50 and 74. In Python, we could write this as:

50 <= mark <= 74  

However, in C++ we must explicitly write this as two separate conditions:

50 <= mark && mark <= 74  

8.4.2 Mathematical Functions

In addition to the above, the C++ standard library offers some additional mathematical functions, such as square rooting and exponentiation. The following code illustrates some basic usage

#include <iostream>
#include <cmath> //need this for math functions like sqrt, pow
using namespace std;
int main(){
        int x = 4;
        x = x + 3;
        int y = x * x; //y is 49
        y = sqrt(y); //take the square root of y
        x = pow(x, 4); // x to the power of 4
        double p = -x;
        double q = abs(p); // the absolute value of p
        return 0;
}

8.4.3 Precedence

The rules of precedence for Python and C++ are identical, and we list them in the table below for reference.

Rules of precedence in C++.
Precedence Level Operator/Symbol Operation Evaluation direction
0 (first) () parentheses Inner ones evaluated first. Left-to-right
1 (unary)-, ! negation (unary minus/NOT) Right-to-left
2 *, /, % product, (integer) division, modulus Left-to-right
3 +, - addition and subtraction Left-to-right
4 <=, <, >, >= less than or equal, less than, greater than, greater than or equal Left-to-right
5 ==, != equal to, not equal to Left-to-right
6 && logical AND Left-to-right
7 || logical OR Left-to-right
8 = assignment Right-to-left

8.5 Summary Lecture