5.11.4. Passing Arrays to Functions

To pass an array as a parameter to a function, pass it as a pointer (since it is a pointer). For example, the following procedure sets the first n cells of array A to 0.

  void zero(int* A, int n)
  {
    for(int k = 0; k < n; k++)
    {
      A[k] = 0;
    }
  }
Now to use that procedure:
  int B[100];
  zero(B, 100);
Notice that the argument, B, does not have any decoration. The array (or pointer) B is being passed, so just call it B.

No implicit copying

Since an array is passed as a pointer, the array's memory is not copied. The function uses the memory of the same array that is passed to it, and can change what is in that memory.

Passing an array by reference

Because arrays are already pointers, there is usually no reason to pass an array explicitly by reference. For example, parameter A of procedure zero above has type int*, not int*&.

The only reason for passing an array explicitly by reference is so that you can change the pointer to point to a different array.


Constant arrays

If a function only looks at the contents of an array, and does not change what is in the array, you usually indicates that by adding const to the parameter. For example, the following function firstPositive does not change what is in array A.
  // firstPositive(A,n) returns the first of
  // A[0], ..., A[n-1] that is positive.  If
  // none of them is positive, then it returns 0.

  int firstPositive(const int* A, int n)
  {
    for(int i = 0; i < n; i++)
    {
      if(A[i] > 0)
      {
        return A[i];
      }
    }
    return 0;
  }

Passing the array size

Recall that you cannot ask an array how big it is. An array is only a pointer to the beginning of the array, and information about how many items are in the array is not available from that.

Typically, you pass the size of an array along with the array. Functions zero and firstPositive, above, pass array A along with its size n.

When you do pass the size, it is important to understand whether you are passing the logical size or the physical size of the array. Most often, you find that you want to pass the logical size. But sometimes you want to pass both sizes, as separate parameters.



A notational issue

In order to accommodate programmers who understand arrays but do not understand pointers, C++ has a notation for array parameters. Function heading

  void zero(int A[], int n)
is equivalent to
  void zero(int* A, int n)
The former form has the advantage that it clearly indicates that A is an array, not a pointer to just one thing. For that reason, it is often preferred. But the two notations mean the same thing. (Indicating that a parameter is an array might allow a compiler to warn you if you use the pointer in a way that is not appropriate for an array.)


Exercises

  1. Write a definition of function sum(A,n) which takes an array if ints A and its logical size n and returns the sum of all of the integers in the array. Include a contract. Answer

  2. Write a definition of procedure cpy(A, B, n) that copies B[0, ..., n−1] into A[0, ..., n−1]. Make A and B each be arrays of ints. Include a contract. Answer

  3. Write a definition of function copyPositives(A, B, n), which copies all of the positive numbers in array B into array A, where B has logical size n.

    The values put in A should be in the same order as those in B, but if there are k positive numbers in array B then they must be put into A[0,...,k−1]. copyPositives should return the number k of values stored in array A.

    Make arrays A and B be arrays of ints. Include a contract.

    Answer

  4. Write a definition of procedure reverse(A, n), which reverses the order of the values in A[0, ..., n−1]. Make A be an array of longs. For example, if n = 3 and A contains

      A[0] = 10
      A[1] = 20
      A[2] = 30
    
    before calling reverse(A,3), then A contains
      A[0] = 30
      A[1] = 20
      A[2] = 10
    
    after calling reverse(A,3). Answer