Consider the problem of calculating statistics about a collection of data. Suppose the data is in an array and you want to calculate the mean and maximum values. These could be calculated by separate methods but it would be more efficient to calculate both with one pass through the data.
void meanMax( double a[], int size, double mean, double max);
The problem here is that assignments to mean and max inside the method
are to the copies and the originals in the calling method remain
unchanged.
One solution would be to make the mean and max global variables declared outside of any function. This works very well for small programs but does not "scale up" to larger programs where different programmers work on various parts and tend to want to use the same global variables.
If only one variable needs to be set then the function/method can return that value.
Another solution is to pass pointers to the variables which need to be set
and remember to allocate space for them in the calling method.
Allocating space for strings is particularly an issue that C programmers
need pay attention to.
Most C programmers first encounter this problem with the scanf input
function. Consider the problem of reading a name and a list of attributes
associated with that name. If these both make sense to be part of one
object (struct in C) then we can allocate that struct in the calling
function and pass a pointer to it and the parts of the object are
initialized in the function. An alternative would be to allocate space
for the object in the function and return a pointer to it. This requires
dynamic space allocation which is more expensive than "automatic"
allocation in the caller.
Note that strings, arrays and lists in C are represented by pointers.
Passing one of these as a var-parameter to a function to be set means
that you pass a "pointer to a pointer" (** in C). One way to do this
is to pass an array to the function:
Getting back to reading a name and a list of attributes.
void meanMax( double a[], int size,
double* ptrMean, double* ptrMax);
and inside the method set *ptrMean =
scanf("%f %f", &mean, &max);
It is very common to forget the ampersands.
double stats[2];
calcStats( stats );
// now stats[0] is mean, and stats[1] is the max
This approach works well with Java as well which does not have ** pointers
to pointers (except arrays/objects containing objects).
char name[SIZE];
Node * head;
getNameAndAttributes( &name, &head);
Note that the first parameter is char** and the second is Node**.
An alternative would be:
char* name;
Node * head;
getNameAndAttributes( &name, &head);
Inside the function use strdup(buf) to create space for the name.