Hunter Liu's Website

4. Week 2 Thursday: Increments, Decrements, and Characters

≪ 3. Week 2 Tuesday: Arithmetic, Integers, and Doubles | Table of Contents | 5. Week 3 Tuesday: Handling Input with Strings and cin ≫

Increments and Decrements

The operation of adding or subtracting one from a number is a very common operation in C++. It’s used when counting number of occurrences of an event, keeping track of how many times a loop was repeated, and many others. If n is a numerical variable, the increments n++ and ++n add one to n, and the decrements n-- and --n subtract one from n.

Remark 1. Non-numeric variables can be incremented or decremented too.

The increment and decrement operators can be manually extended to non-numeric variables by programmers in a process called “operator overloading”. This is beyond the scope of this class, but the upshot is that some variables that are not numbers can nevertheless be incremented or decremented. We will see examples of this when we talk about pointers in the distant future.

We’ll focus on the increment operators; everything we say below will have analogous statements for the corresponding decrement operators.

One can think of both n++ and ++n as shortcuts for writing the statement n += 1. When n++ and ++n stand alone, the behaviour is identical:

1int n = 5;
2n++;
3cout << n << endl; // prints 6
4++n;
5cout << n << endl; // prints 7

However, there is one important difference: you can use n++ and ++n within a larger piece of code. This is where all the power of these operators comes in!

1int n = 5;
2cout << ++n << endl; // prints 6
3cout << n++ << endl; // prints ...6??

The above code highlights a subtlety of the two operators. ++n says to first increase n by one, then substitute its value into the code. Likewise, the n++ operator says to first substitute the value of n into the code, then increment its value.

Be very careful about using multiple increment/decrement operators in the same expression. One might be tempted to think that (n++)++ will increment n twice, but this does not even compile. The code (++n)++ does increment n twice (it increments n once, substitutes that value in, then increments again). However, the code ++(n++) does not compile.

Similarly, statements such as n++ + ++n, n + ++n, n * ++n, etc. produce undefined behaviour according to the C++ standard. That is, the code will compile, but you may get different results depending on your compiler and your computer.

The issue is one of the order of operations — C++ needs to substitute the values of n and ++n into the expression, but the order in which this substitution occurs both affects the resultant value and changes depending on the compiler. There are reasons for why these operators behave like this, but this is well beyond the scope of PIC 10A.

That being said, if one has two variables n and m, expressions such as ++n * ++m are perfectly okay. It’s when a single variable is being incremented or decremented and gets used more than once.

Example 2.

Predict the output of the following code:

 1#include <iostream>
 2
 3using namespace std;
 4
 5int main() {
 6    int n = 15;
 7    int m = 17;
 8
 9    cout << n++ + ++m << endl;
10    cout << ++n + m-- << endl;
11    cout << --m * n-- << endl;
12    cout << m << endl;
13    cout << n << endl;
14
15    return 0;
16}
Solution

My preferred approach to these kinds of problems is to keep track of the values of n and m after each line of code. In the table below, the columns for n and m represent their values after the line has been executed.

Line Number Output n m
8 N/A 15 17
9 (15 + 18 = ) 33 16 18
10 (17 + 18 = ) 35 17 17
11 (16 * 17 = ) 272 16 16
12 16 16 16
13 16 16 16

Thus, the output consists of the five numbers 33, 35, 272, 16, and 16, each on their own line.

Characters and the ASCII Table

I am aware that you have been exposed to strings of text in the recent lectures. Many of the practical applications of manipulating strings actually involve the manipulation of individual characters: consider programs that clean data by removing non-digital characters from phone numbers, by converting names to all caps, so on and so forth. Thus we will focus for now on becoming more familiar with characters and the ways in which we can manipulate them.

Characters, or char variables, are declared with single quotes:

1char ch = 'C'; 
2cout << ch << endl; 

This snippet of code prints the letter C to the screen. We can also declare char variables using numbers? Consider the following code:

1char ch = 67; 
2int n = 'C'; 
3cout << ch << " " << n << endl; 

What do you think the output will be? If you run this on your computer, you should get the output C 67. This illuminates two important facts:

  1. The character 'C' and the integer 67 are the same thing. More broadly, all characters are just numbers to the computer.
  2. C++ interprets the value 67 (or the character 'C') differently depending on what type of variable it’s stored in.

Naturally, we should ask how the computer knows which numbers correspond to which letter and vice-versa. About 3 billion years ago, the leading prokaryotic cells of the time congregated and designed the American Standard Code for Information Interchange, or ASCII. This is a table describing which characters correspond to which numbers, and all standard C++ programs adhere to this code. You may look up an ASCII table online through Google, and you will not need to memorise any portion of the ASCII table for this class.

We’ll call the number on the table the “code” for the corresponding textual “character”.

But what you do need to know are that parts of the ASCII table are structured in a way that’s compatible with certain mathematical operations. Specifically,

Now the fact that all the English letters and digits are in order means that we can do some basic arithmetic. Adding 5 to the character 'a' means to go 5 letters down the alphabet:

1char ch = 'a' + 5; 
2cout << ch << endl; // prints 'f'! 

Likewise, the difference in codes between 'a' and 'A', between 'd' and 'D', between 'h' and 'H', between 'y' and 'Y', are all exactly the same! This gives us a means to convert between cases.

1char difference = 'A' - 'a'; 
2char ch = 'h' + difference; 
3cout << ch << endl; // prints 'H'!! 

Finally, the fact that characters are contiguous on the ASCII table allows us to check if a character is a digit, is uppercase, or is lowercase in a relatively straightforward way. A char ch is lowercase, for instance, if 'a' <= ch and ch <= 'z'. Here, we are comparing the codes of the characters. This will become particularly helpful when we start working with strings in a few weeks.

Problem 3.

Predict the output of the following code.

 1#include <iostream> 
 2using namespace std; 
 3
 4int main() {
 5    char ch = 'M' + 'b' - 'D'; 
 6    int i = 'L' - 'O'; 
 7
 8    cout << --ch << " " << i++ << endl; 
 9    return 0; 
10}