# C++ Programming

## Operators

Now that we have covered the variables and data types it becomes possible to introduce operators. Operators are special symbols that are used to represent and direct simple computations. They have significant importance in programming since they serve to define actions and simple interactions with data in a direct, non-abstract way.

Since computers are mathematical devices, compilers and interpreters require a full syntactic theory of all operations in order to correctly parse formulas involving combinations of symbols. In particular, they depend on operator precedence rules just as mathematical writing depends on order of operations. Conventionally, the computing usage of operator also goes beyond the mathematical usage (for functions).

C++, like all programming languages, uses a set of operators. They are subdivided into several groups:

• arithmetic operators (like addition and multiplication).
• boolean operators.
• string operators (used to manipulate strings of text).
• pointer operators.
• named operators (operators such as sizeof, new, and delete defined by alphanumeric names rather than a punctuation character).

Most of the operators in C++ do exactly what you would expect them to do because most are common mathematical symbols. For example, the operator for adding two integers is +. C++ does allows the re-definition of some operators (operator overloading) on more complex types. This will be covered later on.

Expressions can contain both variables names and integer values. In each case the name of the variable is replaced with its value before the computation is performed.

### Order of operations

When more than one operator appears in an expression, the order of evaluation depends on the rules of precedence. A complete explanation of precedence can get complicated, but just to get you started:

Multiplication and division happen before addition and subtraction. So 2*3-1 yields 5, not 4, and 2/3-1 yields -1, not 1 (remember that in integer division 2/3 is 0). If the operators have the same precedence they are evaluated from left to right. So in the expression minute*100/60, the multiplication happens first, yielding 5900/60, which in turn yields 98. If the operations had gone from right to left, the result would be 59*1 which is 59, which is wrong.

Any time you want to override the rules of precedence (or you are not sure what they are) you can use parentheses. Expressions in parentheses are evaluated first, so 2 * (3-1) is 4. You can also use parentheses to make an expression easier to read, as in (minute * 100) / 60, even though it doesn't change the result.

### Precedence (Composition)

At this point we have looked at some of the elements of a programming language like variables, expressions, and statements in isolation, without talking about how to combine them.

One of the most useful features of programming languages is their ability to take small building blocks and compose them (solving big problems by taking small steps at a time). For example, we know how to multiply integers and we know how to output values. It turns out we can do both at the same time:

```std::cout << 17 * 3;
```

Actually, we shouldn't say "at the same time," since in reality the multiplication has to happen before the output. The point is that any expression involving numbers, characters, and variables can be used inside an output statement. We've already seen one example:

```std::cout << hour * 60 + minute << std::endl;
```

You can also put arbitrary expressions on the right-hand side of an assignment statement:

```int percentage;
percentage = ( minute * 100 ) / 60;
```

This ability may not seem so impressive now, but we will see other examples where composition makes it possible to express complex computations neatly and concisely.

 Note: There are limits on where you can use certain expressions. Most notably, the left-hand side of an assignment statement (normally) has to be a variable name, not an expression. That's because the left side indicates the storage location where the result will go. Expressions do not represent storage locations, only values.

The following is illegal:

``` minute+1 = hour;
```

The exact rule for what can go on the left-hand side of an assignment expression is not so simple as it was in C; as operator overloading and reference types can complicate the picture.

## Chaining

```std::cout << "The sum of " << a << " and " << b << " is " << sum << "\n";
```

The above line illustrates what is called chaining of insertion operators to print multiple expressions. How this works is as follows:

1. The leftmost insertion operator takes as its operands, std::cout and the string "The sum of ", it prints the latter using the former, and returns a reference to the former.
2. Now std::cout << a is evaluated. This prints the value contained in the location a, i.e. 123 and again returns std::cout.
3. This process continues. Thus, successively the expressions std::cout << " and ", std::cout << b, std::cout << " is ", std::cout << " sum ", std::cout << "\n" are evaluated and the whole series of chained values is printed.

## Table of operators

Operators in the same group have the same precedence and the order of evaluation is decided by the associativity (left-to-right or right-to-left). Operators in a preceding group have higher precedence than those in a subsequent group.

 Note: Binding of operators actually cannot be completely described by "precedence" rules, and as such this table is an approximation. Correct understanding of the rules requires an understanding of the grammar of expressions.
Operators Description Example Usage Associativity
Scope Resolution Operator
:: unary scope resolution operator
for globals
::NUM_ELEMENTS
:: binary scope resolution operator
for class and namespace members
std::cout

Function Call, Member Access, Post-Increment/Decrement Operators, RTTI and C++ Casts Left to right
() function call operator swap (x, y)
[] array index operator arr [i]
. member access operator
for an object of class/union type
or a reference to it
obj.member
-> member access operator
for a pointer to an object of
class/union type
ptr->member
++ -- post-increment/decrement operators num++
typeid() run time type identification operator
for an object or type
typeid (std::cout)
typeid (std::iostream)
static_cast<>()
dynamic_cast<>()
const_cast<>()
reinterpret_cast<>()
C++ style cast operators
for compile-time type conversion
static_cast<float> (i)
dynamic_cast<std::istream> (stream)
const_cast<char*> ("Hello, World!")
reinterpret_cast<const long*> ("C++")
type() functional cast operator
(static_cast is preferred
for conversion to a primitive type)
float (i)
also used as a constructor call
for creating a temporary object, esp.
of a class type
std::string ("Hello, world!", 0, 5)

Unary Operators Right to left
!, not logical not operator !eof_reached
~, compl bitwise not operator ~mask
+ - unary plus/minus operators -num
++ -- pre-increment/decrement operators ++num
* indirection operator *ptr
new
new[]
new()
new()[]
new operators
for single objects or arrays
new std::string (5, '*')
new int 
new (raw_mem) int
new (arg1, arg2) int 
delete
delete[]
delete operator
for pointers to single objects or arrays
delete ptr
delete[] arr
sizeof
sizeof()
sizeof operator
for expressions or types
sizeof `123`
sizeof `(int)`
(type) C-style cast operator (deprecated) (float)i

Member Pointer Operators Right to left
.* member pointer access operator
for an object of class/union type
or a reference to it
obj.*memptr
->* member pointer access operator
for a pointer to an object of
class/union type
ptr->*memptr

Multiplicative Operators Left to right
* / % multiplication, division and
modulus operators
celsius_diff * 9 / 5

+ - addition and subtraction operators end - start + 1

Bitwise Shift Operators Left to right
<<
>>
left and right shift operators bits << shift_len
bits >> shift_len

Relational Inequality Operators Left to right
< > <= >= less-than, greater-than, less-than or
equal-to, greater-than or equal-to
i < num_elements

Relational Equality Operators Left to right
== !=, not_eq equal-to, not-equal-to choice != 'n'

Bitwise And Operator Left to right

Bitwise Xor Operator Left to right

Bitwise Or Operator Left to right

Logical And Operator Left to right
&&, and arr != 0 && arr->len != 0

Logical Or Operator Left to right
||, or arr == 0 || arr->len == 0

Conditional Operator Right to left
?: size >= 0 ? size : 0

Assignment Operators Right to left
= assignment operator i = 0
+= -= *= /= %=
&=, and_eq
|=, or_eq
^=, xor_eq <<= >>=
shorthand assignment operators
(foo op= bar represents
foo = foo op bar)
num /= 10

Exceptions
throw throw "Array index out of bounds"

Comma Operator Left to right
, i = 0, j = i + 1, k = 0

### Assignment

The most basic assignment operator is the "=" operator. It assigns one variable to have the value of another. For instance, the statement x = 3 assigns x the value of 3, and y = x assigns whatever was in x to be in y. When the "=" operator is used to assign a class or struct it acts as if the "=" operator was applied on every single element. For instance:

```//Example to demonstrate default "=" operator behavior.

struct A
{
int i;
float f;
A * next_a;
};

//Inside some function
{
A a1, a2;              // Create two A objects.

a1.i = 3;              // Assign 3 to i of a1.
a1.f = 4.5;            // Assign the value of 4.5 to f in a1
a1.next_a = &a2;       // a1.next_a now points to a2

a2.next_a = NULL;      // a2.next_a is guaranteed to point at nothing now.
a2.i = a1.i;           // Copy over a1.i, so that a2.i is now 3.
a1.next_a = a2.next_a; // Now a1.next_a is NULL

a2 = a1;               // Copy a1 to a2, so that now a2.f is 4.5. The other two are unchanged, since they were the same.
}
```

Assignments can also be chained since the assignment operator returns the value it assigns. This time the chaining is from right to left. For example, to assign the value of z to y and assign the same value (which is returned by the = operator) to x you use:

```x = y = z;
```

When the "=" operator is used in a declaration it has special meaning. It tells the compiler to directly initialize the variable from whatever is on the right-hand side of the operator. This is called defining a variable, in the same way that you define a class or a function. With classes, this can make a difference, especially when assigning to a function call:

```class A { /* ... */ };
A foo () { /* ... */ };

// In some function
{
A a;
a = foo();

A a2 = foo();
}
```

In the first case, a is constructed, then is changed by the "=" operator. In the second statement, a2 is constructed directly from the return value of foo(). In many cases, the compiler can save a lot of time by constructing foo()'s return value directly into a2's memory, which makes the program run faster.

Whether or not you define can also matter in a few cases where a definition can result in different linkage, making the variable more or less available to other source files.

### Arithmetic operators

Arithmetic operations that can be performed on integers (also common in many other languages) include:

• Addition, using the `+` operator
• Subtraction, using the `-` operator
• Multiplication, using the `*` operator
• Division, using the `/` operator
• Remainder, using the `%` operator

Consider the next example. It will perform an addition and show the result:

```#include<iostream>

using namespace std;
int main()
{
int a = 3, b = 5;
cout << a << '+' << b << '=' << (a+b);
return 0;
}
```

The line relevant for the operation is where the + operator adds the values stored in the locations a and b. a and b are said to be the operands of +. The combination a + b is called an expression, specifically an arithmetic expression since + is an arithmetic operator.

Addition, subtraction, and multiplication all do what you expect, but you might be surprised by division. For example, the following program:

```int hour, minute;
hour = 11;
minute = 59;
std::cout << "Number of minutes since midnight: ";
std::cout << hour*60 + minute << std::endl;
std::cout << "Fraction of the hour that has passed: ";
std::cout << minute/60 << std::endl;
```

would generate the following output:

Number of minutes since midnight: 719
Fraction of the hour that has passed: 0

The first line is what we expected, but the second line is odd. The value of the variable minute is 59, and 59 divided by 60 is 0.98333, not 0. The reason for the discrepancy is that C++ is performing integer division.

When both of the operands are integers (operands are the things operators operate on) the result must also be an integer, and by definition integer division always rounds down even in cases like this where the next integer is so close.

A possible alternative in this case is to calculate a percentage rather than a fraction:

```std::cout << "Percentage of the hour that has passed: ";
std::cout << minute*100/60 << std::endl;
```

The result is:

Percentage of the hour that has passed: 98

Again the result is rounded down, but at least now the answer is approximately correct. In order to get an even more accurate answer we could use a different type of variable, called floating-point, that is capable of storing fractional values.

This next example:

```#include<iostream>

using namespace std;
int main()
{
int a = 33, b = 5;
cout << "Quotient = " << a / b << endl;
cout << "Remainder = "<< a % b << endl;
return 0;
}
```

will return:

```Quotient = 6
Remainder = 3
```

The multiplicative operators *, / and % are always evaluated before the additive operators + and -. Among operators of the same class, evaluation proceeds from left to right. This order can be overridden using grouping by parentheses, ( and ); the expression contained within parentheses is evaluated before any other neighboring operator is evaluated. But note that some compilers may not strictly follow these rules when they try to optimize the code being generated, unless violating the rules would give a different answer.

For example the following statements convert a temperature expressed in degrees Celsius to degrees Fahrenheit and vice versa:

```deg_f = deg_c * 9 / 5 + 32;
deg_c = ( deg_f - 32 ) * 5 / 9;
```

### Compound assignment

One of the most common patterns in software with regards to operators is to update a value:

```a = a + 1;  //Increases a by 1
b = b * 2;  //Multiplies b by 2
c = c / 4;  //Divides c by 4
```

Since this pattern is used many times, there is a shorthand for it called compound assignment operators. They are a combination of an existing arithmetic operator and assignment operator:

• +=
• -=
• *=
• /=
• %=
• <<=
• >>=
• |=
• &=
• ^=

Thus the example given in the beginning of the section could be rewritten as

```a += 1;  // Equivalent to (a = a + 1)
b *= 2;  // Equivalent to (b = b * 2)
c /= 4;  // Equivalent to (c = c / 4)
```

### Pre and Post Increment

Another common pattern is to increase or decrease a value by just 1. This is often used to keep a count of how many times the code has run:

• a++
• a--
• ++a
• --a
• count++

We can again use the previous example and rewrite it as:

```a++  // Equivalent to both (a = a + 1) and a += 1
a--  // Equivalent to both (a = a - 1) and a -= 1
```

However, while "a++" and "++a" look similar, they can result in different values. Post Increment:

```a++  // Increments after processing the current statement
```

Pre Increment:

```++a  // Increments before processing the current statement
```

In both examples above, a will be incremented by 1. This may not seem like a big difference, however when used in practice, it may not always be equivalent. For example:

```x = 2
a = x++  // a = 2 and x = 3
```

In the above post increment example, a is assigned to the value of x first, then x is incremented. Since we know that x is 2, a is then assigned the value of 2, afterwards, x is incremented to 3.

```x = 2
a = ++x  // a = 3 and x = 3
```

In the above pre increment example, x is incremented and a is assigned to the incremented value. Since we know that x is 2, and it is being incremented by 1, a is assigned the value of 3, and x has been incremented to 3. To do:Parent topic may need a re-writing. About optimization and distinction on the steps in a += 1, a = a + 1, ++a or a++.

### Character operators

Interestingly, the same mathematical operations that work on integers also work on characters.

```char letter;
letter = 'a' + 1;
std::cout << letter << std::endl;
```

For the above example, outputs the letter b (on most systems -- note that C++ doesn't assume use of ASCII, EBCDIC, Unicode etc. but rather allows for all of these and other charsets). Although it is syntactically legal to multiply characters, it is almost never useful to do it.

Earlier I said that you can only assign integer values to integer variables and character values to character variables, but that is not completely true. In some cases, C++ converts automatically between types. For example, the following is legal.

```int number;
number = 'a';
std::cout << number << std::endl;
```

On most mainstream desktop computers the result is 97, which is the number that is used internally by C++ on that system to represent the letter 'a'. However, it is generally a good idea to treat characters as characters, and integers as integers, and only convert from one to the other if there is a good reason. Unlike some other languages, C++ does not make strong assumptions about how the underlying platform represents characters; ASCII, EBCDIC and others are possible, and portable code will not make assumptions (except that '0', '1', ..., '9' are sequential, so that e.g. '9'-'0' == 9).

Automatic type conversion is an example of a common problem in designing a programming language, which is that there is a conflict between formalism, which is the requirement that formal languages should have simple rules with few exceptions, and convenience, which is the requirement that programming languages be easy to use in practice.

More often than not, convenience wins, which is usually good for expert programmers, who are spared from rigorous but unwieldy formalism, but bad for beginning programmers, who are often baffled by the complexity of the rules and the number of exceptions. In this book I have tried to simplify things by emphasizing the rules and omitting many of the exceptions.

### Bitwise operators

These operators deal with a bitwise operations. Bit operations needs the understanding of binary numeration since it will deal with on one or two bit patterns or binary numerals at the level of their individual bits. On most microprocessors, bitwise operations are sometimes slightly faster than addition and subtraction operations and usually significantly faster than multiplication and division operations.

Bitwise operations especially important for much low-level programming from optimizations to writing device drivers, low-level graphics, communications protocol packet assembly and decoding.

Although machines often have efficient built-in instructions for performing arithmetic and logical operations, in fact all these operations can be performed just by combining the bitwise operators and zero-testing in various ways.

The bitwise operators work bit by bit on the operands. The operands must be of integral type (one of the types used for integers).

For this section, recall that a number starting with 0x is hexadecimal (hexa, or hex for short or referred also as base-16). Unlike the normal decimal system using powers of 10 and the digits 0123456789, hex uses powers of 16 and the symbols 0123456789abcdef. In the examples remember that Oxc equals 1100 in binary and 12 in decimal. C++ does not directly support binary notation, which would hamper readability of the code.

NOT
~a
bitwise complement of a.
~0xc produces the value -1-0xc (in binary, ~1100 produces ...11110011 where "..." may be many more 1 bits)

The negation operator is a unary operator which precedes the operand, This operator must not be confused with the "logical not" operator, "`!`" (exclamation point), which treats the entire value as a single Boolean—changing a true value to false, and vice versa. The "logical not" is not a bitwise operation.

These others are binary operators which lie between the two operands. The precedence of these operators is lower than that of the relational and equivalence operators; it is often required to parenthesize expressions involving bitwise operators.

AND
a & b
bitwise boolean and of a and b
0xc & 0xa produces the value 0x8 (in binary, 1100 & 1010 produces 1000)

The truth table of a AND b:

a b
1 1 1
1 0 0
0 1 0
0 0 0
OR
a | b
bitwise boolean or of a and b
0xc | 0xa produces the value 0xe (in binary, 1100 | 1010 produces 1110)

The truth table of a OR b is:

a b
1 1 1
1 0 1
0 1 1
0 0 0

XOR
a ^ b
bitwise xor of a and b
0xc ^ 0xa produces the value 0x6 (in binary, 1100 ^ 1010 produces 0110)

The truth table of a XOR b:

a b
1 1 0
1 0 1
0 1 1
0 0 0
Bit shifts
a << b
shift a left by b (multiply a by $2^{b}$ )
0xc << 1 produces the value 0x18 (in binary, 1100 << 1 produces the value 11000)
a >> b
shift a right by b (divide a by $2^{b}$ )
0xc >> 1 produces the value 0x6 (in binary, 1100 >> 1 produces the value 110)

### Derived types operators

There are three data types known as pointers, references, and arrays, that have their own operators for dealing with them. Those are *, &, [], ->, .*, and ->*.

Pointers, references, and arrays are fundamental data types that deal with accessing other variables. Pointers are used to pass around a variables address (where it is in memory), which can be used to have multiple ways to access a single variable. References are aliases to other objects, and are similar in use to pointers, but still very different. Arrays are large blocks of contiguous memory that can be used to store multiple objects of the same type, like a sequence of characters to make a string.

#### Subscript operator [ ]

This operator is used to access an object of an array. It is also used when declaring array types, allocating them, or deallocating them.

##### Arrays

An array stores a constant-sized sequential set of blocks, each block containing a value of the selected type under a single name. Arrays often help organize collections of data efficiently and intuitively.

It is easiest to think of an array as simply a list with each value as an item of the list. Where individual elements are accessed by their position in the array called its index, also known as subscript. Each item in the array has an index from 0 to (the size of the array) -1, indicating its position in the array.

• Random access in O(1) (Big O notation)
• Ease of use/port: Integrated into most modern languages

• Constant size
• Constant data-type
• Large free sequential block to accommodate large arrays
• When used as non-static data members, the element type must allow default construction
• Arrays do not support copy assignment (you cannot write `arraya = arrayb`)
• Arrays cannot be used as the value type of a standard container
• Syntax of use differs from standard containers
• Arrays and inheritance don't mix (an array of Derived is not an array of Base, but can too easily be treated like one)
 Note: If complexity allows you should consider the use of containers (as in the C++ Standard Library). You should and can use for example std::vector which are as fast as arrays in most situations, can be dynamically resized, support iterators, and lets you treat the storage of the vector just like an array. In C++11, std::array provides a fixed size array which is guaranteed to be as efficient as an old-style array but with some advantages such as being able to be queried for its size, using iterators like other containers, and having a copy assignment operator. (Modern C allows VLAs, variable length arrays, but these are not used in C++, which already had a facility for re-sizable arrays in std::vector.) The pointer operator as you will see is similar to the array operator.

For example, here is an array of integers, called List with 5 elements, numbered 0 to 4. Each element of the array is an integer. Like other integer variables, the elements of the array start out uninitialized. That means it is filled with unknown values until we initialize it by assigning something to it. (Remember primitive types in C are not initialized to 0.)

 Index Data 00 unspecified 01 unspecified 02 unspecified 03 unspecified 04 unspecified

Since an array stores values, what type of values and how many values to store must be defined as part of an array declaration, so it can allocate the needed space. The size of array must be a const integral expression greater than zero. That means that you cannot use user input to declare an array. You need to allocate the memory (with operator new[]), so the size of an array has to be known at compile time. Another disadvantage of the sequential storage method is that there has to be a free sequential block large enough to hold the array. If you have an array of 500,000,000 blocks, each 1 byte long, you need to have roughly 500 megabytes of sequential space to be free; Sometimes this will require a defragmentation of the memory, which takes a long time.

To declare an array you can do:

```int numbers; // creates an array of 30 integers
```

or

```char letters; // create an array of 4 characters
```

and so on...

to initialize as you declare them you can use:

```int vector={0,0,1,0,0,0};
```

this will not only create the array with 6 int elements but also initialize them to the given values.

If you initialize the array with less than the full number of elements, the remaining elements are set to a default value - zero in the case of numbers.

```int vector={0,0,1}; // this is the same as the example above
```

If you fully initialize the array as you declare it, you can allow the compiler to work out the size of the array:

```int vector[]={0,0,1,0,0,0};  // the compiler can see that there are 6 elements
```
###### Assigning and accessing data

You can assign data to the array by using the name of the array, followed by the index.

For example to assign the number 200 into the element at index 2 in the array

```
List = 200;
```

will give

 Index Data 00 unspecified 01 unspecified 02 200 03 unspecified 04 unspecified

You can access the data at an element of the array the same way.

```std::cout << List << std::endl;
```

This will print 200.

Basically working with individual elements in an array is no different then working with normal variables.

As you see accessing a value stored in an array is easy. Take this other example:

```int x;
x = vector;
```

The above declaration will assign x the valued store at index 2 of variable vector which is 1.

Arrays are indexed starting at 0, as opposed to starting at 1. The first element of the array above is vector. The index to the last value in the array is the array size minus one. In the example above the subscripts run from 0 through 5. C++ does not do bounds checking on array accesses. The compiler will not complain about the following:

```char y;
int z = 9;
char vector = { 1, 2, 3, 4, 5, 6 };

// examples of accessing outside the array. A compile error is not raised
y = vector;
y = vector[-4];
y = vector[z];
```

During program execution, an out of bounds array access does not always cause a run time error. Your program may happily continue after retrieving a value from vector[-1]. To alleviate indexing problems, the sizeof expression is commonly used when coding loops that process arrays.

```int ix;
short anArray[]= { 3, 6, 9, 12, 15 };

for (ix=0; ix< (sizeof(anArray)/sizeof(short)); ++ix) {
DoSomethingWith( anArray[ix] );
}
```

Notice in the above example, the size of the array was not explicitly specified. The compiler knows to size it at 5 because of the five values in the initializer list. Adding an additional value to the list will cause it to be sized to six, and because of the sizeof expression in the for loop, the code automatically adjusts to this change.

###### multidimensional arrays

You can also use multi-dimensional arrays. The simplest type is a two dimensional array. This creates a rectangular array - each row has the same number of columns. To get a char array with 3 rows and 5 columns we write...

```char two_d;
```

To access/modify a value in this array we need two subscripts:

```char ch;
ch = two_d;
```

or

```two_d = 'x';
```
###### example

There are also weird notations possible:

```int a;
int i = 0;
if (a[i]==i[a])
printf("Hello World!\n");
```

a[i] and i[a] point to the same location. You will understand this better after knowing about pointers.

To get an array of a different size, you must explicitly deal with memory using realloc, malloc, memcpy, etc.

###### Why start at 0?

Most programming languages number arrays from 0. This is useful in languages where arrays are used interchangeably with a pointer to the first element of the array. In C++ the address of an element in the array can be computed from (address of first element) + i, where i is the index starting at 0 (a == *(a + 1)). Notice here that "(address of the first element) + i" is not a literal addition of numbers. Different types of data have different sizes and the compiler will correctly take this into account. Therefore, it is simpler for the pointer arithmetic if the index started at 0.

###### Why no bounds checking on array indexes?

C++ does allow for, but doesn't force, bounds-checking implementations, in practice little or no checking is done. It affects storage requirements (needing "fat pointers") and impacts runtime performance. However, the std::vector template class, that we mentioned and we will examine later in greater detail (a template class container, representing an array provides the at() method) which does enforce bounds checking. Also in many implementations, the standard containers include particularly complete bounds checking in debug mode. They might not support these checks in release builds, as any performance reduction in container classes relative to built-in arrays might prevent programmers from migrating from arrays to the more modern, safer container classes.

 Note: Some compilers, or external tools, can help detect issues outside of the language specifications, even in an automated faction. See the section about debugging for more information.