C++ Statements
A C++ program is a collection of functions, and each function is a collection of statements. C++ has several kinds of statements, so let’s look at some of the possibilities. Listing 2.2 provides two new kinds of statements. First, a declaration statement creates a variable. Second, an assignment statement provides a value for that variable. Also the program shows a new capability for cout.
Listing 2.2 carrots.cpp
// carrots.cpp -- food processing program // uses and displays a variable #include <iostream> int main() { using namespace std; int carrots; // declare an integer variable carrots = 25; // assign a value to the variable cout << "I have "; cout << carrots; // display the value of the variable cout << " carrots."; cout << endl; carrots = carrots - 1; // modify the variable cout << "Crunch, crunch. Now I have " << carrots << " carrots." << endl; return 0; }
A blank line separates the declaration from the rest of the program. This practice is the usual C convention, but it’s somewhat less common in C++. Here is the program output for Listing 2.2:
I have 25 carrots. Crunch, crunch. Now I have 24 carrots.
The next few pages examine this program.
Declaration Statements and Variables
Computers are precise, orderly machines. To store an item of information in a computer, you must identify both the storage location and how much memory storage space the information requires. One relatively painless way to do this in C++ is to use a declaration statement to indicate the type of storage and to provide a label for the location. For example, the program in Listing 2.2 has this declaration statement (note the semicolon):
int carrots;
This statement provides two kinds of information: the type of memory storage needed and a label to attach to that storage. In particular, the statement declares that the program requires enough storage to hold an integer, for which C++ uses the label int. The compiler takes care of the details of allocating and labeling memory for that task. C++ can handle several kinds, or types, of data, and the int is the most basic data type. It corresponds to an integer, a number with no fractional part. The C++ int type can be positive or negative, but the size range depends on the implementation. Chapter 3 provides the details on int and the other basic types.
Naming the storage is the second task achieved. In this case, the declaration statement declares that henceforth the program will use the name carrots to identify the value stored at that location. carrots is called a variable because you can change its value. In C++ you must declare all variables. If you were to omit the declaration in carrots.cpp, the compiler would report an error when the program attempts to use carrots further on. (In fact, you might want to try omitting the declaration just to see how your compiler responds. Then if you see that response in the future, you’ll know to check for omitted declarations.)
In general, then, a declaration indicates the type of data to be stored and the name the program will use for the data that’s stored there. In this particular case, the program creates a variable called carrots in which it can store an integer (see Figure 2.4).
Figure 2.4 A variable declaration.
The declaration statement in the program is called a defining declaration statement, or definition, for short. This means that its presence causes the compiler to allocate memory space for the variable. In more complex situations, you can also have reference declarations. These tell the computer to use a variable that has already been defined elsewhere. In general, a declaration need not be a definition, but in this example it is.
If you’re familiar with C or Pascal, you’re already familiar with variable declarations. You also might have a modest surprise in store for you. In C and Pascal, all variable declarations normally come at the very beginning of a function or procedure. But C++ has no such restriction. Indeed, the usual C++ style is to declare a variable just before it is first used. That way, you don’t have to rummage back through a program to see what the type is. You’ll see an example of this later in this chapter. This style does have the disadvantage of not gathering all your variable names in one place; thus, you can’t tell at a glance what variables a function uses. (Incidentally, C99 now makes the rules for C declarations much the same as for C++.)
Assignment Statements
An assignment statement assigns a value to a storage location. For example, the following statement assigns the integer 25 to the location represented by the variable carrots:
carrots = 25;
The = symbol is called the assignment operator. One unusual feature of C++ (and C) is that you can use the assignment operator serially. For example, the following is valid code:
int steinway; int baldwin; int yamaha; yamaha = baldwin = steinway = 88;
The assignment works from right to left. First, 88 is assigned to steinway; then the value of steinway, which is now 88, is assigned to baldwin; then baldwin’s value of 88 is assigned to yamaha. (C++ follows C’s penchant for allowing weird-appearing code.)
The second assignment statement in Listing 2.2 demonstrates that you can change the value of a variable:
carrots = carrots - 1; // modify the variable
The expression to the right of the assignment operator (carrots – 1) is an example of an arithmetic expression. The computer will subtract 1 from 25, the value of carrots, obtaining 24. The assignment operator then stores this new value in the carrots location.
A New Trick for cout
Up until now, the examples in this chapter have given cout strings to print. Listing 2.2 also gives cout a variable whose value is an integer:
cout << carrots;
The program doesn’t print the word carrots; instead, it prints the integer value stored in carrots, which is 25. Actually, this is two tricks in one. First, cout replaces carrots with its current numeric value of 25. Second, it translates the value to the proper output characters.
As you can see, cout works with both strings and integers. This might not seem particularly remarkable to you, but keep in mind that the integer 25 is something quite different from the string "25". The string holds the characters with which you write the number (that is, a 2 character and a 5 character). The program internally stores the numeric codes for the 2 character and the 5 character. To print the string, cout simply prints each character in the string. But the integer 25 is stored as a numeric value. Rather than store each digit separately, the computer stores 25 as a binary number. (Appendix A, “Number Bases,” discusses this representation.) The main point here is that cout must translate a number in integer form into character form before it can print it. Furthermore, cout is smart enough to recognize that carrots is an integer that requires conversion.
Perhaps the contrast with old C will indicate how clever cout is. To print the string "25" and the integer 25 in C, you could use C’s multipurpose output function printf():
printf("Printing a string: %s\n", "25"); printf("Printing an integer: %d\n", 25);
Without going into the intricacies of printf(), note that you must use special codes (%s and %d) to indicate whether you are going to print a string or an integer. And if you tell printf() to print a string but give it an integer by mistake, printf() is too unsophisticated to notice your mistake. It just goes ahead and displays garbage.
The intelligent way in which cout behaves stems from C++’s object-oriented features. In essence, the C++ insertion operator (<<) adjusts its behavior to fit the type of data that follows it. This is an example of operator overloading. In later chapters, when you take up function overloading and operator overloading, you’ll learn how to implement such smart designs yourself.