Array Types


The syntax of array declarations was presented in the section on declarators. This section gives further information on the subject of arrays.

Syntax

An array of type T may be declared as follows.

array_declaration:
       T array_name[constant_expression]

Notes

Examples are given in the section on initializers (topic aggregates) of arrays that are declared without the array dimension being specified (see also below). In such cases, the dimension of the array can be determined from the number of initializers given.

If the dimension of the array is specified (as denoted by constant_expression in the above syntax statement), it must be a value greater than zero. The subscript operator (operator[]) may be used to access elements of an array. The index supplied to this operator is zero based, thus if the array contains N elements then valid values for the index range from 0...N-1.

Whilst an array of functions is not possible, an array of pointers to functions or methods is possible. An array of void is not possible, although an array of void* is acceptable.

Arrays and Pointers

In C++, there is an intimate relationship between pointers and arrays. It is useful to note that some arithmetic operators may be applied to pointers (see prefix and postfix unary operators and binary operators). Consider the following example.

structure point {int x; int y;} array[10];
 
point* pointer = array;
 
for (int i=0; i<10; i++)
 {
  pointer->x = pointer->y = i;
  pointer++;
}

Note that the expression pointer++ indeed sets the pointer to point at successive elements in the array. Unlike some other languages, in C++ pointers always point to a specific type. Thus, the size of the object pointed to is always known, hence the increment operator correctly increments a pointer. Certain other arithmetic operations, such as addition, are also valid with pointers. The statement assigning array to pointer spells out the relationship between an array name and a pointer. Except in the cases where the identifier naming an array is:

it is converted to a pointer to the first element of the array. For this reason, arrays are not modifiable lvalues. For an array A and an index i, the expression A[i] is converted to *(A+i), where A is treated as a pointer to the first element. From this it follows that

A[B] = *(A+B) == *(B+A) = B[A]

hence, the commutivity of the subscript operator follows from the commutivity of operator+ and the interpretation placed upon pointers by addition.

Multidimensional Arrays

Multidimensional arrays are also supported. For example, the following code fragment declares, initializes and makes use of a two dimensional array of integers.

int array2D[][4] = { {11,12,13,14}, {21,22,23,24} };
 
for (int i=0; i<2; i++)
 {
  for (int j=0; j<4; j++)
   cout << array2D[i][j] << ",";

  cout << "\n";
 }

The following output results.

11,12,13,14,
21,22,23,23,

Multidimensional arrays are stored in row order in memory. The last index varies most rapidly when accessing an array. When declaring a multidimensional array, only the first array bound may be omitted from the declaration. Omitting the first array bound can often be a useful device when declaring an array parameter to a function. Consider the following program.

#define include_stream
#include <windows.hpp>
 
void main()
{
 double array3D[][4][2] = { { {10,11}, {20,21}, {30,31}, {40,41} },
                            { {50,51}, {60,61}, {70,71}, {80,81} }  };
 
 double n = array3D[1][3][1];
 cout << n << '\n';
 double* pointer = array3D[0][3];
 cout << *pointer << '\n';
 double (*pointer_array)[] = array3D[1];
 cout << (*pointer_array)[1] << '\n';
}

The numbers 81, 40 and 51 are printed on successive lines. The expression array3D[1][3][1] is of type double, and selects the last element in the three dimensional array. In the calculation of pointer, array3D[0][3] is of type double[2], and is the array {40,41}. Upon assignment to pointer, the type double[2] is converted to a pointer to the first element of this array - which is 40. The expression array3D[1] is of type double[4][2], and is converted to a pointer of type double(*)[2]. That is, array3D[1] is converted to a pointer to an array of pairs of doubles (being the second row of the above declaration). The assignment to pointer_array selects the first element of this array, being the pair {50,51}, which is itself an array of type double[2]. This explains why the number 51 is printed out.

From the above discussion it should be apparent that the first index in a multidimensional array determines the amount of storage allocated, whereas subsequent indexes determined the structure of the array and the underlying arithmetic that applies to indexing on that array. It is for this reason that the first, and only the first, dimension may be omitted when declaring a multidimensional array.