Examples Using Arrays

This section presents many examples that demonstrate how to declare arrays, how to initialize arrays and how to perform many common array manipulations.

Declaring an Array and Using a Loop to Initialize the Array's Elements

The program in Fig. 7.3 declares 10-element integer array n (line 12). Lines 1516 use a for statement to initialize the array elements to zeros. The first output statement (line 18) displays the column headings for the columns printed in the subsequent for statement (lines 2122), which prints the array in tabular format. Remember that setw specifies the field width in which only the next value is to be output.

Figure 7.3. Initializing an array's elements to zeros and printing the array.

(This item is displayed on page 331 in the print version)

1 // Fig. 7.3: fig07_03.cpp 2 // Initializing an array. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include 8 using std::setw; 9 10 int main() 11 { 12 int n[ 10 ]; // n is an array of 10 integers 13 14 // initialize elements of array n to 0 15 for ( int i = 0; i < 10; i++ ) 16 n[ i ] = 0; // set element at location i to 0 17 18 cout << "Element" << setw( 13 ) << "Value" << endl; 19 20 // output each array element's value 21 for ( int j = 0; j < 10; j++ ) 22 cout << setw( 7 ) << j << setw( 13 ) << n[ j ] << endl; 23 24 return 0; // indicates successful termination 25 } // end main  

Element Value 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0  

Initializing an Array in a Declaration with an Initializer List

The elements of an array also can be initialized in the array declaration by following the array name with an equals sign and a comma-separated list (enclosed in braces) of initializers. The program in Fig. 7.4 uses an initializer list to initialize an integer array with 10 values (line 13) and prints the array in tabular format (lines 1519).

Figure 7.4. Initializing the elements of an array in its declaration.

(This item is displayed on pages 331 - 332 in the print version)

1 // Fig. 7.4: fig07_04.cpp 2 // Initializing an array in a declaration. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include 8 using std::setw; 9 10 int main() 11 { 12 // use initializer list to initialize array n 13 int n[ 10 ] = { 32, 27, 64, 18, 95, 14, 90, 70, 60, 37 }; 14 15 cout << "Element" << setw( 13 ) << "Value" << endl; 16 17 // output each array element's value 18 for ( int i = 0; i < 10; i++ ) 19 cout << setw( 7 ) << i << setw( 13 ) << n[ i ] << endl; 20 21 return 0; // indicates successful termination 22 } // end main  

Element Value 0 32 1 27 2 64 3 18 4 95 5 14 6 90 7 70 8 60 9 37  

If there are fewer initializers than elements in the array, the remaining array elements are initialized to zero. For example, the elements of array n in Fig. 7.3 could have been initialized to zero with the declaration

int n[ 10 ] = { 0 }; // initialize elements of array n to 0

The declaration explicitly initializes the first element to zero and implicitly initializes the remaining nine elements to zero, because there are fewer initializers than elements in the array. Automatic arrays are not implicitly initialized to zero although static arrays are. The programmer must at least initialize the first element to zero with an initializer list for the remaining elements to be implicitly set to zero. The initialization method shown in Fig. 7.3 can be performed repeatedly as a program executes.


If the array size is omitted from a declaration with an initializer list, the compiler determines the number of elements in the array by counting the number of elements in the initializer list. For example,

int n[] = { 1, 2, 3, 4, 5 };

creates a five-element array.

If the array size and an initializer list are specified in an array declaration, the number of initializers must be less than or equal to the array size. The array declaration

int n[ 5 ] = { 32, 27, 64, 18, 95, 14 };

causes a compilation error, because there are six initializers and only five array elements.

Common Programming Error 7.2

Providing more initializers in an array initializer list than there are elements in the array is a compilation error.

Common Programming Error 7.3

Forgetting to initialize the elements of an array whose elements should be initialized is a logic error.

 

Specifying an Array's Size with a Constant Variable and Setting Array Elements with Calculations

Figure 7.5 sets the elements of a 10-element array s to the even integers 2, 4, 6, ..., 20 (lines 1718) and prints the array in tabular format (lines 2024). These numbers are generated (line 18) by multiplying each successive value of the loop counter by 2 and adding 2.


Figure 7.5. Generating values to be placed into elements of an array.

1 // Fig. 7.5: fig07_05.cpp 2 // Set array s to the even integers from 2 to 20. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include 8 using std::setw; 9 10 int main() 11 { 12 // constant variable can be used to specify array size 13 const int arraySize = 10; 14 15 int s[ arraySize ]; // array s has 10 elements 16 17 for ( int i = 0; i < arraySize; i++ ) // set the values 18 s[ i ] = 2 + 2 * i; 19 20 cout << "Element" << setw( 13 ) << "Value" << endl; 21 22 // output contents of array s in tabular format 23 for ( int j = 0; j < arraySize; j++ ) 24 cout << setw( 7 ) << j << setw( 13 ) << s[ j ] << endl; 25 26 return 0; // indicates successful termination 27 } // end main  

Element Value 0 2 1 4 2 6 3 8 4 10 5 12 6 14 7 16 8 18 9 20  

Line 13 uses the const qualifier to declare a so-called constant variable arraySize with the value 10. Constant variables must be initialized with a constant expression when they are declared and cannot be modified thereafter (as shown in Fig. 7.6 and Fig. 7.7). Constant variables are also called named constants or read-only variables.

Figure 7.6. Initializing and using a constant variable.

(This item is displayed on page 334 in the print version)

1 // Fig. 7.6: fig07_06.cpp 2 // Using a properly initialized constant variable. 3 #include 4 using std::cout; 5 using std::endl; 6 7 int main() 8 { 9 const int x = 7; // initialized constant variable 10 11 cout << "The value of constant variable x is: " << x << endl; 12 13 return 0; // indicates successful termination 14 } // end main  

The value of constant variable x is: 7  

Figure 7.7. const variables must be initialized.

(This item is displayed on page 334 in the print version)

1 // Fig. 7.7: fig07_07.cpp 2 // A const variable must be initialized. 3 4 int main() 5 { 6 const int x; // Error: x must be initialized 7 8 x = 7; // Error: cannot modify a const variable 9 10 return 0; // indicates successful termination 11 } // end main  

Borland C++ command-line compiler error message:

Error E2304 fig07_07.cpp 6: Constant variable 'x' must be initialized in function main() Error E2024 fig07_07.cpp 8: Cannot modify a const object in function main()  

 

Microsoft Visual C++ .NET compiler error message:

C:cpphtp5_examplesch07fig07_07.cpp(6) : error C2734: 'x' : const object must be initialized if not extern C:cpphtp5_examplesch07fig07_07.cpp(8) : error C2166: l-value specifies const object  

 

GNU C++ compiler error message:

fig07_07.cpp:6: error: uninitialized const `x' fig07_07.cpp:8: error: assignment of read-only variable `x'  

Common Programming Error 7.4

Not assigning a value to a constant variable when it is declared is a compilation error.

Common Programming Error 7.5

Assigning a value to a constant variable in an executable statement is a compilation error.


Constant variables can be placed anywhere a constant expression is expected. In Fig. 7.5, constant variable arraySize specifies the size of array s in line 15.

Common Programming Error 7.6

Only constants can be used to declare the size of automatic and static arrays. Not using a constant for this purpose is a compilation error.

Using constant variables to specify array sizes makes programs more scalable. In Fig. 7.5, the first for statement could fill a 1000-element array by simply changing the value of arraySize in its declaration from 10 to 1000. If the constant variable arraySize had not been used, we would have to change lines 15, 17 and 23 of the program to scale the program to handle 1000 array elements. As programs get larger, this technique becomes more useful for writing clearer, easier-to-modify programs.

Software Engineering Observation 7.1

Defining the size of each array as a constant variable instead of a literal constant can make programs more scalable.

Good Programming Practice 7.2

Defining the size of an array as a constant variable instead of a literal constant makes programs clearer. This technique eliminates so-called magic numbers. For example, repeatedly mentioning the size 10 in array-processing code for a 10-element array gives the number 10 an artificial significance and can unfortunately confuse the reader when the program includes other 10s that have nothing to do with the array size.

 

Summing the Elements of an Array

Often, the elements of an array represent a series of values to be used in a calculation. For example, if the elements of an array represent exam grades, a professor may wish to total the elements of the array and use that sum to calculate the class average for the exam. The examples using class GradeBook later in the chapter, namely Figs. 7.167.17 and Figs. 7.237.24, use this technique.

The program in Fig. 7.8 sums the values contained in the 10-element integer array a. The program declares, creates and initializes the array at line 10. The for statement (lines 1415) performs the calculations. The values being supplied as initializers for array a also could be read into the program from the user at the keyboard, or from a file on disk (see Chapter 17, File Processing). For example, the for statement

for ( int j = 0; j < arraySize; j++ ) cin >> a[ j ];

reads one value at a time from the keyboard and stores the value in element a[ j ].

Figure 7.8. Computing the sum of the elements of an array.

(This item is displayed on pages 335 - 336 in the print version)

1 // Fig. 7.8: fig07_08.cpp 2 // Compute the sum of the elements of the array. 3 #include 4 using std::cout; 5 using std::endl; 6 7 int main() 8 { 9 const int arraySize = 10; // constant variable indicating size of array 10 int a[ arraySize ] = { 87, 68, 94, 100, 83, 78, 85, 91, 76, 87 }; 11 int total = 0; 12 13 // sum contents of array a 14 for ( int i = 0; i < arraySize; i++ ) 15 total += a[ i ]; 16 17 cout << "Total of array elements: " << total << endl; 18 19 return 0; // indicates successful termination 20 } // end main  

Total of array elements: 849  


Using Bar Charts to Display Array Data Graphically

Many programs present data to users in a graphical manner. For example, numeric values are often displayed as bars in a bar chart. In such a chart, longer bars represent proportionally larger numeric values. One simple way to display numeric data graphically is with a bar chart that shows each numeric value as a bar of asterisks (*).

Professors often like to examine the distribution of grades on an exam. A professor might graph the number of grades in each of several categories to visualize the grade distribution. Suppose the grades were 87, 68, 94, 100, 83, 78, 85, 91, 76 and 87. Note that there was one grade of 100, two grades in the 90s, four grades in the 80s, two grades in the 70s, one grade in the 60s and no grades below 60. Our next program (Fig. 7.9) stores this grade distribution data in an array of 11 elements, each corresponding to a category of grades. For example, n[ 0 ] indicates the number of grades in the range 09, n[ 7 ] indicates the number of grades in the range 7079 and n[ 10 ] indicates the number of grades of 100. The two versions of class GradeBook later in the chapter (Figs. 7.167.17 and Figs. 7.237.24) contain code that calculates these grade frequencies based on a set of grades. For now, we manually create the array by looking at the set of grades.

Figure 7.9. Bar chart printing program.

(This item is displayed on pages 336 - 337 in the print version)

1 // Fig. 7.9: fig07_09.cpp 2 // Bar chart printing program. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include 8 using std::setw; 9 10 int main() 11 { 12 const int arraySize = 11; 13 int n[ arraySize ] = { 0, 0, 0, 0, 0, 0, 1, 2, 4, 2, 1 }; 14 15 cout << "Grade distribution:" << endl; 16 17 // for each element of array n, output a bar of the chart 18 for ( int i = 0; i < arraySize; i++ ) 19 { 20 // output bar labels ("0-9:", ..., "90-99:", "100:" ) 21 if ( i == 0 ) 22 cout << " 0-9: "; 23 else if ( i == 10 ) 24 cout << " 100: "; 25 else 26 cout << i * 10 << "-" << ( i * 10 ) + 9 << ": "; 27 28 // print bar of asterisks 29 for ( int stars = 0; stars < n[ i ]; stars++ ) 30 cout << '*'; 31 32 cout << endl; // start a new line of output 33 } // end outer for 34 35 return 0; // indicates successful termination 36 } // end main  

Grade distribution: 0-9: 10-19: 20-29: 30-39: 40-49: 50-59: 60-69: * 70-79: ** 80-89: **** 90-99: ** 100: *  


The program reads the numbers from the array and graphs the information as a bar chart. The program displays each grade range followed by a bar of asterisks indicating the number of grades in that range. To label each bar, lines 2126 output a grade range (e.g., "70-79: ") based on the current value of counter variable i. The nested for statement (lines 2930) outputs the bars. Note the loop-continuation condition at line 29 (stars < n[ i ]). Each time the program reaches the inner for, the loop counts from 0 up to n[ i ], thus using a value in array n to determine the number of asterisks to display. In this example, n[ 0 ]n[ 5 ] contain zeros because no students received a grade below 60. Thus, the program displays no asterisks next to the first six grade ranges.

Common Programming Error 7.7

Although it is possible to use the same control variable in a for statement and a second for statement nested inside, this is confusing and can lead to logic errors.


Using the Elements of an Array as Counters

Sometimes, programs use counter variables to summarize data, such as the results of a survey. In Fig. 6.9, we used separate counters in our die-rolling program to track the number of occurrences of each side of a die as the program rolled the die 6,000,000 times. An array version of this program is shown in Fig. 7.10.

Figure 7.10. Die-rolling program using an array instead of switch.

1 // Fig. 7.10: fig07_10.cpp 2 // Roll a six-sided die 6,000,000 times. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include 8 using std::setw; 9 10 #include 11 using std::rand; 12 using std::srand; 13 14 #include 15 using std::time; 16 17 int main() 18 { 19 const int arraySize = 7; // ignore element zero 20 int frequency[ arraySize ] = { 0 }; 21 22 srand( time( 0 ) ); // seed random number generator 23 24 // roll die 6,000,000 times; use die value as frequency index 25 for ( int roll = 1; roll <= 6000000; roll++ ) 26 frequency[ 1 + rand() % 6 ]++; 27 28 cout << "Face" << setw( 13 ) << "Frequency" << endl; 29 30 // output each array element's value 31 for ( int face = 1; face < arraySize; face++ ) 32 cout << setw( 4 ) << face << setw( 13 ) << frequency[ face ] 33 << endl; 34 35 return 0; // indicates successful termination 36 } // end main  

Face Frequency 1 1000167 2 1000149 3 1000152 4 998748 5 999626 6 1001158  


Figure 7.10 uses the array frequency (line 20) to count the occurrences of each side of the die. The single statement in line 26 of this program replaces the switch statement in lines 3052 of Fig. 6.9. Line 26 uses a random value to determine which frequency element to increment during each iteration of the loop. The calculation in line 26 produces a random subscript from 1 to 6, so array frequency must be large enough to store six counters. However, we use a seven-element array in which we ignore frequency[ 0 ]it is more logical to have the die face value 1 increment frequency[ 1 ] than frequency[ 0 ]. Thus, each face value is used as a subscript for array frequency. We also replace lines 5661 of Fig. 6.9 by looping through array frequency to output the results (lines 3133).

Using Arrays to Summarize Survey Results

Our next example (Fig. 7.11) uses arrays to summarize the results of data collected in a survey. Consider the following problem statement:

Forty students were asked to rate the quality of the food in the student cafeteria on a scale of 1 to 10 (1 meaning awful and 10 meaning excellent). Place the 40 responses in an integer array and summarize the results of the poll.

Figure 7.11. Poll analysis program.

(This item is displayed on pages 339 - 340 in the print version)

1 // Fig. 7.11: fig07_11.cpp 2 // Student poll program. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include 8 using std::setw; 9 10 int main() 11 { 12 // define array sizes 13 const int responseSize = 40; // size of array responses 14 const int frequencySize = 11; // size of array frequency 15 16 // place survey responses in array responses 17 const int responses[ responseSize ] = { 1, 2, 6, 4, 8, 5, 9, 7, 8, 18 10, 1, 6, 3, 8, 6, 10, 3, 8, 2, 7, 6, 5, 7, 6, 8, 6, 7, 19 5, 6, 6, 5, 6, 7, 5, 6, 4, 8, 6, 8, 10 }; 20 21 // initialize frequency counters to 0 22 int frequency[ frequencySize ] = { 0 }; 23 24 // for each answer, select responses element and use that value 25 // as frequency subscript to determine element to increment 26 for ( int answer = 0; answer < responseSize; answer++ ) 27 frequency[ responses[ answer ] ]++; 28 29 cout << "Rating" << setw( 17 ) << "Frequency" << endl; 30 31 // output each array element's value 32 for ( int rating = 1; rating < frequencySize; rating++ ) 33 cout << setw( 6 ) << rating << setw( 17 ) << frequency[ rating ] 34 << endl; 35 36 return 0; // indicates successful termination 37 } // end main  

Rating Frequency 1 2 2 2 3 2 4 2 5 5 6 11 7 5 8 7 9 1 10 3  

This is a typical array-processing application. We wish to summarize the number of responses of each type (i.e., 1 through 10). The array responses (lines 1719) is a 40-element integer array of the students' responses to the survey. Note that array responses is declared const, as its values do not (and should not) change. We use an 11-element array frequency (line 22) to count the number of occurrences of each response. Each element of the array is used as a counter for one of the survey responses and is initialized to zero. As in Fig. 7.10, we ignore frequency[ 0 ].


Software Engineering Observation 7.2

The const qualifier should be used to enforce the principle of least privilege. Using the principle of least privilege to properly design software can greatly reduce debugging time and improper side effects and can make a program easier to modify and maintain.

Good Programming Practice 7.3

Strive for program clarity. It is sometimes worthwhile to trade off the most efficient use of memory or processor time in favor of writing clearer programs.

Performance Tip 7.1

Sometimes performance considerations far outweigh clarity considerations.

The first for statement (lines 2627) takes the responses one at a time from the array responses and increments one of the 10 counters in the frequency array (frequency[ 1 ] to frequency[ 10 ]). The key statement in the loop is line 27, which increments the appropriate frequency counter, depending on the value of responses[ answer ].

Let's consider several iterations of the for loop. When control variable answer is 0, the value of responses[ answer ] is the value of responses[ 0 ] (i.e., 1 in line 17), so the program interprets frequency[ responses[ answer ] ]++ as

frequency[ 1 ]++


which increments the value in array element 1. To evaluate the expression, start with the value in the innermost set of square brackets (answer). Once you know answer's value (which is the value of the loop control variable in line 26), plug it into the expression and evaluate the next outer set of square brackets (i.e., responses[ answer ], which is a value selected from the responses array in lines 1719). Then use the resulting value as the subscript for the frequency array to specify which counter to increment.

When answer is 1, responses[ answer ] is the value of responses[ 1 ], which is 2, so the program interprets frequency[ responses[ answer ] ]++ as

frequency[ 2 ]++

which increments array element 2.

When answer is 2, responses[ answer ] is the value of responses[ 2 ], which is 6, so the program interprets frequency[ responses[ answer ] ]++ as

frequency[ 6 ]++

which increments array element 6, and so on. Regardless of the number of responses processed in the survey, the program requires only an 11-element array (ignoring element zero) to summarize the results, because all the response values are between 1 and 10 and the subscript values for an 11-element array are 0 through 10.

If the data in the responses array had contained an invalid value, such as 13, the program would have attempted to add 1 to frequency[ 13 ], which is outside the bounds of the array. C++ has no array bounds checking to prevent the computer from referring to an element that does not exist. Thus, an executing program can "walk off" either end of an array without warning. The programmer should ensure that all array references remain within the bounds of the array.

Common Programming Error 7.8

Referring to an element outside the array bounds is an execution-time logic error. It is not a syntax error.

Error-Prevention Tip 7.1

When looping through an array, the array subscript should never go below 0 and should always be less than the total number of elements in the array (one less than the size of the array). Make sure that the loop-termination condition prevents accessing elements outside this range.

Portability Tip 7.1

The (normally serious) effects of referencing elements outside the array bounds are system dependent. Often this results in changes to the value of an unrelated variable or a fatal error that terminates program execution.

C++ is an extensible language. Section 7.11 presents C++ Standard Library class template vector, which enables programmers to perform many operations that are not available for C++'s built-in arrays. For example, we will be able to compare vectors directly and assign one vector to another. In Chapter 11, we extend C++ further by implementing an array as a user-defined class of our own. This new array definition will enable us to input and output entire arrays with cin and cout, initialize arrays when they are created, prevent access to out-of-range array elements and change the range of subscripts (and even their subscript type) so that the first element of an array is not required to be element 0. We will even be able to use noninteger subscripts.


Error-Prevention Tip 7.2

In Chapter 11, we will see how to develop a class representing a "smart array," which checks that all subscript references are in bounds at runtime. Using such smart data types helps eliminate bugs.

 

Using Character Arrays to Store and Manipulate Strings

To this point, we have discussed only integer arrays. However, arrays may be of any type. We now introduce storing character strings in character arrays. Recall that, starting in Chapter 3, we have been using string objects to store character strings, such as the course name in our GradeBook class. A string such as "hello" is actually an array of characters. While string objects are convenient to use and reduce the potential for errors, character arrays that represent strings have several unique features, which we discuss in this section. As you continue your study of C++, you may encounter C++ capabilities that require you to use character arrays in preference to string objects. You may also be asked to update existing code using character arrays.

A character array can be initialized using a string literal. For example, the declaration

char string1[] = "first";

initializes the elements of array string1 to the individual characters in the string literal "first". The size of array string1 in the preceding declaration is determined by the compiler based on the length of the string. It is important to note that the string "first" contains five characters plus a special string-termination character called the null character. Thus, array string1 actually contains six elements. The character constant representation of the null character is '' (backslash followed by zero). All strings represented by character arrays end with this character. A character array representing a string should always be declared large enough to hold the number of characters in the string and the terminating null character.

Character arrays also can be initialized with individual character constants in an initializer list. The preceding declaration is equivalent to the more tedious form

char string1[] = { 'f', 'i', 'r', 's', 't', '' };

Note the use of single quotes to delineate each character constant. Also, note that we explicitly provided the terminating null character as the last initializer value. Without it, this array would simply represent an array of characters, not a string. As we discuss in Chapter 8, not providing a terminating null character for a string can cause logic errors.

Because a string is an array of characters, we can access individual characters in a string directly with array subscript notation. For example, string1[ 0 ] is the character 'f', string1[ 3 ] is the character 's' and string1[ 5 ] is the null character.

We also can input a string directly into a character array from the keyboard using cin and >>. For example, the declaration

char string2[ 20 ];

creates a character array capable of storing a string of 19 characters and a terminating null character. The statement


cin >> string2;

reads a string from the keyboard into string2 and appends the null character to the end of the string input by the user. Note that the preceding statement provides only the name of the array and no information about the size of the array. It is the programmer's responsibility to ensure that the array into which the string is read is capable of holding any string the user types at the keyboard. By default, cin reads characters from the keyboard until the first white-space character is encounteredregardless of the array size. Thus, inputting data with cin and >> can insert data beyond the end of the array (see Section 8.13 for information on preventing insertion beyond the end of a char array).

Common Programming Error 7.9

Not providing cin >> with a character array large enough to store a string typed at the keyboard can result in loss of data in a program and other serious runtime errors.

A character array representing a null-terminated string can be output with cout and <<. The statement

cout << string2;

prints the array string2. Note that cout <<, like cin >>, does not care how large the character array is. The characters of the string are output until a terminating null character is encountered. [Note: cin and cout assume that character arrays should be processed as strings terminated by null characters; cin and cout do not provide similar input and output processing capabilities for other array types.]

Figure 7.12 demonstrates initializing a character array with a string literal, reading a string into a character array, printing a character array as a string and accessing individual characters of a string.

Figure 7.12. Character arrays processed as strings.

(This item is displayed on pages 343 - 344 in the print version)

1 // Fig. 7.12: fig07_12.cpp 2 // Treating character arrays as strings. 3 #include 4 using std::cout; 5 using std::cin; 6 using std::endl; 7 8 int main() 9 { 10 char string1[ 20 ]; // reserves 20 characters 11 char string2[] = "string literal"; // reserves 15 characters 12 13 // read string from user into array string1 14 cout << "Enter the string "hello there": "; 15 cin >> string1; // reads "hello" [space terminates input] 16 17 // output strings 18 cout << "string1 is: " << string1 << " string2 is: " << string2; 19 20 cout << " string1 with spaces between characters is: "; 21 22 // output characters until null character is reached 23 for ( int i = 0; string1[ i ] != ''; i++ ) 24 cout << string1[ i ] << ' '; 25 26 cin >> string1; // reads "there" 27 cout << " string1 is: " << string1 << endl; 28 29 return 0; // indicates successful termination 30 } // end main  

Enter the string "hello there": hello there string1 is: hello string2 is: string literal string1 with spaces between characters is: h e l l o string1 is: there  


Lines 2324 of Fig. 7.12 use a for statement to loop through the string1 array and print the individual characters separated by spaces. The condition in the for statement, string1[ i ] != '', is true until the loop encounters the terminating null character of the string.

Static Local Arrays and Automatic Local Arrays

Chapter 6 discussed the storage class specifier static. A static local variable in a function definition exists for the duration of the program, but is visible only in the function body.

Performance Tip 7.2

We can apply static to a local array declaration so that the array is not created and initialized each time the program calls the function and is not destroyed each time the function terminates in the program. This can improve performance, especially when using large arrays.

A program initializes static local arrays when their declarations are first encountered. If a static array is not initialized explicitly by the programmer, each element of that array is initialized to zero by the compiler when the array is created. Recall that C++ does not perform such default initialization for automatic variables.

Figure 7.13 demonstrates function staticArrayInit (lines 2541) with a static local array (line 28) and function automaticArrayInit (lines 4460) with an automatic local array (line 47).

Figure 7.13. static array initialization and automatic array initialization.

(This item is displayed on pages 344 - 346 in the print version)

1 // Fig. 7.13: fig07_13.cpp 2 // Static arrays are initialized to zero. 3 #include 4 using std::cout; 5 using std::endl; 6 7 void staticArrayInit( void ); // function prototype 8 void automaticArrayInit( void ); // function prototype 9 10 int main() 11 { 12 cout << "First call to each function: "; 13 staticArrayInit(); 14 automaticArrayInit(); 15 16 cout << " Second call to each function: "; 17 staticArrayInit(); 18 automaticArrayInit(); 19 cout << endl; 20 21 return 0; // indicates successful termination 22 } // end main 23 24 // function to demonstrate a static local array 25 void staticArrayInit( void ) 26 { 27 // initializes elements to 0 first time function is called 28 static int array1[ 3 ]; // static local array 29 30 cout << " Values on entering staticArrayInit: "; 31 32 // output contents of array1 33 for ( int i = 0; i < 3; i++ ) 34 cout << "array1[" << i << "] = " << array1[ i ] << " "; 35 36 cout << " Values on exiting staticArrayInit: "; 37 38 // modify and output contents of array1 39 for ( int j = 0; j < 3; j++ ) 40 cout << "array1[" << j << "] = " << ( array1[ j ] += 5 ) << " "; 41 } // end function staticArrayInit 42 43 // function to demonstrate an automatic local array 44 void automaticArrayInit( void ) 45 { 46 // initializes elements each time function is called 47 int array2[ 3 ] = { 1, 2, 3 }; // automatic local array 48 49 cout << " Values on entering automaticArrayInit: "; 50 51 // output contents of array2 52 for ( int i = 0; i < 3; i++ ) 53 cout << "array2[" << i << "] = " << array2[ i ] << " "; 54 55 cout << " Values on exiting automaticArrayInit: "; 56 57 // modify and output contents of array2 58 for ( int j = 0; j < 3; j++ ) 59 cout << "array2[" << j << "] = " << ( array2[ j ] += 5 ) << " "; 60 } // end function automaticArrayInit  

First call to each function: Values on entering staticArrayInit: array1[0] = 0 array1[1] = 0 array1[2] = 0 Values on exiting staticArrayInit: array1[0] = 5 array1[1] = 5 array1[2] = 5 Values on entering automaticArrayInit: array2[0] = 1 array2[1] = 2 array2[2] = 3 Values on exiting automaticArrayInit: array2[0] = 6 array2[1] = 7 array2[2] = 8 Second call to each function: Values on entering staticArrayInit: array1[0] = 5 array1[1] = 5 array1[2] = 5 Values on exiting staticArrayInit: array1[0] = 10 array1[1] = 10 array1[2] = 10 Values on entering automaticArrayInit: array2[0] = 1 array2[1] = 2 array2[2] = 3 Values on exiting automaticArrayInit: array2[0] = 6 array2[1] = 7 array2[2] = 8  


Function staticArrayInit is called twice (lines 13 and 17). The static local array is initialized to zero by the compiler the first time the function is called. The function prints the array, adds 5 to each element and prints the array again. The second time the function is called, the static array contains the modified values stored during the first function call. Function automaticArrayInit also is called twice (lines 14 and 18). The elements of the automatic local array are initialized (line 47) with the values 1, 2 and 3. The function prints the array, adds 5 to each element and prints the array again. The second time the function is called, the array elements are reinitialized to 1, 2 and 3. The array has automatic storage class, so the array is recreated during each call to automaticArrayInit.

Common Programming Error 7.10

Assuming that elements of a function's local static array are initialized every time the function is called can lead to logic errors in a program.

Категории