The program in Listing 5.4 demonstrates how the for loop works hand-in-hand with arrays by providing a convenient means to access each array member in turn. Also formore.cpp uses const to create a symbolic representation (ArSize) for the array size. Then it uses ArSize wherever the array size comes into play, such as in the array definition and in the limits for the loops handling the array. Now, if you wish to extend the program to, say, 20 factorials, you just have to set ArSize to 20 in the program and recompile. By using a symbolic constant, you avoid having to change every occurrence of 16 to 20 individually.
Tip
It’s usually a good idea to define a const value to represent the number of elements in an array. You can use the const value in the array declaration and in all other references to the array size, such as in a for loop.
The limit expression i < ArSize reflects the fact that subscripts for an array with ArSize elements run from 0 to ArSize - 1, so the array index should stop one short of ArSize. You could use the test i <= ArSize - 1 instead, but it looks awkward in comparison.
Note that the program declares the const int variable ArSize outside the body of main(). As the end of Chapter 4, “Compound Types,” mentions, this makes ArSize external data. The two consequences of declaring ArSize in this fashion are that ArSize exists for the duration of the program and that all functions in the program file can use it. In this particular case, the program has just one function, so declaring ArSize externally has little practical effect. But multifunction programs often benefit from sharing external constants, so we’ll practice using them next.
Also this example reminds us that we can use std:: instead of a using directive to make selected standard names available.
Changing the Step Size
So far the loop examples in this chapter have increased or decreased the loop counter by one in each cycle. You can change that by changing the update expression. The program in Listing 5.5, for example, increases the loop counter by a user-selected step size. Rather than use i++ as the update expression, it uses the expression i = i + by, where by is the user-selected step size.
Listing 5.5. bigstep.cpp
// bigstep.cpp -- count as directed
#include
int main()
{
using std::cout; // a using declaration
using std::cin;
using std::endl;
cout << "Enter an integer: ";
int by;
cin >> by;
cout << "Counting by " << by << "s:\n";
for (int i = 0; i < 100; i = i + by)
cout << i << endl;
return 0;
}
Here is a sample run of the program in Listing 5.5:
Enter an integer: 17
Counting by 17s:
0
17
34
51
68
85
When i reaches the value 102, the loop quits. The main point here is that the update expression can be any valid expression. For example, if you want to square i and add 10 in each cycle, you can use i = i * i + 10.
Another point to note is that it often is a better idea to test for inequality than equality. For example, the test i == 100 would have failed in this case because i skips over the value 100.
Finally, this example illustrates the use of using declarations instead of a using directive.
Inside Strings with the for Loop
The for loop provides a direct way to access each character in a string in turn. For example, Listing 5.6 enables you to enter a string and then displays the string character-by-character, in reverse order. You could use either a string class object or an array of char in this example because both allow you to use array notation to access individual characters in a string; Listing 5.6 uses a string class object. The string class size() method yields the number of characters in the string; the loop uses that value in its initializing expression to set i to the index of the last character in the string, not counting the null character. To count backward, the program uses the decrement operator (--) to decrease the array subscript by one in each loop. Also Listing 5.6 uses the greater-than-or-equal-to relational operator (>=) to test whether the loop has reached the first element. We’ll summarize all the relational operators soon.
Listing 5.6. forstr1.cpp
// forstr1.cpp -- using for with a string
#include
#include
int main()
{
using namespace std;
cout << "Enter a word: ";
string word;
cin >> word;
// display letters in reverse order
for (int i = word.size() - 1; i >= 0; i--)
cout << word[i];
cout << "\nBye.\n";
return 0;
}
Here is a sample run of the program in Listing 5.6:
Enter a word: animal
lamina
Bye.
Yes, the program succeeds in printing animal backward; choosing animal as a test word more clearly illustrates the effect of this program than choosing, say, a palindrome such as rotator, redder, or stats.
The Increment (++) and Decrement (--) Operators