# Functions and Pointer Parameters

## Introduction

Today we reveal an important aspect of memory and parameter passing that has been mostly abstracted in your programming work so far. Namely, we show how to identify the memory address of a particular variable, which can be used as a function parameter to modify the variable's value outside that procedure.

• King: Sections 11.1-11.5, pp. 241-255

## Summary of Value and Address 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 `valueAsParameter` function creates a new variable `valueParameter`, and the call of the `valueAsParameter` copies a value to `valueParameter`.

As an example, consider the following code:

``````void
valueAsParameter (double valueParameter)
{
printf ("value of valueParameter at start of valueAsParameter: %lf\n",
valueParameter);

valueParameter = 543.21;

printf ("value of valueParameter at end of valueAsParameter: %lf\n",
valueParameter);
} //valueAsParameter

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

The stack model of computation reminds us that when this code is executed,

• `number` gets an initial value of 123.45
• when `valueAsParameter` is called,
• new storage is allocated for `valueParameter`
• 123.45 is copied into `valueParameter`
• the value of `valueParameter` (123.45) is printed
• the value stored in `valueParameter` is changed to 543.21 (but the value stored in `number` is unaffected)
• the new value 543.21 of `valueParameter` is printed
• when `valueAsParameter` is done, `valueParameter` 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`).

In the following code, execution of the `addressAsParameter` function stores the address (not the value) of the original variable. Using the address as the parameter, changes at the stored address refer back to the `main` variable.

As an example, consider the following code:

``````void
{
printf ("value of valueParameter at start of addressAsParameter: %lf\n",

printf ("value of valueParameter at end of addressAsParameter: %lf\n",

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

When this code is executed,

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

## Notes on Style

Pointers are not excessively difficult to master, but following a few stylistic guidelines will certainly help avoid some common errors and confusion.

First, when defining pointer variables, treat the asterisk (`*`) as part of the variable name, rather than the type. That is, because C requires each pointer variable to have its own asterisk, you put a space between the type declaration and the asterisk, rather than the asterisk and the name.

POOR: `int* p, q;`
BETTER: `int *p, q;`

The first example is stylistically poor because a careless programmer might either miss that variable `p` is in fact a pointer to an integer (though compiler warnings should nearly always fix this), or that variable `q` is NOT a pointer to an integer. The compiler knows the difference, but you should still write your code to be readable.

If both `p` and `q` were to be pointers, you'd need to write the following:

``int *p, *q;``

The BEST strategy is to avoid the potential for confusion altogether by declaring pointer variables and non-pointer variables separately:

``````int * p;
int q;``````

The extra space ensures the asterisk is clearly visible and does not get visually "glossed" by reading quickly and associating it with either the type or the variable name. This issue brings us to a second stylistic injunction.

Naming conventions help clarify the role of variables in your program text. Whereas variables should already have clear, noun-based names, like `area` or `balance`, appending a prefix `p` (when using "camel case") or `p_` (when using underscores) reminds us that these are pointers to such values. Alternatively, some programmers include "ptr" in the name. For example, `pUsableArea` or `p_final_balance` or `AreaPtr`. Names like these reinforce how they are to be used within the program (i.e., with asterisks for dereferencing when values are desired). Pick a style that works for you and then be consistent in your naming style.