Arrays

(read ch. 7)

Arrays are used to hold lists, tables, or multidimensional tables of data. The size of the list, table, ... is fixed and must be known in advance.

Example: an array holding the number of fish I've caught each day this week:

5 0 0 1 0 2 3

Example: a string is just an array of characters:

'I' ' ' 'a' 'm' ' ' 'a' ' ' 's' 't' 'r' 'i' 'n' 'g' '\0'

One-Dimensional Arrays

A one-dimensional array is simply a list of a fixed size. The type of data held in the array (int, float, char, etc) is called the base type of the array.

An array variable called ArrayName containing data of type basetype of size size (an int) is declared as follows:

basetype ArrayName[size];

Examples:

   int FishWeek[7]; /* to keep track of my daily catch */
   char str[41]; /* a string of length 40 */

It is good program design to define a constant for the size of the array. Programs need to know the size of the array when processing it, so changing the size of an array in a program will require changes in many places unless a constant is used for the size, and that constant is used every time the array size is needed.

Example - an array for keeping track of student grades:

const int CLASS_SIZE = 27;

float classgrades[CLASS_SIZE];

Now I can easily reuse a gradebook program that uses this array, even if next year's class is larger or smaller than this year's.

The data stored in the array (often called the elements of the array) is accessed by index numbers 0 through one less than the size of the array.

Example - given the previous declaration of classgrades:

Example: printing all of the grades in the array classgrades:

  int count;

  for (count = 0; count < CLASS_SIZE; count++) {
    printf("The grade is %f\n", classgrades[count]);
  }

Example: see ~taw2/pub/array1.c.

Trying to access an array using too large an index is a common mistake in C programs.

Example - given our previous declaration of classgrades:

  classgrades[100] = 89.3;

will not cause a compilation error. The C compiler does not do bounds checking. However, such a mistake in a program will cause it to crash or misbehave in unpredictable ways.

The name of an array variable by itself (with no []) means the address of the array. Any parameter of an array type is automatically a pass-by-address parameter.

Example: see ~taw2/pub/array2.c.

Not all positions in an array need be filled. For example, I could just declare classgrades to be of size 100, and then I can reuse my gradebook program every year without modifying it. However, this wastes some memory, and my program still needs to keep track of how much of the array actually contains useful data.

When a function takes a parameter of an array type, the size of the array need not be specified in the function prototype and function definition. This is useful for writing functions that can handle arrays of varying sizes. Such functions still need to know how big the array is (or at least how much of it is used). This is done by passing an int parameter specifying how much of the array contains valid data.

Example: see ~taw2/pub/array3.c.

Another useful operation is sorting an array (for example, an array of scores for assigning grades). One reasonable sorting algorithm (called selection sort) orders an array by repeatedly finding the smallest (or largest) element in the array and putting it in the appropriate spot.

Example: see ~taw2/pub/array4.c.

Return to Table of Contents

Multidimensional Arrays

Multidimensional arrays are just arrays that contain other arrays. Think of them as tables or layers of tables.

Format of declarations:

basetype ArrayName [size_1][size_2];

declares a two-dimensional array variable called ArrayName containing data of type basetype in size_1 rows and size_2 columns.

Example - a multiplication table with four rows and 6 columns:

#define ROWS 4
#define COLS 6

int multTable[ROWS][COLS];
see ~taw2/pub/array5.c.

Return to Table of Contents

Declaring New Types

The C keyword typedef can be used to give a name to a particular array type (or any other type). This saves typing and helps in avoiding errors if arrays are passed as parameters, or if multiple variables of the same array type are required.

Example:

#define CLASS_SIZE 27
typedef float booktype[CLASS_SIZE];
/* now, booktype is a type - the type of
   arrays of floats of size CLASS_SIZE */

  /* a variable of this type: */
  booktype classgrades;

  /* equivalent to:
  float classgrades[CLASS_SIZE];
  */

  /* in a function prototype: */
  void sort(booktype, int);

This is safer (and better programming style) than using an explicit array type. Type definitions can also be used to define other kinds of types in C. Example:

typedef int sizetype;

This makes sizetype another name for int. The prototype for sort can now be written:

void sort(booktype, sizetype);

Advantage: the type names give an idea of how the parameters are used.

Return to Table of Contents

Initializing Arrays

The contents of an array can be initialized when the array is declared by listing the initial contents in { }.

Example:

#define NUM_DAYS 7
typedef int catchtype[NUM_DAYS];

catchtype mycatch = {5, 0, 0, 1, 0,  2, 3};
/* now, mycatch is an array variable with all
   7 positions initialized to the above values */

If the number of values listed in the declaration is smaller than the size of the array, the "left over" array positions are initialized to 0 (for arrays of numeric types).

Example:

  catchtype mycatch = {0};

initializes all array positions to be 0.

Multidimensional arrays can be initialized by giving a list of lists of initial values (one for each row).

Example:

#define ROWS 2
#define COLS 3

typedef int tabletype[ROWS][COLS];

tabletype table = { {1, 2, 3},
                    {4, 5, 6} };

Return to Table of Contents

Advice on Using Arrays

Return to Table of Contents