One point that might be a bit puzzling in this program is why it's not necessary to add an << endl to the end of the lines that send data to cout before we ask the user for input. For example, in the sequence:
cout << "What is your first name? ";
cin >> name;
That wasn't the only subtle point that this problem raised. You'll be happy (or at least unsurprised) to hear that Susan and I had quite a discussion about this problem and its solution:
Susan:
When I was trying to put that period in the answer, I finally got it to work with double quotes. But then I thought that maybe it should have been surrounded by single quotes ' instead of double quotes. It worked with a double quote but since it was only one character it should have been a single quote, so I went back and changed it to a single quote and the compiler didn't like that at all. So I put it back to the double. So what is the deal?
Steve:
You should be able to use 'x' or "x" more or less interchangeably with <<, because it can handle both of those data types (char and C string literal, respectively). However, they are indeed different types. The first one specifies a literal char value, whereas the second specifies a C string literal value. A char value can only contain one character, but a C string literal can be as long as you want, from none to hundreds or thousands of characters.
Susan:
Here's the line that gave me the trouble:
cout << "That is very old, " << name << ". " << endl;
Remember I wanted to put that period in at the end in that last line? It runs like this but not with the single quotes around it. That I don't understand. This should have been an error. But I did something right by mistake <G>. Anyway, is there something special about the way a period is handled?
Steve:
I understand your problem now. No, it's not the period; it's the space after the period. Here are four possible versions of that line:
cout << "That is very old, " << name << ". " << endl;
cout << "That is very old, " << name << '. ' << endl;
cout << "That is very old, " << name << "." << endl;
cout << "That is very old, " << name << '.' << endl;
None of these is exactly the same as any of the others. However, 1, 3, and 4 will do what you expect, whereas 2 will produce weird looking output, with some bizarre number where the "." should be. Why is this? It's not because "." is handled specially, but because the space (" "), when inside quotes, either single or double, is a character like any other character. Thus, the expression '. ' in line 2 is a “multicharacter constant”, which has a value dependent on the compiler; with the compiler on the CD, you'll get a short value equal to (256 * the ASCII value of the period) + the ASCII value of the space. This comes out to 11808, as I calculate it. So the line you see on the screen may look like this:
That is very old, Joe11808
Now why do all of the other lines work? Well, 1 works because a C string literal can have any number of characters and be sent to cout correctly; 3 works for the same reason; and 4 works because '.' is a valid one-character constant, which is another type that << can handle.
I realize it's hard to think of the space as a character when it doesn't look like anything; in addition, you can add spaces freely between variables, expressions, and so forth, in the program text. However, once you're dealing with C string literals and literal character values, the space is just like any other character.
Susan:
So it is okay to use single characters in double quotes? If so, why bother with single quotes?
Steve:
Single quotes surround a literal of type char. This is a 1-byte value that can be thought of (and even used) as a very short number. Double quotes surround a literal value of type “C string literal”. This is a multibyte value terminated by a 0 byte, which cannot be used or treated as a number.
Susan:
I am not too clear on what exactly the difference is between the char and “C string literal”. I thought a char was like an alpha letter, and a string was just a bunch of letters.
Steve:
Right. The difference is that a C string literal is variable length, and a char isn't; this makes a lot of difference in how they can be manipulated.
Susan:
Am I right in thinking that a char could also be a small number that is not being used for calculations?
Steve:
Or that is used for (very small) calculations; for instance, if you add 1 to the value 'A', you get the value for 'B'. At least that's logical.
Susan:
What do you mean by “terminated by a 0 byte”? That sounds familiar; was that something from an earlier chapter which is now ancient history?
Steve:
Yes, we covered that some time ago. The way the program can tell that it's at the end of a C string literal (which is of variable length, remember) is that it gets to a byte with the value 0. This wouldn't be my preferred way to specify the size of a variable-length string, but it's too late to do anything about it; it's built into the compiler.
Susan:
When you say a C string literal, do you mean the C programming language in contrast to other languages?
Steve:
Yes.
Susan:
All right, then the 0 byte used to terminate a C string literal is the same thing as a null byte?
Steve:
Yes.
Susan:
Then you mean that each C string literal must end in a 0 so that the compiler will know when to stop processing the data for the string?
Steve:
Yes.
Susan:
Could you also just put 0? Hey, it doesn't hurt to ask. I don't see the problem with the word hello; it ends with an o and not a 0. But what if you do need to end the sentence with a 0?
Steve:
It's not the digit '0', which has the ASCII code 30h, but a byte with a 0 value. You can't type in a null byte directly, although you can create one with a special character sequence if you want to. However, there's no point in doing that usually, because all C string literals such as "hello" always have an invisible 0 byte added automatically by the compiler. If for some reason you need to explicitly create a null byte, you can write it as ' ', as in
which emphasizes that you really mean a null byte and not just a plain old 0 like this:
The difference between these two is solely for the benefit of the next programmer who looks at your code; they're exactly the same to the compiler.