Book Cover

Introduction to Scientific Programming
Computational Problem Solving Using:
Maple and C
Mathematica and C

Author:
Joseph L. Zachary
Online Resources:
Maple/C Version
Mathematica/C Version

Arrays Tutorial

In this tutorial, you will experiment with arrays in C as discussed in Chapter 17. You will be using some example programs in this laboratory. You can use your Web browser to view or download them as you prefer.

As programs become larger and more complicated, it becomes increasingly difficult to manage the data. Variable names typically become longer to ensure their uniqueness. And, the number of variable names makes it difficult for the programmer to concentrate on the more important task of correct coding.

Arrays provide a mechanism for declaring and accessing several data items with only one identifier, thereby simplifying the task of data management.

Why Use Arrays?

Any collection of homogeneous data (data of the same type) is well-suited for storage in arrays. Think for a moment of some information that might lend itself towards storage into an array.

Click here for some array data examples

If you still doubt the usefulness of arrays, consider this. You are given the task of reading the entire Salt Lake City telephone directory in order to provide an on-line lookup service for the directory assistance operators. With the programming skills you have learned thus far, arrays are the only practical way to load the thousands and thousands of telephone numbers.

Imagine the alternative: What would it be like if you had to declare a different variable to contain each name and number in the phone book?

An Array Example

Take a look at array1.c. This program prompts the user for and reads ten numbers, and then prints them all back out. What is clumsy about this program?

Click here for the answer

The program cries out to be simplified by a for loop to repeat the statements

  printf("Please enter an integer: ");
  scanf("%d", &n0);

ten times over, and by using another for loop to repeat the statement

  printf("%d\n", n0);

ten times over. Unfortunately, this is not possible (at least without arrays!) Why not?

Click here for the answer

By using an array of ten elements to store the input, instead of ten distinct variables, we can vastly shorten the program. Take a look at array2.c.

Does this convince you of the utility of arrays? If not, consider what changes would be required to ``array1.c'' if you wanted to read 100 numbers. Compare that to the changes required for ``array2.c'' to accomplish the same thing.

Array Details

Let's consider ``array2.c'' to get a better feel for how arrays are declared and used. Here are a few questions to consider.

  1. How can you tell that ``n'' is an array?

    Click here for the answer

  2. How can you read from or write to an array element?

    Click here for the answer

  3. How could you change this program so that it read and printed out 12 numbers instead of 10?

    Click here for the answer

  4. Isn't there an easier way to arrange for such changes?

    Click here for the answer

Take a look at array3.c. How have we improved upon ``array2.c''?

Click here for the answer

Array Bounds

Let's go back to ``array2.c'', in which the array bounds should now be 12. With the declaration of ``n'' as it is, the low bound of ``n'' is 0, and the high bound is 11. (The low bound of a C array is always 0.) What do you suppose will happen if you attempt to access an array location that is not in the range 0-11? Change the program (by changing the range of one of the for loops) and find out.

Click here for the answer

Array Parameters

An array, like any other kind of value in C, can be passed as a parameter to a function. In a better world that is all we would have to say about array parameters, since you already know about integer parameters and floating-point parameters. Unfortunately, array parameters in C do not behave the way that beginning C programmers would expect.

So that you can understand what I am talking about, take a look at arraydemo.c.

Read the program carefully, and notice that there are three function calls (two to ``modifyInt'' and one to ``modifyArray'') in the main function. Very carefully try to predict what will be printed out when you run the program. Then compile and run the program and see if your intuition is correct.

Here's an explanation for what went on.

  1. In the first call to ``modifyInt'', we are passing the value of an integer variable as the parameter. Recall that C uses call-by-value, which means that the formal parameter in ``modifyInt'' (n) contains the value of the actual parameter (x), but has nothing more in common. So when the value of ``n'' is changed, there is no effect on ``x''. (There's nothing new going on here--we've talked about this before.)

  2. In the second call to ``modifyInt'', we are passing the value of an integer array element as the parameter. Since an element of an integer array behaves identically to a simple integer variable, we would expect this case to behave just like the previous one. And, in fact, it does.

  3. In the call to ``modifyArray'', we are passing the entire integer array as an parameter. You might reasonably assume that the entire array would be copied during the function call, so that any modifications to the ``n'' made by ``modifyArray'' would not be visible in the original version ``y''. (After all, this is what happened in the first two cases.) But in this case, as you can see, the assignment to ``n[0]'' in ``modifyArray'' results in a change to ``y[0]'' in the main function. This seems like an inconsistency. What is going on?

If this seems like an inconsistency, it is because it is an inconsistency! When you pass an entire array as a parameter in C, nothing is copied. Instead, the address in memory of the actual array parameter is passed up to the function. In effect, the formal parameter becomes another name for the actual parameter, and any modifications made to the formal parameter are actually made in the original parameter.

In our example, when we call ``modifyArray'' we are passing the address of ``y''. So the assignment to ``n[0]'' in ``modifyArray'' is actually an assignment to ``y[0]''. This is known as ``call-by-reference,'' which is how all parameter passing is done in Fortran, and how var parameters are passed in Pascal.

This difference between array parameters and other kinds of parameters may be confusing. Can you think of a good reason for passing array parameters in this way?

Click here for the answer

A Real Example

Suppose that we want to write a function to add up the elements of an array of integers. How many parameters should such a function take, and what should it return?

Click here for the answer

Take a look at arrayadd.c, which implements exactly such a function.

Here are a few things to notice about this program.

  1. First look at how the array parameter ``A'' of the function ``addArray'' is declared. What is unusual about it?

    Click here for the answer

  2. Why is the size immaterial?

    Click here for the answer

  3. What's nice about the fact that the declaration of the formal parameter doesn't need to contain the array size?

    Click here for the answer

  4. Now took a look at the main program. Do you see anything interesting?

    Click here for the answer

How it Works

You might be curious about how a function can get by knowing only the address of the beginning of an array. If you're not curious, you can skip right over this part.

When you give an array name as a parameter to a function, C passes only one value. That value is a number that locates the beginning of the array in the computer's memory. This number is called a pointer. We call it a pointer, because, in effect, it points to the first element in the array. When we access the array by giving an index, the index we give locates the particular data cell relative to the array pointer.

Now you might wonder how C knows how far to offset from the array pointer if all it knows is the number of elements to offset. After all, the size of the elements in different arrays can be different.

Click here for the answer