As first discussed in Chapter 3, initialization is when you assign a value to a variable in the same statement in which you declare that variable. By contrast, assignment is when you assign a value to a variable in a statement after the one in which you declare that variable.
We will discuss assigning values to an array later in this chapter in the section Assigning and Displaying Array Values. This section covers initialization of an array.
You have two alternative methods of initializing an array. The first alternative is explicit array sizing, in which the square brackets contain a numerical constant that explicitly specifies the size of the array. The second alternative is implicit array sizing, in which the square brackets are empty and the size of the array is indicated implicitly by the number of elements on the right side of the assignment operator.
The following are examples of explicit array sizing:
int testScore[3] = { 74, 87, 91 }; float milesPerGallon[4] = { 44.4, 22.3, 11.6, 33.3}; char grades[5] = {'A', 'B', 'C', 'D', 'F' }; string days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
The syntax of initialization, with both explicit and implicit array sizing, is that the array declaration, such as int testScore[3], is followed by an assignment operator and then, enclosed in curly braces, the values to be assigned to each array element, in order, are separated by commas. For example, in the following statement, the value of the first element of the array ( testScore[0] ) would be 74, the value of the second element of the array 87, and the value of the third element of the array 91.
int testScore[3] = { 74, 87, 91 };
The number of elements on the right-hand side of the assignment operator cannot be greater than the number within the square brackets. Thus, the following statement will not compile, the error message being too many initializers.
float milesPerGallon[4] = { 44.4, 22.3, 11.6, 33.3, 7.4}; // won't compile
You do not have to assign values to each element of the array; the number of elements on the right-hand side of the assignment operator may be less than the number within the square brackets:
float milesPerGallon[4] = { 44.4, 22.3, 11.6};
If you do not initialize all of the elements of an array, the uninitialized elements have a default value that depends on the data type of the array. For example, the default value is 0 for an integer array, 0.0 for a float array, and the null character, ˜\0 , for a character array.
Note | The null character is discussed later in this chapter in the section Initializing a Character Array. |
Additionally, if you leave an element uninitialized, all elements that follow it must be uninitialized. You can t, for example, alternate initializing and not initializing array elements. For example, the following statement won t compile:
float milesPerGallon[4] = { 44.4, , 11.6, 33.3}; // won't compile
The following are examples of implicit array sizing:
int testScore[ ] = { 74, 87, 91 }; float milesPerGallon[ ] = { 44.4, 22.3, 11.6, 33.3}; char grades[ ] = {'A', 'B', 'C', 'D', 'F' }; string days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
The first array, testScore, allocates memory for three integers. Since the square brackets are blank, the compiler allocates memory based on the number of elements to the right side of the assignment statement.
Similarly, the second array, milesPerGallon, allocates memory for four floats, the third array, grades, allocates memory for five characters , and the fourth array, days, allocates memory for seven strings.
The compiler only allocates memory based on the number of elements to the right side of the assignment statement if the square brackets are empty. Otherwise, memory is allocated based on the number in the square brackets. Thus, in the following example, the declaration of the array testScore would allocate memory for five integers even though only three integers are in the initialization statement because memory allocation is determined by the number within the square brackets. As discussed in the previous section, the fourth and fifth elements of the array would be initialized to a default value, 0.
int testScore[5] = { 74, 87, 91 };
However, you must tell the compiler one way or the other how much memory to allocate. Therefore, when declaring an array, you cannot have both empty square brackets and no initialization, as in the following example:
int testScore[ ];
The compiler error message will be that the array is of unknown size. This of course is a problem since the computer has no way of knowing how much memory to allocate for the array.
As the previous section showed, you can initialize a character array using the same syntax as you would to initialize an array of another data type such as an integer or a float. However, as you will see in this chapter, there are some important differences between character arrays and arrays of numeric data types. This section will show you the first difference.
The following two initializations of a character array to my first name are different in syntax but identical in effect:
char name[ ] = {'J', 'e', 'f', 'f', '/0' }; char name = "Jeff";
The latter syntax usually is preferred by programmers simply because it is easier to type.
The character ˜\0 is the escape sequence for a null character. The 0 in ˜\0 is a zero, not a big letter o. The zero corresponds to the ASCII value of the null character.
Chapter 2 introduced escape sequences, starting with ˜\n , the newline character, which causes the cursor to go to the next line for further printing. The ˜\n in a string is not displayed literally by cout because the backslash signals cout that ˜\n is an escape sequence.
The null character has a different purpose, which is to signal cout when to end the output of a character array. For example, the following program outputs, as expected, Jeff :
#include <iostream> using namespace std; int main () { char name[ ] = {'J', 'e', 'f', 'f', '/0' }; cout << name; return 0; }
The result would be the same if the alternate syntax of char name = Jeff was used to initialize the character array.
By contrast, the following program outputs Jeff + ?.
#include <iostream> using namespace std; int main () { char name[ ] = {'J', 'e', 'f', 'f'}; cout << name; return 0; }
The strange characters after Jeff (which may differ when you run the program) sometimes are referred to as garbage characters. However, that really is not a fair or accurate description. What really is happening is that cout keeps outputting the values at each succeeding address after the end of the array until it reaches a value that it interprets as a null character. As discussed earlier in this chapter, the program does its best to interpret whatever value is at a given memory address, perhaps left over from some other program, but the resulting output often makes little sense. In general, garbage characters are ASCII representations of integers stored in a memory address.
All this does not mean that the last element of a character array always should be a null character. When each element of a character array is separate from the other, such as a separate grade for each test, there is no need to use a null character. However, if the character array elements are related , such as a character array representing a person s name, then usually the last element should be a null character. The syntax of char name = Jeff accomplishes that, automatically inserting a null character as the fifth element of the array.
Finally, the alternate syntax of char name = Jeff is quite similar to how you initialize a string data type:
char name[] = "Jeff"; string name = "Jeff";
Indeed, a character array that ends with a null character often is referred to colloquially as a string. However, a character array that ends with a null character is not thereby converted to a string data type; it is still a character array. Indeed, there is no guarantee that a compiler s implementation of the string data type will result in the last character of a true string being a null character.
Thus, while character arrays and strings have many similarities, they are not the same. There are important differences. One is you cannot safely assume that a string ends with a null character. Other differences will be discussed later in this chapter in the sections on the cin Object s get and getline member functions.
You can create arrays that are constants. For example, the following array contains the number of days in each month (for February, we assume a non “leap year).
const int daysInMonth [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
Using a constant array here is a good choice since the number of days in each month will not change.
You must use initialization when creating a constant array, just as you must use initialization when creating a constant variable. Since you cannot change the values later, you must specify the values when you create the constant.
C++ gives you the option of just declaring an array, with the values of the array elements unassigned , and initializing an array, assigning values to some or all of the array elements.
Initialization usually is the better choice when you know in advance some or all of the array element values, but it is not limited to that scenario. Initialization sometimes is used to provide each array element with an initial default value. For example, we might initialize each element of the testScore array to “1 as a signal that no test score has yet been assigned. The number “1 is a better choice for this purpose than 0 since a student could get a zero on a test, but not a “1.
However, initializing to a default value can be cumbersome when there are many array elements. Additionally, when you don t know in advance the array values, such as for test scores, you may decide against initializing for a default value. Further, even if you do use initialization, you may later want to change the values of some or all of the array elements. Accordingly, you need to know how to assign values to an array. You also will want to display array values. The next section shows you how.