ASCII
-
Recall that everything inside the computer is represented in 0s and 1s (binary). That means that everything, even
char
s andstring
s are represented as integers under the hood. -
ASCII is an encoding system which represents every character with a given number. For example, an uppercase
A
is represented by the number65
and an uppercaseZ
is represented by the number90
. -
Here’s a glimpse of the ASCII table that illustrates the correspondence between characters and numbers that represent them:
-
You should try to memorize all the ASCII values. However, you should know the following:
-
There is an integer corresponding to each character in the ASCII table.
-
Uppercase letters are next to each other in the ASCII table.
-
Lowercase letters are next to each other in the ASCII table.
-
A
has a value of65
anda
has a value of97
, so uppercase letters come before lowercase letters. -
The character
0
does not have an ASCII value of0
. In other words, the character0
is not represented with the number0
.
-
-
Let’s now write a program that prints all the English letters in the alphabet (first, uppercase A–Z, and then lowercase a–z), along with their ASCII values. The program should print something like this:
A: 65 B: 66 C: 67 ... a: 97 b: 98 c: 99 ...
-
Here’s one way to do it:
ascii-0.cppint main() { // mapping for uppercase letters for (int i = 65; i < 65 + 26; i++) (1) { cout << (char) i << ": " << i << endl; (2) } cout << endl; // mapping for lowercase letters for (int i = 97; i < 97 + 26; i++) (3) { cout << (char) i << ": " << i << endl; } }
1 We start the first loop at 65 (the ASCII value of A
) and execute the loop 26 times (once per letter), so long asi
is less than 98. (97 is the ASCII value ofZ
).2 Inside the body of the first loop, we print the ASCII value after printing the corresponding character that we get by casting the integer with the ASCII value to a char
.3 Similarly, we have a for loop for lowercase letters that starts at 97 (the ASCII value of a
) and executes 26 times.However,
ascii-0.cpp
has a lot of magic numbers (65, 26, 97). And to implement it correctly, you’d have to remember, for example, thata
corresponds to 97. -
It turns out that we can also cast from
char
s toint
s, so let’s write a second version of that program, where we avoid magic numbers:ascii-1.cpp#include <iostream> using namespace std; int main() { // mapping for uppercase letters for (char c = 'A'; c <= 'Z'; c++) (1) { cout << c << ": " << (int) c << endl; (2) } cout << endl; // mapping for lowercase letters for (char c = 'a'; c <= 'z'; c++) (3) { cout << c << ": " << (int) c << endl; } }
1 We iterate over char
s, starting atA
up untilZ
. We can also incrementc
on each iteration, and we’ll get the next character in the ASCII table.2 Each time, we print the character, and then its ASCII value that we get by casting the char
to anint
.3 Similarly we iterate over char
s froma
toz
.Notice how now in
ascii-1.cpp
, we don’t have to now the exact values ofA
,Z
,a
orz
-
Being able to represent characters with numbers gives us the ability to manipulate them, which opens lots of possibilities (e.g. capitalizing strings). More on this in a week or so!
Battleship
-
Write a program that prints this Battleship board using loops. Take care to ensure that all spaces match this example:
1 2 3 4 5 6 7 8 9 10 A o o o o o o o o o o B o o o o o o o o o o C o o o o o o o o o o D o o o o o o o o o o E o o o o o o o o o o F o o o o o o o o o o G o o o o o o o o o o H o o o o o o o o o o I o o o o o o o o o o J o o o o o o o o o o
-
Since it’s a lot easier to print top to bottom, we’ll print the board row by row.
So first, let’s print the top row of numbers. All we need is a single for loop that prints numbers 1 through 10 separated by spaces:
for (int i = 1; i <= 10; i++) { cout << i << " "; }
Now we need to print ten rows of holes, with letters in the leftmost column. Let’s start by just printing a single row of 10 holes:
for (int i = 0; i < 10; i++) { cout << "o "; }
To print ten such rows, we’ll need to put the above loop inside another loop. And we’ll need to go to a new line after the inner loop executes to separate each row.
for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { cout << "o "; } cout << endl; }
Finally, we need to print the corresponding letter in each row. We can do that by printing the character that we get after adding
i
(a number from 0 to 10, corresponding to the row) to the characterA
when we print each row.// print rows of holes, with letters in leftmost column for (int i = 0; i < 10; i++) { cout << (char) ('A' + i) << " "; // print 10 holes cout << endl; }
Also, let’s define a constant to avoid magic numbers
const int BOARD_SIZE = 10;
And replace
10
withBOARD_SIZE
. -
Here’s the full solution:
battleship.cpp1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29#include <iostream> using namespace std; int main() { const int BOARD_SIZE = 10; // print top row of numbers cout << " "; for (int i = 1; i <= BOARD_SIZE; i++) { cout << i << " "; } cout << endl; // print rows of holes, with letters in leftmost column for (int i = 0; i < BOARD_SIZE; i++) { // letter cout << (char) ('A' + i) << " "; // holes for (int j = 0; j < BOARD_SIZE; j++) { cout << "o "; } cout << endl; } }
Strings
-
Think of
string
s as of sequences of characters. For example, the string"hello"
is a sequence of five characters:Notice how each character is associated with an index. Indices always start at 0. The last index is always one less than the length of the string.
-
You can get the length of the string by calling the
length
function on that string. For example,string name = "Grace"; cout << name.length() << endl;
Prints
5
-
You can access individual characters of a string by using bracket (subscript) notation. This code accesses the first character of
name
:string name = "Grace"; cout << name[0] << endl;
And prints
G
-
Be careful not to access the string an an invalid index! For example, the valid indices for the string
"hello"
are only 0, 1, 2, 3 and 4. So doing something like this is bad and might cause your program to crash:string name = "Grace"; cout << name[5] << endl;
-
Write a program that asks the user for a string and than prints that string’s characters, one per line. The program should behave per the output below, wherein red underlined text represents some user’s input:
Give me a string: Lumos L u m o s
spell.cpp#include <iostream> using namespace std; int main() { // get a string from the user cout << "Give me a string: "; string s; getline(cin, s); (1) // print characters in s, one per line for (int i = 0; i < s.length(); i++) (2) { cout << s[i] << endl; (3) } }
1 We use getline
to get the entire line of the user’s input, instead of just the first word.2 To go through each character one by one, we need i
that represents the index of each character, starting at0
and ending at 1 less than the length of the string.3 For each index i
, we print the corresponding character ins
, followed by a newline.
Pass by Reference
-
Pass by value copies the value from a variable or a literal into a parameter. The original variable’s value is not changed.
-
Pass by reference gives the parameter a reference to the variable that was passed as an argument. The original variable’s value may be changed.
Arrays
-
Arrays are data structures that allow us to store data of the same type in contiguous memory locations.
-
As an anology, think of the mailboxes in your dorm. An array is simply a block of contiguous space in memory (the mail center) that has been partitioned into identically-sized chunks (mailboxes). Each chunk can store a certain amount of data (mail) that can be accessed by an index number (mailbox number).
-
Note that array indices in C always start at 0!
-
Declare an array by specifying the data type it will store, its name, as well as its size. Here, we declare an array of 3
int
s callednumbers
and load it with values.int numbers[3]; numbers[0] = 1; numbers[1] = 2; numbers[2] = 3;
Alternatively, you can declare and initialize the array in a single step (in which case stating the size is optional).
int numbers[] = {1, 2, 3};
-
Because arrays store data contiguously in memory, array size is fixed after array declaration. You are effectively asking the operating system to reserve the appropriate number of contiguous chunks of memory for the array’s elements. There’s no guarantee that more memory adjacent to your array will be available for use later, so arrays cannot easily grow.
-
Remember that the first valid index of an array is 0 and the last valid index its size - 1. Be careful not to access invalid indices of the array (< 0 or ≥ size).
In other words, you should not do the following:
int numbers[3] = 4;
The above code would not cause a compile error, but you risk to overwrite another variable’s value. In some cases, the program will crash.