WHAT YOU WILL LEARN IN THIS CHAPTER:
How to use arrays
How to declare and initialize arrays of different types
How to declare and use multidimensional arrays
How to use pointers
How to declare and initialize pointers of different types
The relationship between arrays and pointers
How to declare references and some initial ideas on their uses
How to allocate memory for variables dynamically in a native C++ program
How dynamic memory allocation works in a Common Language Runtime (CLR) program
Tracking handles and tracking references and why you need them in a CLR program
How to work with strings and arrays in C++/CLI programs
How to create and use interior pointers
So far, we have covered all the fundamental data types of consequence, and you have a basic knowledge of how to perform calculations and make decisions in a program. This chapter is about broadening the application of the basic programming techniques that you have learned so far, from using single items of data to working with whole collections of data items.
In this chapter, you'll be using objects more extensively. Although you have not yet explored the details of how they are created, don't worry if everything is not completely clear. You'll learn about classes and objects in detail starting in Chapter 7.
You already know how to declare and initialize variables of various types that each holds a single item of information; I'll refer to single items of data as data elements. The most obvious extension to the idea of a variable 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 consider 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, their 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 ISO/IEC C++. An array is simply a number of memory locations called array elements or simply elements, each of which can store an item of data of the same given 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 being 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 the payroll, you could arrange the 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 Figure 4-1.
Figure 4-1 shows an array with the name height
that has 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. Because 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. If you think of the index as being the offset from the first element, it's easy to see that the index value for the fourth element will be 3.
The amount of memory required to store each element is determined by its type, and all the elements of an array are stored in a contiguous block of memory.
You declare an array in essentially the same way as you declared the variables that you 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, you could declare the integer array height
, shown in the previous figure, with the following declaration statement:
long height[6];
Because 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 on which your program is running.
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]; // Engine size double horsepower[10]; // Engine power output
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 you have seen before with other variables, you can declare multiple arrays of a given type in a single statement, but in practice it is almost always better to declare variables in separate statements.
To initialize an array in its declaration, you put the initializing values, separated by commas, between braces, and you place the set of initial values following an equals sign after the array name. Here's an example of how you can declare and initialize an array:
int cubic_inches[5] = { 200, 250, 300, 350, 400 };
The array has the name cubic_inches
and has five elements that each store a value of type int
. The values in the initializing list between the braces correspond to successive index values of the array, so in this case cubic_inches[0]
has the value 200, cubic_inches[1]
the value 250, cubic_inches[2]
the value 300, and so on.
You must not specify more initializing values than there are elements in the array, but you can include fewer. If there are fewer, the values are assigned to successive elements, starting with the first element — which is the one corresponding to the index value 0
. The array elements for which you didn't provide an initial value are initialized with zero. This isn't the same as supplying no initializing list. Without an initializing list, the array elements contain junk values. Also, if you include an initializing list, there must be at least one initializing value in it; otherwise the compiler generates an error message. I can illustrate this with the following rather limited example.
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 indicates the end of the string; this character is defined by the escape sequence '