UNIX C Programming

Chapter 10: Arrays and Pointers



This chapter expands on the topics of arrays and pointers and illustrates alternative ways of passing both single- and multidimensional arrays to functions. The objectives important to this chapter include

  • Discuss how to create and initialize arrays
  • Provide several examples which pass arrays to functions, where processing occurs
  • Compare single to N-dimensional arrays
  • Introduce C storage classes
  • Explain pointers to arrays
  • Discuss the five pointer operations
  • Show how arrays are used in a highly modular program

An array is composed of a series of elements of one data type. An array declaration follows the format

	type name[size];

where size tells the compiler how many elements the array contains.

The terms external, static, and automatic describe different C storage classes for variables. An automatic variable (or array) is defined inside a function. It is private to that function. An external variable (or array) is defined outside a function. This type of variable is public to all functions which follow, persists as long as the program runs, and are initialized to zero. A static variable (or array) can be defined inside a function; however, it retains its value between function calls.

An array can be initialized as follows:

type name [size] = { value1, value2,.....valueN} ;
/* No comma follows the last element */

Array values can be assigned regardless of storage class. However, you cannot assign one array to another, nor attempt to initialize an array using the list-in braces, except when declaring the array. This means the notation above is only to be used when initialization and declaration take place together.

Pointer to arrays is a complex subject. The following is a series of "equalities" and "inequalities" from our authors. These are not statements in a program, but logical comparisons to explain matters. First::

array_name == &array_name[0]

Both represent the memory address of the first array element.

Two additional equalities are:

array_name + 2 == &array_name[2]; 
/*This accesses the same address, that of array member 3 */
/* Yes, 3.  We start counting at 0.  */

where the array is of type int and

 *(array_name + 2) == array_name[2]; 
/* Accesses the same value, that of array member 3 */

An inequality to remember is:

 *(array_name + 2) != *array_name + 2

The first expression reads the value of array member 3, while the second returns the value of the first element of the array plus 2 (it does not modify the value stored in the array.)

Arrays can be passed to functions using array name or pointer notation. Array notation is as follows:

answer = sum(marbles, SIZE); /*Function call */
long sum(int ar[], int n) /*Function heading*/

Pointer notation is:

answer = sum(marbles, SIZE); /*Same function call */
long sum(int *AR, int n) /*Function heading */

C provides for five basic pointer operations. The programmer can:

  1. Assign an address to a pointer using the & operator.
  2. Find the value stored at an address using the * operator.
  3. Take a pointer's address.
  4. Increment a pointer.
  5. Find the difference between two pointers.

Multidimensional arrays are also known as an array of arrays. The format for a two dimensional array is

type name[row dimension][column dimension]

Two-dimensional arrays are initialized using the following format:

	type name[row][column] = {
	{row 0, col 0 },
	{row 0, col 1 },
	: :
	{row n, col m }

Note the required punctuation when using this format.

The relationship between array and pointer notation with multidimensional arrays can also be represented by equalities. Using an array named zippo, the equalities are:

zippo[0] == &zippo[0][0] == *zippo
zippo[1] == &zippo[1][0] == *(zippo + 1)
*zippo[0] == zippo[0][0] == **zippo
*zippo[1] == zippo[1][0] == *(*zippo + 1))

Passing a multidimensional array to a function can be done in three ways; where the two-dimensional function is perhaps the most interesting. In this instance, the function declaration, function call and the function heading are as follows:

void dub2(int junk [3][4]); 
/*Function declaration */

dub2(junk, 3); 
/* Function call*/

void dub2(int AR[][4], int size) 
/*Function heading */

In this instance, the call specifies an address and three rows; the function heading indicates an array of arrays of 4 ints.