ES101 - Lesson 8 : Functions with Pass-By-Reference

From Embedded Systems Learning Academy
Revision as of 18:31, 16 October 2012 by Charley (talk | contribs)

Jump to: navigation, search

Objective

You will learn the basics of pointers, which are used in combination with the functions.

Pass-by-value type of functions pass just the value of the variables into a function, but with a simple change, you can use functions that accept pass-by-reference type of variables. This is a very powerful concept that will allow your functions to change the values outside of its scope.

Pass By Reference

Pass by reference provides a mean to provide input to functions by specifying a memory location, which allows the function to modify caller's variables. In other words, instead of just merely giving a value, you pass the pointer of variable(s), and the pointer points to the memory address where the data is stored. The values are then accessed by using the * operator inside the function, which is called the dereference operator. Students often get confused with & and * symbols. & refers to the memory address whereas as * refers to a value stored at this memory address.

// Declare foobar() that takes pointers of int and float
void foobar(int *intInput, float *fpInput);

int main(void)
{
   // We can no longer do this since we have to provide
   // addresses of some variable
   foobar(1, 1.2);        // ERROR!
   foobar(anInt, aFloat); // ERROR!

   // Pass variable addresses to foobar()
   int anInt = 1;
   float aFloat = 2.3;
   foobar(&anInt, &aFloat);

   // After function call to foobar(): anInt and aFloat are zero
   printf("Variables now: %i, %f\n", anInt, aFloat);
}

void foobar(int *intInput, float *fpInput)
{
   // intInput and fpInput are addresses, so to read/write
   // the values at these addresses, we must use * (dereference)
   // operator
   printf("Input was: %i, %f\n", *intInput, *fpInput);

   // Modify the inputs:
   *intInput = 0;
   *fpInput  = 0;
}

Similar to how you provided address to scanf function, you must provide address of variables to foobar(), when calling the function otherwise a compiler error will be encountered as seen by first two calls to foobar() in the figure above. The third call to foobar() shows correct function call, which passes addresses of anInt and aFloat variables. The main() function called foobar() with values as 1 and 2.3, and, after foobar() returns, the values of the variables are set to 0 by foobar().

Passing Arrays to a Function

Passing arrays to a function is not much different than passing a pointer. This is because to pass an array to a function, you actually still pass the address of its first element. Arrays usually consist of large number of elements; therefore, passing array pass-by-value would be time consuming because each elements needs to copied. To address this issue, the address of first element of the array is passed to functions (pass-by-reference). See the examples below for illustration.

void getName(char *charArray);
float getAverageOfFloatingPointArray(float *floatArray, int elements);

int main(void)
{
   char userName[50];
   getName(userName);
   printf("Your name is: %s\n", userName);

   float samples[4] = {1.1, 2.2, 3.3, 4.4};
   float average = getAverageOfFloatingPointArray(samples, 4);
   printf("Average = %f\n", average);
}

void getName(char *charArray)
{
   printf("Enter your name: ");
   // No & symbol needed since the pointer is already the address
   scanf("%s", charArray);
}

float getAverageOfFloatingPointArray(float *floatArray, int elements)
{
   int i = 0;
   float sum = 0;
   for(i = 0; i < elements; i++)
   {
      sum += floatArray[i];
   }

   float average = sum / elements;
   return average;
}

Notice that when main() calls the getName() and getAverageOfFloatingPointArray() functions, it just passes the arrays without the & operator; this is because the array name itself is the address of the first element of the array. The one problem is that getAverageOfFloatingPointArray() will not know how big the array is, so another parameter, elements, is given, such that this function can know how many elements there are in the array. Again, this is similar to pass-by-reference, except how the arrays are passed. One last thing to note is that when the getName() function tried to do scanf, it did not need to pass the address of charArray, because the charArray is the address to begin with. Furthermore, notice that the floatArray was accessed simply by using index locations.