Essentialssec8.htm

Essentials of C++: Section VIII


Arrays

A. Declaring Arrays
The array is the C++ data structure used to identify and manipulate a set of memory locations all of which hold values of the same type. To declare an identifier to be an array, one uses the form:

someType someVariableName [some constant expression]

For example:

const   MAX_ITEMS = 100;
double prices[MAX_ITEMS];

declares an array called 'prices' that represents a contiguous region of memory large enough to hold 100 doubles.

Usually one uses a named constant (or less preferably a positive integer) inside the square brackets but any expression that evaluates to a positive constant integer is acceptable.

As written, this declaration creates a one-dimensional array - the data can be pictured as consisting of one row. A two dimensional array (often pictured as a table) can be declared by adding a second set of square brackets as in:

const   MAX_ITEMS = 100;
const   MAX-YEARS = 20;
double pricesByYear[MAX_YEARS] [MAX_ITEMS];

This declares a variable 'pricesByYear' that holds the prices for MAX_YEAR's worth of MAX_ ITEMS.

Inside the computer, this would be represented as one contiguous memory space large enough to hold MAX-YEARS * MAX_ITEMS doubles, but we would treat it as a two-dimensional object.

One can create arrays with extra dimensions simply by including more constant expressions in brackets as in:

const DIM_1 = 10;
const DIM_2 = 5;
const DIM_3 = 20;
int anArray[DIM_1] [DIM_2] [DIM_3];

It is possible to initialize an array at declaration time. The general initialization form for one-dimensional arrays is:

someType someVariableName [some constant expression] = {.......}

where the number of elements inside the {} is equivalent to the value of "some constant expression". If not enough initialization values are included, the remaining array elements are initialized to 0. When initializing an array in this form, it is legal to leave out "some constant expression" inside the square brackets since the compiler can determine the size of the array from the number of initialization values.

One can initialize a multi-dimensional array in the same way - by including a list of initialization values. To make it easier to keep track of which value goes into which array element, it is possible to group initialization values by dimension. For example,

int twoDim[3] [2] = { {10,11}, {12,13}, {14,15}};

 

B. Using Arrays
The array name represents all the elements of the array. To access the individual elements of a one-dimensional array, one uses the form:

array name [some constant expression]

as in:

cout << prices[3];

The 'constant expression' (the '3' in this case) represents an index (or subscript) into the array. In C++, all arrays start with an index value of 0 and go to one less than the value of the constant expression used in the declaration. These are the array bounds. For example, given the declaration of 'prices' above, the array indices range from 0 to 99 and thus its bounds are 0 through 99.

Using an index value outside the array bounds can have unpredictable results. You are actually requesting direct access to memory that is not within the confines of the array! Since C++ by default has no bounds checking, the programmer must take on this responsibility. If a program that uses arrays exhibits strange behavior, the programmer should check carefully to make sure all array element references are within bounds.

Index values can be represented by any expression that evaluates to a positive integer constant. Thus, one can, for example, use arithmetic expressions as indices as in::

prices[index1 + index2] = prices[index1] * .05;

While this code probably makes no sense, it is syntactically correct and demonstrates both the use of expressions to represent index values and that one can use array elements anywhere one can use variables and constants.

Multi-dimensional array elements are accessed the same way, using as many indices as there are dimensions. Thus, to input a value into the "3rd row, 5th column" of the 'pricesByYear' table defined above, we would write:

cin >> pricesByYear[2] [4];

(Remember, since array indices start counting from 0, the indices in this code are one less than the values used in the verbal description.)

Since the individual elements represent some specific type, one can use array elements of some type anywhere that one can use non-array elements of that same type. However, with few exceptions, one cannot perform an operation on an array as a whole. It is therefore illegal, for example, to write:

cout << prices; // THIS IS ILLEGAL

This is true also of the 'return' statement. While it is possible to 'return' an element of an array, it is not possible to return the whole array as in:

return prices; // THIS IS ILLEGAL

One exception to the rule that arrays cannot be handled as a whole is in parameter passing. It is possible to declare a variable as a formal parameter so as to receive (and return) an entire array. For example,

GetPrices(double thePrices[]);

declares a function that receives an array of doubles. Note that the brackets do NOT contain a value indicating the size of the array. The system takes care of that when it sees the size of the array being passed. You can also use the 'typedef' statement (Section IX) or pointer notation (Section X) to declare array parameters.

Array parameters are automatically treated as reference parameters and there is, therefore, no reason to use the '&' symbol in declaring an array whose values you wish to return. This means that arrays, by default, are always modifiable. If you wish to protect the array being passed from being changed inside the function, you can place the keyword 'const' in front of the formal parameter as in:

GetPrices(const double thePrices[]);

With when using multi-dimensional arrays as parameters one must provide the size of all indices except the first as in:

GetPrices(double thePricesByYear [] [MAX_ITEMS]);

To pass an array as an actual parameter on simply uses the array name in the function call.
 

C. Strings as Arrays
A string is a collection of characters and in C++ it is traditionally represented as an array with the special symbol '\0', referred to as the null character, at the end. (This symbol represents the value for the integer 0, not the value corresponding to the character '0'.) If a string has six characters, as in "curtis", the array for this string must have room for seven characters - one for the null character. This null character is extremely important as all standard string manipulation functions assume its existence.

One can manipulate string arrays in the ways described above for general array manipulation. However, strings are an exception to the rule that only the individual elements of an array can be manipulated. One can input and output string arrays as a unit as in:

char str[] = "curtis";

cout << str;

Notice that the string array can be initialized via a string constant and that the null character is automatically added.

More recently C++ compilers have added a predefined string type. See Section XIII for more information on this and on general string processing.
 

Links to 'The Story of C++" and other documents

Arrays
Indices and Bounds Checking
Arrays as Parameters

Top of Section Main Menu of Essentials of C++ Next Section