Wrox Press C++ Tutorial
We already know how to declare and initialize variables of various types, which each hold a single item of information and which we will refer to as data elements. We know how to create a single character in a char variable, a single integer in a variable of type int or of type long, or a single floating point number in a variable of type float or double. The most obvious extension to these ideas is to be able to reference several data elements of a particular type with a single variable name. This would enable you to handle applications of a much broader scope.
Let's think about an example of where you might need this. Suppose that you needed to write a payroll program. Using a separately-named variable for each individual's pay, tax liability, and so on, would be an uphill task to say the least. A much more convenient way to handle such a problem would be to reference an employee by some kind of generic name - EmployeeName to take an imaginative example - and to have other generic names for the kinds of data related to each employee, such as Pay, Tax, and so on. Of course, you would also need some means of picking out a particular employee from the whole bunch, together with the data from the generic variables associated with them. This kind of requirement arises with any collection of like entities that you want to handle in your program, whether they're baseball players or battleships. Naturally, C++ provides you with a way to deal with this.
The basis for the solution to all of these problems is provided by the array in C++. An array is simply a number of memory locations, each of which can store an item of data of the same data type, and which are all referenced through the same variable name. The employee names in a payroll program could be stored in one array, the pay for each employee in another, and the tax due for each employee could be stored in a third array.
Individual items in an array are specified by an index value which is simply an integer representing the sequence number of the elements in the array, the first having the sequence number 0, the second 1, and so on. You can also envisage the index value of an array element as an offset from the first element in an array. The first element has an offset of 0 and therefore an index of 0, and an index value of 3 will refer to the fourth element of an array. For our payroll, we could arrange our arrays so that if an employee's name was stored in the EmployeeName array at a given index value, then the arrays Pay and Tax would store the associated data on pay and tax for the same employee in the array positions referenced by the same index value.
The basic structure of an array is illustrated in the figure below:

This shows an array, called Height, with six elements, each storing a different value. These might be the heights of the members of a family, for instance, recorded to the nearest inch. As there are six elements, the index values run from 0 through 5. To refer to a particular element, you write the array name, followed by the index value of the particular element between square brackets. The third element is referred to as Height[2], for example.
The amount of memory required to store each element will be determined by its type, and all the elements of an array will be stored in a contiguous block of memory.
You declare an array in essentially the same way as you declared the variables that we have seen up to now, the only difference being that the number of elements in the array is specified between square brackets immediately following the array name. For example, we could declare the integer array Height, shown in the previous figure, with the following declaration statement:
long Height[6];
Remember that the indexes in an array start at 0, however, so that the highest element of this array is Height[5].
Since each long value occupies 4 bytes in memory, the whole array requires 24 bytes. Arrays can be of any size, subject to the constraints imposed by the amount of memory in the computer that your program will be running on.
You can declare arrays to be of any type. For example, to declare arrays intended to store the capacity and power output of a series of engines, you could write the following:
double cubic_inches[10];
double horsepower[10];
If auto mechanics is your thing, this would enable you to store the cubic capacity and power output of up to 10 engines, referenced by index values from 0 to 9. As we have seen before with other variables, you can declare multiple arrays of a given type in a single statement, but in practice it is better to declare variables in separate statements.
As a basis for an exercise in using arrays, let's imagine that we have kept a record of both the amount of gas we have bought for the car and the odometer reading on each occasion. We can write a program to analyze this data to see how the gas consumption looks on each occasion that we bought gas:
// Ex3_01.cpp
// Calculating gas mileage
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
const int MAX = 20; // Maximum number of values
double gas[ MAX ]; // Gas quantity in gallons
long miles[ MAX ]; // Odometer readings
int count = 0; // Loop counter
char indicator = 'y'; // Input indicator
while( (indicator == 'y' || indicator == 'Y') && count < MAX )
{
cout << endl
<< "Enter gas quantity: ";
cin >> gas[count]; // Read gas quantity
cout << "Enter odometer reading: ";
cin >> miles[count]; // Read odometer value
++count;
cout << "Do you want to enter another(y or n)? ";
cin >> indicator;
}
if(count <= 1) // count = 1 after 1 entry completed -
{ // we need at least 2.
cout << endl
<< "Sorry - at least two readings are necessary.";
return 0;
}
// Output results from 2nd entry to last entry
for(int i=1; i < count; i++)
cout << endl
<< setw(2) << i << "." // Output sequence number
<< "Gas purchased = " << gas[ i] << " gallons"
// Output gas
<< " resulted in " // Output miles per gallon
<< (miles[i] - miles[i-1])/gas[i]
<< " miles per gallon.";
cout << endl;
return 0;
}
Since we need to take the difference between two odometer readings to calculate the miles covered for the gas used, we only use the odometer reading from the first pair of input values - we ignore the gas bought in the first instance. The typical output produced by this example is shown in the figure below:

During the second period shown in the output, the traffic must have been really bad - or maybe the parking brake was always on.
The dimensions of the two arrays gas and miles used to store the input data are determined by the value of the constant variable MAX. By changing the value of MAX, you can change the program to accommodate a different maximum numbers of input values. This technique is commonly used to make a program flexible in the amount of information that it can handle. Of course, all the program code must be written to take account of the array dimensions, or of any other parameters being specified by const variables. However, this presents little difficulty in practice, so there's no reason why you should not adopt this approach. We'll also see later how to allocate memory for storing data as the program executes, so that we don't need to fix the amount of memory allocated for data storage in advance.
The data values are read in the while loop. Since the loop variable can run from 0 to MAX-1, we haven't allowed the user of our program to enter more values than the array can handle. We initialize the variables count and indicator to 0 and 'y' respectively, so that the while loop is entered at least once. There's a prompt for each input value required and the value is read into the appropriate array element. The element used to store a particular value is determined by the variable count, which is 0 for the first input. The array element is specified in the cin statement by using count as an index, and count is then incremented ready for the next value.
After you enter each value, the program prompts you for confirmation that another value is to be entered. The character entered is read into the variable indicator and then tested in the loop condition. The loop will terminate unless 'y' or 'Y' is entered and the variable count is less than the specified maximum value, MAX.
Once the input loop ends (by whatever means), the value of count contains one more than the index value of the last element entered in each array. (Remember, we increment it after we enter each new element.) This is checked in order to verify that at least two pairs of values were entered. If this wasn't the case, the program ends with a suitable message, since two odometer values are necessary to calculate a mileage value.
The output is generated in the for loop. The control variable i runs from 1 to count-1, allowing mileage to be calculated as the difference between the current element, miles[i] and the previous element, miles[i-1]. Note that an index value can be any expression evaluating to an integer that represents a legal index for the array in question.
If the value of an index expression lies outside of the range corresponding to legitimate array elements, you will be referencing a spurious data location that may contain other data, garbage, or even program code. If the reference to such an element appears in an expression, you will be using some arbitrary data value in the calculation, which will certainly produce a result that you did not intend. If you are storing a result in an array element using an illegal index value, you will overwrite whatever happens to be in that location. When this is part of your program code, the results will be catastrophic. If you use illegal index values, there are no warnings produced either by the compiler or at run-time. The only way to guard against this is to code your program to prevent it happening.
The output is generated by a single cout statement for all values entered, except for the first. A line number is also generated for each line of output using the loop control variable i. The miles per gallon is calculated directly in the output statement. You can use array elements in exactly the same way as any other variables in an expression.
To initialize an array, the initializing values are enclosed within curly braces in the declaration and placed following an equals sign after the array name. The following statement shows an example of a declaration and initialization of an array:
int cubic_inches[5] = { 200, 250, 300, 350, 400 };
The values in the initializing list correspond to successive index values of the array, so in this case cubic_inches[0] will have the value 200, cubic_inches[1] the value 250, cubic_inches[2] the value 300, and so on.
You mustn't specify more initializing values than there are elements in the list, but you can include fewer. If there are fewer, the values are assigned to successive elements, starting with the first element which has the index 0. The array elements for which you didn't provide an initial value will be initialized with zero. This isn't the same as supplying no initializing list. Without an initializing list, the array elements will contain junk values. Also, if you include an initializing list, there must be at least one initializing value in it, otherwise the compiler will generate an error message. We can illustrate this with the following, rather limited, example.
// Ex3_02.cpp
// Demonstrating array initialization
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int value[5] = { 1, 2, 3 };
int Junk [5];
cout << endl;
for(int i=0; i<5; i++)
cout << setw(12) << value[i];
cout << endl;
for(i=0; i<5; i++)
cout << setw(12) << Junk[i];
cout << endl;
return 0;
}
In this example we declare two arrays, the first of which, value, is initialized in part, and the second, Junk, is not initialized at all. The program generates two lines of output, which on my computer look like this:

The second line (corresponding to values of Junk[0] to Junk[4]) may well be different on your computer.
The first three values of the array value are the initializing values and the last two have the default value of 0. In the case of Junk, all the values are spurious since we didn't provide any initial values at all. The array elements will contain whatever values were left there by the program which last used these memory locations.
A convenient way to initialize a whole array to zero is simply to specify a single initializing value as 0. For example, the statement,
long data[100] = {0}; // Initialize all elements to zero
declares the array data, with all one hundred elements initialized with 0.
You can also omit the dimension of an array of numeric type, providing you supply initializing values. The number of elements in the array will be determined by the number of initializing values. For example, the array declaration,
int value[] = { 2, 3, 4 };
defines an array with three elements with initial values 2, 3, and 4.
An array of type char is called a character array and is generally used to store a character string. A character string is a sequence of characters with a special character appended to indicate the end of the string. The string terminating character is defined by the escape sequence '\0', and is sometimes referred to as a null character, being a byte with all bits as zero. The representation of a string in memory is shown in the figure below:
This illustrates how a string looks in memory and shows a form of declaration for a string that we will get to in a moment.
Each character in the string occupies one byte, so together with the null character, a string requires a number of bytes that is one greater than the number of characters contained in the string.
We can declare a character array and initialize it with a string literal between quotation marks. For example:
char movie_star[12] = "Paul Newman";
Note that the terminating '\0' will be supplied automatically by the compiler. If you include one explicitly in the string constant, you will end up with two of them. You must, however, include space for the terminating null in the number of elements that you allot to the array.
You can let the compiler work out the length of an initialized array for you, as we saw in the previous illustration. Have a look at the following declaration:
char President[] = "Ulysses Grant";
Because the dimension is unspecified, the compiler will allocate space for enough elements to hold the initializing string, plus the terminating null character. In this case it allocates 14 elements for the array President. Of course, if you want to use this array later for storing a different string, its length (including the terminating null character) must not exceed 14 bytes. In general, it is your responsibility to ensure that the array is large enough for any string you might subsequently want to store.
You may well have heard of Unicode, or seen references to it in the Visual C++ documentation, so we'll just outline it here so that you know what it refers to. For supporting international character sets, a character type wchar_t is supported, which uses 2 bytes for each character. This allows 65,536 different characters to be represented, which makes it possible for all the national characters sets to be given unique 16-bit codes, so they can coexist within a single 2-byte character set. This makes creating applications intended for multinational markets much easier.
The definition of the 2-byte character set which incorporates all national character sets, as well as all other standard technical and publishing symbols, is called Unicode. The MFC provides facilities for using the Unicode character set in your Windows programs. We won't be going into any further detail on Unicode in this book, not because it's difficult - it isn't - but simply because we have to stop somewhere!
The header file iostream contains definitions of a number of functions for reading characters from the keyboard. The one that we shall look at here is the function getline(), which reads a string into a character array. This is typically used with statements such as this:
const int MAX = 80;
char name[MAX];
...
cin.getline(name, MAX, '\n');
These statements first declare a char array name with MAX elements and then read characters from cin using the function getline(). The source of the data, cin, is written as shown, with a period separating it from the function name. The significance of various parts of the input statement is shown below:

Characters are read from cin until the '\n' (newline or end line character) character is read, or when MAX-1 characters have been read (the terminating '\0' is appended), whichever occurs first. The '\n' character is generated when you press the Return key on your keyboard, and is therefore usually the most convenient character to end input. You can, however, specify something else if you wish by changing the last argument. The '\n' isn't stored in the input array name, but a '\0' is added at the end of input string in the array.
We will learn more about this form of syntax when we discuss classes later on. Meanwhile, just take it for granted and we'll have a go at using it in an example.
We now have enough knowledge to write a simple program to read a string, and then count how many characters it contains.
// Ex3_03.cpp
// Counting string characters
#include <iostream>
using namespace std;
int main()
{
const int MAX = 80; // Maximum array dimension
char buffer[MAX]; // Input buffer
int count = 0; // Character count
cout << "Enter a string of less than 80 characters:\n";
cin.getline(buffer, MAX, '\n'); // Read a string until \n
while(buffer[count]!= '\0')
// Increment count as long as the current character
// is not null
count++;
cout << endl
<< "The string \"" << buffer
<< "\" has " << count << " characters.";
cout << endl;
return 0;
}
Typical output from this program is illustrated below:

This program declares a character array buffer and reads a character string from the keyboard after displaying a prompt for the input. Reading from the keyboard ends when the user presses Return, or when MAX-1 characters have been read.
A while loop is used to count the number of characters read. The loop continues as long as the current character, referenced with buffer[count], is not '\0'. This sort of checking on the current character (while stepping through an array) is a common technique in C++. The only action in the loop is to increment count for each non-null character.
There is also a library function, strlen(), that can save you the trouble of coding it yourself. If you use it, you need to include the string.h header file in your program.
Finally in our example, the string and the character count is displayed with a single output statement. Note how we need to use the escape character '\"' to output a quote.
The arrays that we have defined so far with one index are referred to as one-dimensional arrays. An array can also have more than one index value, in which case it is called a multidimensional array. Suppose we have a field in which we are growing bean plants in rows of 10, and the field contains 12 such rows (so there are 120 plants in all). We could declare an array to record the weight of beans produced by each plant using the following statement:
double beans[12][10];
This declares the two-dimensional array beans, the first index being the row number, and the second index the number within the row. To refer to any particular element requires two indices. For example, we could set the value of the element reflecting the fifth plant in the third row with the following statement:
beans[2][4] = 10.7;
Remember that the index values start from zero, so the index value for the third row is 2 and the index for the fifth plant within the row is 4.
Being successful bean farmers, we might have several identical fields planted with beans in the same pattern. Assuming that we have eight fields, we could use a three-dimensional array, declared thus:
double beans[8][12][10];
This will record production for all of the plants in each of the fields, the leftmost index referencing a particular field. If we ever get to bean farming on an international scale, we will be able to use a four-dimensional array, with the extra dimension designating the country. Assuming that you're as good a salesman as you are a farmer, growing this quantity of beans to keep up with the demand may start to affect the ozone layer.
Arrays are stored in memory such that the rightmost index value varies most rapidly. You can visualize the array data[3][4] as three one-dimensional arrays of four elements each. The arrangement of this array is illustrated below:

To initialize a multidimensional array, you use an extension of the method used for a one-dimensional array. For example, you can initialize a two-dimensional array, data, with the following declaration:
long data[2][4] = {
{ 1, 2, 3, 5 },
{ 7, 11, 13, 17 }
};
Thus, the initializing values for each row of the array are contained within their own pair of curly braces. Since there are four elements in each row, there are four initializing values in each group, and since there are two rows, there are two groups between braces, each group of initializing values being separated from the next by a comma.
You can omit initializing values in any row, in which case the remaining array elements in the row will be zero. For example, in the declaration,
long data[2][4] = {
{ 1, 2, 3 },
{ 7, 11 }
};
the initializing values have been spaced out to show where values have been omitted. The elements data[0][3], data[1][2], and data[1][3] have no initializing values and will therefore be zero.
If you wanted to initialize the whole array with zeros you could simply write:
long data[2][4] = {0};
If you are initializing arrays with even more dimensions, remember that you need as many nested braces for groups of initializing values as there are dimensions in the array.
We can use a single two-dimensional array to store several strings. We can see how this works with an example:
// Ex3_04.cpp
// Storing strings in an array.
#include <iostream>
using namespace std;
int main()
{
char stars[6][80] = { "Robert Redford",
"Hopalong Cassidy",
"Lassie",
"Slim Pickens",
"Boris Karloff",
"Oliver Hardy"
};
int dice = 0;
cout << endl
<< " Pick a lucky star!"
<< " Enter a number between 1 and 6: ";
cin >> dice;
if(dice >= 1 && dice <= 6) // Check input validity
cout << endl // Output star name
<< "Your lucky star is " << stars[dice-1];
else
cout << endl // Invalid input
<< "Sorry, you haven't got a lucky star.";
cout << endl;
return 0;
}
Apart from its incredible inherent entertainment value, the main point of interest in this example is the declaration of the array stars. It is a two-dimensional char array, which can hold up to 6 strings, each of which can be up to 80 characters (including the terminating null character that is automatically added by the compiler). The initializing strings for the array are enclosed between braces and separated by commas.
One disadvantage of using arrays in this way is the memory that is almost invariably left unused. All of our strings are less than 80 characters and the surplus elements in each row of the array are wasted.
You can also let the compiler work out how many strings you have by omitting the first array dimension and declaring it as follows:
char stars[][80] = { "Robert Redford",
"Hopalong Cassidy",
"Lassie",
"Slim Pickens",
"Boris Karloff",
"Oliver Hardy"
};
This will cause the compiler to define the first dimension to accommodate the number of initializing strings that you have specified. Since we have six the result is exactly the same, but it avoids the possibility of an error. Here you can't omit both array dimensions. The rightmost dimension must always be defined.
Note the semicolon at the end of the declaration. It's easy to forget it when there are initializing values for an array.
Where we need to reference a string for output statement, we need only specify the first index value:
cout << endl // Output star name
<< "Your lucky star is " << stars[dice-1];
A single index value selects a particular 80-element sub-array, and the output operation will display the contents up to the terminating null character. The index is specified as dice-1 as the dice values are from 1 to 6, whereas the index values clearly need to be from 0 to 5.