Here’s a brain puzzle for you: Write a function that accepts a numeric array and returns the high and low values from that array. Can it be done?
Of course it can be done! I’ve yet to encounter a programming puzzle that can’t be cracked. Doing it well or doing it sloppy is the only issue.
What’s sloppy? Global variables.
Then how can you return two values from a function?
Sure, you could write a function that fills a structure with both high and low elements of the array. To make a structure work with a function, however, you have to declare it as a global variable. Sloppy.
The real solution is to use pointers. The function accepts three arguments: The array, of course, and then two addresses, one for the high value and the other for the low value. Here’s your sample code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 25 /* size of the array */
void hilo(int *a, int *h, int *l);
void fill_array(int *a);
int main()
{
int array[SIZE];
int x,high,low;
fill_array(array); /* assign random values to the array */
for(x=0;x<SIZE;x++) /* display array */
printf("%d\t",array[x]);
putchar('\n');
/* Get high and low values */
hilo(array,&high,&low);
printf("The highest value is %d.\n",high);
printf("The lowest value is %d.\n",low);
return(0);
}
/* Fetch the highest and lowest values in the array */
void hilo(int *a, int *h, int *l)
{
int x = 0; /* initalize x to zero */
*h = *l = a[x]; /* Initialize high/low values */
for(;x<SIZE;x++) /* x is already initialized */
{
if(a[x] < *l) /* new low value? */
*l = a[x]; /* set new low value */
if(a[x] > *h) /* new high value? */
*h = a[x]; /* set new high value */
}
}
/* Put random values 1 through 100 into the array */
void fill_array(int *a)
{
int x;
srandom((unsigned)time(NULL)); /* Seed the randomizer */
for(x=0;x<SIZE;x++)
{
a[x] = random() % 100; /* Get random int value 0 to 99 */
a[x]++; /* add one to equal 1 to 100 */
}
}
Here’s sample output:
74 71 28 5 21 52 86 67 12 94
58 58 74 10 98 95 29 82 31 76
99 21 37 57
The highest value is 99.
The lowest value is 5.
The meat of the code is the hilo() function, which uses dratted pointers to “return” the high and low values. Let me explain how that works.
int variables high and low are declared at Line 13. They’re regular int variables, not pointers. When those variables are passed to the hilo() function at Line 21, however, only their addresses (memory locations) are sent, thanks to the & prefix operator.
Remember: A pointer is a variable that stores a memory location. So the effect of passing the &high and &low memory locations is that the function receives those variables as pointers. The function definition shows the variables passed defined that way:
void hilo(int *a, int *h, int *l)
Within the hilo() function, both variables h and l represent the memory locations of the high and low variables. Those variables must be prefixed by the * operator to access the variables’ contents. The end effect is that the values assigned to *h and *l within hilo() directly affect the original variables in main(). There’s no need to “return” anything.
The a[x] variable doesn’t need to be prefixed by * within the hilo() function because it’s an array. The compiler is just being nice to you by letting you use array notation. Internally, it sees *(a+x).
The method of returning a value by using a pointer explains why some functions specify pointers as arguments, such as scanf(). That way the function directly affects a variable’s value and doesn’t need to return something. Or, in the case of hilo(), it returns multiple values.