Lecture 12: Modular Programming II:

functions with input and output



In the previous lecture (aula 11) we have seen functions that are not accepting parameters and are not returning values. These are simple functions. Now we are going to look at functions that are accepting parameters and functions that are producing return values.

Parameters to pass to functions

We can pass parameters to functions. The functions can then work with these parameters. Inside the function, the parameters work like normal variables. In C the parameters the functions expects are put after the name of the functions inside parenthesis. For a function that doesn't have output (or in other words, "returns type void"):
A function with input (but without output):
 void functionname(parameter_list)
 {
 <local variable declarations>

  instructions;
}

The variables on the parameter list are declared in the same way as the normal variables of a program or functions, namely we have to specify the type of each parameter. Inside the functions we can use the parameter as if it were a normal variable. We can calculate with it, use it in conditions, and even change its value. It doesn't have to be initialized, though, because the initialzation comes from the calling program.

As an example, the following program will calculate and show the square of a variable x: Note the way the parameter r is declared and used.
program code


#include <stdio.h>

void write_square(float r)
{
  float y;

  y = r*r;
  printf("The square of %f is %f", r, y); 
}

void main()
{
  float x;

  x = 4;
  write_square(x);
  write_square(3.0);
}

output


The square of 4.0 is 16.0
The square of 3.0 is 9.0

As seen in the program above, the functions with parameters can now be called with a variable, as in write_square(x) or with a constant.as in write_square(3.0).

Another example, that uses two parameters:
program code


#include <stdio.h>

void write_sum(int i1, i2)
/* write the sum of i1 and i2 */
{
 int j;

  j = i1+i2;
  printf("The sum of %d  and %d is %d',
    i1, i2, j); 
}

void main()
{
  int x, y;

  x = 4;
  y = 5;
  write_sum(x, y);
  write_sum(3, 4);
}

output


The sum of 4 and 5 is 9
The sum of 3 and 4 is 7
Note that we have to pass to the function the type of information that is expected. In this case, the function expects two integers, so we should pass two integers (x and y).
Finally, an example with a parameter list of mixed types. Variables to be declared in the parameter list are separated by a comma ,
program code


#include <stdio.h>

void write_N_times(float r, int n);
  /* Will write n times the real r */
{
  int i;

  for (i= 1; i<=n; i++)
    printf("%10.3f\n", r);
}

void main()
{
  write_N_times(3.0, 4);
}

output


3.000 
3.000
3.000
3.000


Functions with output

Functions can return an output value. The type of the returning value has to be specified at the moment of declaring the function before the name of the function
 
 type FunctionName(parameter_list)
  {
  <variable_list>

   instructions;
 }

Functions with output and with input
parameters

Somewhere in the instructions we have to specify a returning value. We do this with the reserved word return
 

 return (value)

Obviously, the value has to be of the same type as the type of the declaration of the function.
Note that the return instruction immediately exits from the function and the instructions after return will not be executed.

  double square(double r)
    /* will return the square of of the parameter r */
  {
    r = r*r;
    return (r);
  }

At the place where the function will be called, we can assign this value to a variable (of the same type as the returning value of the function!), for example

  y = square(3.0);

use it as part of an expression, for example

  y = 4.0 * square(3.0) + 1.0;

or use it in another function, for example

  printf("%f", square(3.0));


A full example:

program code


/* example with parameters */
#include <stdio.h>

double square(double r)
  (* will return the square of of the parameter r *) 
{
  r = r*r;
  return(r);
}

void main()
{
  double x, y;
  x = 4.0;
  y = square(x);
  printf("The square of %f is %f\n", x, y);
  printf("The square of %f is %f\n", 3.0, square(3.0));
}

output


The square of 4.0 is 16.0
The square of 3.0 is 9.0
What is happening in the instruction y = square(x) is the following:
  1. The value of the expression inside parenthesis is calculated. In this case this is simple. It is the value of x, namely 4.0;
  2. This value (4.0) is passed to the function square(). Inside the function:
  3. A temporary variable with name r is created.
  4. The value passed to the function is attributed to this variable r. Effectively an instruction r=4.0 has happened.
  5. r=r*r; The new value of r is calculated. r now has the value 16.0.
  6. return(r); The value of the expression inside parenthesis (16) is passed back to the calling instruction (y=square(x);); where it will be used further.
  7. In this case, the value returned (square(4.0) which is 16.0) will be attributed to y. The instruction y=square(x); effectively becomes y=16.0;
  8. The next line (printf...) shows the values of the variables x and y. (Note that the value of x has remained unchanged and is still 4.0. later, in the lecture on "passing by value / passing by reference" will we see that it is not necessarily like that.)


Note that in C we don't have to use the value that is coming back from the function. We could, for example write in our function main()
  square(3.0);
This construction is very confusing and should be avoided when possible in structured programs; a value returned by a function should, in principle, be used on the receiving side.


Why?

Now the big question is "why?". Why write functions if we can do the same thing with normal lines of instructions? Indeed, the first languages (for example BASIC) didn't have the possibility to write functions and still we could write programs to solve any problem with it. There are however three important reasons why to use modules.


Quick test:

To test your knowledge of what you have learned in this lesson, click here for an on-line test.

Peter Stallinga. Universidade do Algarve, 8 November 2002