CSC 161 Grinnell College Spring, 2013 Imperative Problem Solving and Data Structures

# Array Parameters

The concepts of passing arrays as parameters follows from the underlying philosophy of arrays in C. In order to understand array parameters, it helps to first review the mechanisms available for passing simple types (e.g., ints, doubles) to functions in C.

## Summary of Value and Reference Parameters

The lab on functions and parameters considered two basic types of function parameters:

Suppose variable number is declared as follows in a main function:

```double number = 123.45;
```

### Value Parameter Passage

In the following code, execution of the byValue function creates a new variable valueParm, and the call of the byValue copies a value to valueParm.

As an example, consider the following code:

```void byValue (double valueParm)
{
printf ("value of valueParm at start of byValue: %lf\n", valueParm);
valueParm = 543.21;
printf ("value of valueParm at end of byValue: %lf\n", valueParm);
}

int main ()
{
double number = 123.45;
byValue (number);
printf ("value of number after byValue completed:  %lf\n", number);
}
```

When this code is executed,

• number gets an initial value of 123.45
• when byValue is called,
• new storage is allocated for valueParm
• 123.45 is copied into valueParm
• the value of valueParm (123.45) is printed
• the value stored in valueParm is changed to 543.21 (but the value stored in number is unaffected)
• the new value 543.21 of valueParm is printed
• when byValue is done, valueParm is deallocated, and the value 543.21 is lost
• number remains 123.45, and this number is printed in main

Altogether, value parameter passage copies a value to the new parameter, work in the function works with the copied value, and changes to the new parameter do not affect the original variable (in main).

### Reference Parameter Passage

In the following code, execution of the byReference function stores the address (not the value) of the original variable. Using the address as a reference, changes to variable values refer back to the main variable.

As an example, consider the following code:

```void byReference (double *refParm)
{
printf ("value of valueParm at start of byValue: %lf\n", *refParm);
*refParm = 543.21;
printf ("value of valueParm at end of byValue: %lf\n", *refParm);
}

int main ()
{
double number = 123.45;
byReference (&number);
printf ("value of number after byValue completed:  %lf\n", number);
}
```

When this code is executed,

• number gets an initial value of 123.45
• when byReference is called,
• refParm is given the address of variable number
• the value in the location reference by refParm (123.45) is printed
• the value at the location reference by refParm is changed to 543.21 (i.e., the value stored in number is changed)
• the new value 543.21 referenced by refParm is printed
• when byValue is done, valueParm is deallocated, but the changed value in number remains
• number contains 543.21, and this number is printed in main

## Array Parameters

In C, the declaration

```double numberArr [5] = {43.7, 23.1, -56.2, 98.6, -40.0};
```

allocates space for 5 double precision numbers and initializes those values. The variable numberArr refers to the address of the first array element. From a compiler's perspective, a reference to the variable numberArr usually is equivalent to the expression &numberArr[0]. (Documentation lists three exceptions, as noted in the given link.)

Since numberArr is actually an address, parameter passage for arrays is by reference — without specifying a ampersand &, the reference to the array is passed to the function.

As an example, consider the following code:

```#include <stdio.h>

/* illustration of parameter passage of an array */

void arrFunc (double arrayParm[])
{
int i;
printf ("values of array at start of function: ");
for (i = 0; i < 5; i++)
printf ("%8.2lf", arrayParm[i]);
printf ("\n");
arrayParm[1] += 100;
arrayParm[3] += 300;
printf ("values of array at end of function:   ");
for (i = 0; i < 5; i++)
printf ("%8.2lf", arrayParm[i]);
printf ("\n");
}

int main ()
{
double numberArr [5] = {43.7, 23.1, -56.2, 98.6, -40.0};
arrFunc(numberArr);
int k;
printf ("values of array at end of main:       ");
for (k = 0; k < 5; k++)
printf ("%8.2lf", numberArr[k]);
printf ("\n");

return 0;
}
```

When this program is run, initial values are stored in the numberArr array. When function arrFunc is called, the base address of the numberArr array is copied to the arrayParm parameter, but the values within the are are not copied. Thus, array references within the arrFunc function refer to the original array — there is not another copy of the array.

The resulting output from this program follows:

```values of array at start of function:    43.70   23.10  -56.20   98.60  -40.00
values of array at end of function:      43.70  123.10  -56.20  398.60  -40.00
values of array at end of main:          43.70  123.10  -56.20  398.60  -40.00
```

Note that the changes to array elements 2 and 4, made within the function, are record in the main array.

### Observation

As a secondary observation, note that an array variable (e.g., numberArr) contains information about where the array begins. However, the array does NOT contain information about how long it is or where it stops. Thus, in the sample program, the programmer had to remember that numberArr was declared with 5 elements, and this information was hard coded into the program in both arrFunc and main.

If a function will be called with several arrays, it is common for an extra parameter (the array length) to be added, so the function will know how many array elements might be involved in processing.

## Feedback Welcome

Development of laboratory exercises is an interative process. Prof. Walker welcomes your feedback! Feel free to talk to him during class or stop by his office.