Previous Page
Next Page

8.5. Multidimensional Arrays

A multidimensional array in C is merely an array whose elements are themselves arrays. The elements of an n-dimensional array are (n-1)-dimensional arrays. For example, each element of a two-dimensional array is a one-dimensional array. The elements of a one-dimensional array, of course, do not have an array type.

A multidimensional array declaration has a pair of brackets for each dimension:

char screen[10][40][80];      // A three-dimensional array.

The array screen consists of the 10 elements screen[0] to screen[9]. Each of these elements is a two-dimensional array, consisting in turn of 40 one-dimensional arrays of 80 characters each. All in all, the array screen contains 32,000 elements with the type char.

To access a char element in the three-dimensional array screen, you must specify three indices. For example, the following statement writes the character Z in the last char element of the array:

screen[9][39][79] = 'Z';

8.5.1. Matrices

Two-dimensional arrays are also called matrices . Because they are so frequently used, they merit a closer look. It is often helpful to think of the elements of a matrix as being arranged in rows and columns. Thus the matrix mat in the following definition has three rows and five columns:

float mat[3][5];

The three elements mat[0], mat[1], and mat[2] are the rows of the matrix mat. Each of these rows is an array of five float elements. Thus the matrix contains a total of 3 x 5 = 15 float elements, as the following diagram illustrates:

 

0

1

2

3

4

mat[0]

0.0

0.1

0.2

0.3

0.4

mat[1]

1.0

1.1

1.2

1.3

1.4

mat[2]

2.0

2.1

2.2

2.3

2.4


The values specified in the diagram can be assigned to the individual elements by a nested loop statement. The first index specifies a row, and the second index addresses a column in the row:

for ( int row = 0;  row < 3;  ++row )
  for ( int col = 0;  col < 5;  ++col )
    mat[row][col] = row + (float)col/10;

In memory, the three rows are stored consecutively, since they are the elements of the array mat. As a result, the float values in this matrix are all arranged consecutively in memory in ascending order.

8.5.2. Declaring Multidimensional Arrays

In an array declaration that is not a definition, the array type can be incomplete; you can declare an array without specifying its length. Such a declaration is a reference to an array that you must define with a specified length elsewhere in the program. However, you must always declare the complete type of an array's elements. For a multidimensional array declaration, only the first dimension can have an unspecified length. All other dimensions must have a magnitude. In declaring a two-dimensional matrix, for example, you must always specify the number of columns.

If the array mat in the previous example has external linkage, for examplethat is, if its definition is placed outside all functionsthen it can be used in another source file after the following declaration:

extern float mat[ ][5];      // External declaration.

The external object so declared has an incomplete two-dimensional array type.

8.5.3. Initializing Multidimensional Arrays

You can initialize multidimensional arrays using an initialization list according to the rules described in "Initializing Arrays," earlier in this chapter. There are some peculiarities, however: you do not have to show all the braces for each dimension, and you may use multidimensional element designators.

To illustrate the possibilities, we will consider the array defined and initialized as follows:

int a3d[2][2][3] = { { { 1, 0, 0 }, { 4, 0, 0 } },
                     { { 7, 8, 0 }, { 0, 0, 0 } } };

This initialization list includes three levels of list-enclosing braces, and initializes the elements of the two-dimensional arrays a3d[0] and a3d[1] with the following values:

 

0

1

2

a3d[0][0]

1

0

0

a3d[0][1]

4

0

0

 

0

1

2

a3d[1][0]

7

8

0

a3d[1][1]

0

0

0


Because all elements that are not associated with an initializer are initialized by default to 0, the following definition has the same effect:

int a3d[ ][2][3] = { { { 1 }, { 4 } },  { { 7, 8 } } };

This initialization list likewise shows three levels of braces. You do not need to specify that the first dimension has the size 2, as the outermost initialization list contains two initializers.

You can also omit some of the braces. If a given pair of braces contains more initializers than the number of elements in the corresponding array dimension, then the excess initializers are associated with the next array element in the storage sequence. Hence these two definitions are equivalent:

int a3d[2][2][3] = {  { 1, 0, 0, 4 }, { 7, 8 } };
int a3d[2][2][3] = { 1, 0, 0, 4, 0, 0, 7, 8 };

Finally, you can achieve the same initialization pattern using element designators as follows:

int a3d[2][2][3] = { 1, [0][1][0]=4, [1][0][0]=7, 8 };

Again, this definition is equivalent to the following:

int a3d[2][2][3] = { {1}, [0][1]={4}, [1][0]={7, 8} };

Using element designators is a good idea if only a few elements need to be initialized to a value other than 0.


Previous Page
Next Page