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:
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!
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:
This snippet of code prints the letter C to the screen.
We can also declare char variables using numbers?
Consider the following code:
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:
- The character
'C'and the integer67are the same thing. More broadly, all characters are just numbers to the computer. - 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,
- The characters
'0'through'9'occupy 10 contiguous codes. They are in order, starting with'0'. - The characters
'a'through'z'occupy 26 contiguous codes. They are in order, starting with'a'. - The characters
'A'through'Z'occupy 26 contiguous codes. They are in order, starting with'A'. Note, by the way, that the character'0'and the number0are distinct. In fact,'0'corresponds to the numerical code48.
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:
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.
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.