Objects First


Arrays

If all we could do in a C program was identify single objects, then many programs would become extremely painful! For example, suppose we want to plot a graph with 100 points: if we had to make our declaration like this:

double x0, x1, x2, x3, x4, ..., x99;
double y0, y1, y2, y3, y4, ..., y99;
Then not only will our fingers become rather tired just creating the program, but we will become somewhat less than enthusiastic when someone asks us to change the program to handle a 1000-point graph. Fortunately, C allows us to declare an array:
/* Define a constant for the size of the array */
#define N   100

double x[N], y[N];
and to access elements of the array:
for(i=0;i<N;i++)
    y[i] = f( x[i] );
which places in the elements of the array, y, the value of f(x) evaluated at the points contained in the array, x.

The declaration of an array consists of an identifier or name followed by square brackets which enclose an expression giving the number of elements of an array. Since the number of elements is given by an expression, we can use declarations like:

int xy[N+1];
double y[M+5*N];
However, the expression must be able to be evaluated by the compiler, so that all components of the expression must be able to be evaluated when the program is compiled - there must be no unknowns! This means that the expression must be composed of constants: so that in the examples above, identifiers consisting of upper case letters have been used - the convention for symbols defined with #define directives.

Accessing Array Elements

Elements of arrays are accessed by using the name of the array followed by an expression in square brackets, eg
x[4]
a[j+1]
blocks[4*i+k]
table[f(i,j,k+m)]
This expression is called the array index. In the last expression, a function, f, has been invoked to calculate the array index: this example was chosen to re-iterate that the index is an expression and that any legal expression will be accepted. However, it should be obvious that the expression must produce an integer result: in the example, f must be an int with specification:
int f( some_type1 i, some_type2 j, some_type3 k );
Floating point expressions are not accepted by the compiler.

Index range

The declaration
Rectangle rects[N];
defines an array of N Rectangle objects. (The value of N will be supplied by a #define somewhere in the program.) The elements of rects are numbered from 0 to N-1. Thus the following expressions accessing elements of rects are sensible:
/* Give N a value so that the examples are concrete! */
#define N 20

Rectangle rects[N];

rects[0]
rects[3]
rects[9]
rects[i*j+k] /* i*j+k evaluates to 5 */
rects[N-10]
rects[N-1]
but the following are not:
rects[-1]
rects[N-21]
rects[N+20]
rects[N]
The last example causes the most problems for new C programmers: you must remember that C array indices start at 0. Thus for an array with N elements, the last elements has index N-1. It may help to think of the array index as an offset from the beginning of the array, so that the first element (at offset 0 from the beginning) is rects[0] and the last must be at offset N-1 - rects[N-1].

Warning

Unfortunately C never checks whether the array index is valid - either at compile time or when the program is running.

Thus expressions like rects[N] are happily accepted by the compiler. (C compilers usually make the assumption that programmers know what they are doing!) The results of running such programs are entirely unpredictable, since the space at the end of the array may have arbitrary data in it. The results from your program may even vary from one run to another as the space in which the compiler assumes the (N+1)th Rectangle object is stored may well have been allocated to some other object.

Initialisation of arrays

When a variable is declared, it may also be given an initial value, eg
int x = 45;
double y = 101.23;
char c = 'A';
When an array is declared, it may also be given a set of initial values:
int x[3] = {45, 0, 3 };
double y[5] = {1.,2.,4.,101.23,-34.3};
char c[4] = {'A','B','C','D'};
The initial values are provided as a comma separated list of values enclosed in braces - {}. This is particularly useful for setting up look-up tables in programs: for example a Date class might contain an array giving the number of days in each month:
int days_in_month[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
int days_to_first_of_month[12] = {0,31,59,90,120,151,181,212,243,273,304,334};

Multiply Dimensioned Arrays

There are many situations where we would like to construct tables (with rows and columns) or matrices with two dimensions. C allows us to declare arrays with more than one dimension by simply adding further dimensions in square brackets:

int a[N][M];
char c[N_ITEMS][LENGTH];
double m[N_ROWS][N_COLS];

Elements from these arrays are addressed or accessed with expressions that also have the second index in square brackets following the first:

a[i][j+1];
c[k][0];
m[0][N_COLS-1];

As before the index can be any expression that produces an integer result.

Cautions

There are some further traps that await you when using arrays:

The first two traps mean that, having defined

int b[N];
int c[M][P];

we can write

b

which is the address of b[0] and

c[3]

which is the address of the 4th row: remember that C indices start at 0, so that c[0] is the address of the first row of c.

These addresses are also known as pointers. We will meet pointers and all the traps they provide for you in a later section!

Arrays as arguments to functions

The normal way of passing an array to a function is simply to pass its name (equivalent to the address of its first element) when the function is invoked: thus if we had a function with specification:
double sum( double a[], int n );
Note the use of the empty square brackets [] to indicate a singly-dimensioned array of unspecified size. This allows us to write library functions which work on arrays of all sizes. In this example, we build a function that sums the elements of all singly-dimensioned double arrays, no matter how many elements they have.

The implementation is:

double sum( double a[], int n ) {
        double s = 0.0;
        int i;
        for(i=0;i<n;i++) s = s + a[i];
        return s;
        }
we might invoke this function:
double x[N];
for(j=0;j<N;j++) x[j] = j;
sum_ints = sum( x, N );

Comma expressions

We will deal with these further, but at this stage, let us just note that
expression1 , expression2
in C is a valid single expression - a so called comma expression. Thus
a[i,j]
is perfectly legal C but generates the address of the row indexed by the expression
i,j
not the jth element of the ith row!

Key terms

array
The usual term in computer languages for vectors, matrices, etc. All elements of an array have the same type.
array index
An identifier for an element of an array. In C, array indices are integers starting at 0.
comma expression
An expression containing a comma: exp1,exp2
exp1 is evaluated first, followed by exp2 and the whole expression has the value of exp2

Continue on to Loops Back to the Table of Contents
© John Morris, 1999