Lecture 8:  Input and output parameters

 

Objectives of this lecture

q       Learn how to apply pointer variables to write functions than can return more than one result

q       Differentiate between call-by-value & call-by-reference

q       Differentiate between input and output parameters

 

Functions that return one result

q       Many functions receive one or more arguments and return only one result.

e.g.  double sqrt(double x);

          long int fact(int n);

double power(double x, double y);

q       These types of functions returns their result through the function name using the return statement.  For example, the following implements the factorial function:

 

long int fact(int n)

{       long int ans=1;

          int i;

          for (i=n; i>1, i--)

                   ans*=i;

          return ans;

}

q       The parameters in these types of functions are used to receive actual values (rvalues) from the main program (or calling functions)  they are therefore called input parameters.

q       These functions can only be called with variables that already have values assigned to them.  For example, the following main program calls the function fact above.

#include <stdio.h>

main()

{       int num;

          long int factorial;

          printf(”Type your number >”);

          scanf(”%d”,num);

          factorial=fact(num);

          printf(”The factorial of %d is %ld\n ”,num,

 factorial);

                             return 0;

}

q       The following diagrams show the values of the variables in both functions before, when, and after the function is called.

 

Before the function is called

fig_8_1.gif (3477 bytes)

When the function is called (before the return statement)

fig_8_2.gif (3463 bytes)

After the return statement

fig_8_3.gif (3497 bytes)

q       Notice that when the function is called:

factorial = fact(num);

The value (rvalue) of the input argument num is copied to the input parameter n.  This is called call-by-value.

 

Functions that returns more than one result

q       Some functions are required to return more than one result.  Example;  a function that converts time in seconds into hours, minutes and seconds.

q       Since the return statement can only return one result, it cannot be used in this case.

q       Our best option is to use output parameters.

q       In C, output parameters are declared as pointer variables as shown by the following example:


 

void get_time (int n, int *phr, int *pmin, int *psec)

{       *phr = n/3600;

          *pmin = (*phr % 3600)/60;

          *psec = n – *phr * 3600 - *pmin * 60;

}

q       In the above, n is an input parameter used to receive the time in seconds from the calling function;  phr, pmin, and psec are output parameters – pointer variables used to receive the address of the variables where output should be sent.

q       Notice the use of the derefencing operator ‘*’ to indirectly access the actual variables that are being assigned the output

    as in:            *phr = n/3600

q       It is wrong to write the above assignement as:  phr = n/3600 Why?.

q       The following main program shows how the function get_time can be called.

 

#include <stdio.h>

{       int num, hr, min, sec;

          printf(”Enter your time in seconds >”);

          scanf(”%num”);

          get_time(num, &hr, &min, &sec);

          printf(”%d seconds = %d hours %d minutes %d

   seconds\n”, num, hr, min, sec);

          return 0;

}

q       Notice that the function call:

Get_time(num, &hr, &min, &sec);

Passes the value (rvalue) of num to the function, but passes only the addresses (lvalues) of hr, min, and sec using the address of operator ‘&’.  The latter is called call-by-reference. 

q       The following diagrams show the status of the variables before, when and after the function is called.

 

Before the function is called

fig_8_4.gif (3898 bytes)

When the function is called (before executing any statement)

fig_8_5.gif (3974 bytes)

After the function is called

fig_8_6.gif (3901 bytes)

Exceptions: 

q       As explained in previous lectures, the exceptions to the above rules on input and output parameters are arrays (and strings). 

q       An array can only be passed as an output parameter (by-reference) even if the function is not going to change its values. 

q       However, with arrays, the ‘*’ is not required when specifying the function prototype.  We just use the array name followed by [] 

q       Also, the ‘&’ operator is not required when calling the function.  We just use the array name.

 

Functions that update (change) values of their arguments

q       Some functions are required to receive input and send output using the same parameters – This is usually referred to as update. 

q       Example of functions that perform update operation is the swap function:

           void swap(int *first, int *second);

q       Parameters that are used both for input and for output are called inout parameters.

q       In C, update is achieved using call-by-reference as described above.

Example:  The following program receives 4 float values and return them after removing the smallest from each value.

 

# include <stdio.h>

 

 


void remove_min(float *pfl1, float *pfl2, float *pfl3, float *pfl4);

 

main()

{  float fl1, fl2, fl3, fl4;

    printf("Enter four float values >");

    scanf("%f%f%f%f",&fl1, &fl2, &fl3, &fl4);

 

    printf("\nValues before removing the min : %.2f  %.2f  %.2f

             %.2f\n", fl1,fl2,fl3,fl4);

    remove_min(&fl1, &fl2, &fl3, &fl4);

    printf("Values after removing the min  :%.2f, %.2f  %.2f

              %.2f\n", fl1,fl2,fl3,fl4);

    return 0;

}

 

void remove_min(float *pfl1, float *pfl2, float *pfl3, float *pfl4)

{   float min;

    min = *pfl1;

    if (*pfl2 < min)

       min = *pfl2;

    if (*pfl3 < min)

       min = *pfl3;

    if (*pfl4 < min)

       min = *pfl4;

  *pfl1 = *pfl1-min;

  *pfl2 = *pfl2-min;

  *pfl3 = *pfl3-min;

  *pfl4 = *pfl4-min;

}

 

Tutorial Questions

1.  How would you call a function f with two input arguments a and b and three output arguments x,y and z.

2.  Assuming a and b are integers and x, y, & z are float, an appropriate function prototype for f is:

3.  Given the function call:  status = calc_volume(radius, &volume); What can you say about  radius and volume?

4.  An acceptable prototype for calc_volume in 3 above is…..

5.  Assuming that x is an integer array and the function call:  square_elements(x, size); is made.  What would be a possible function header?

6.  Using the array in 5, if the function call:  max = calc_max(x[0], x[1]) is made, what would be a possible function header.