functions

CS35: Programming and Problem Solving
Ray Ontko
Department of Computer Science
Earlham College

Why Functions?

Most of the programs we've seen or written so far were fairly small and simple. The entire program could be expressed in under 100 lines of code. But suppose we had a very large and complex programming task at hand. We could possibly write a long sequence of statements with nested loops and if statements where appropriate to handle our complex problem, but chances are we would have too many variables to keep track of, too many control structures to remember which ones we're in deep within the program, and too much complexity to have confidence that what we've written is correct. Even worse, because the variables, statements and control structures are highly interdependent, it would be difficult to break the task up among multiple programmers, so you'd be pretty much on your own. You need functions.

Functions allow us to break a large programming problem down into smaller, more tractable problems. In some instances, we wish to break a problem into distinct sections, where each section is simply a smaller part of the whole. In other cases, we identify parts of a problem which are in fact repeated in several different parts of our proposed solution, or possibly even reusable in similar situations in other programs.

Functions allow us to reduce a problem to a small enough size that we can focus our efforts on making each part well defined and correctly implemented. By assembling our complete solution from such small, well-defined, and correctly implemented parts, we can create programs that are not only more complex but have confidence that they are correct, despite their complexity. Because of this, functions provide us leverage in dealing with large, complicated problems; they are essential to building anything larger than trivial programs.

Functions in C

In C, functions are declared, and functions are defined. Further, values are passed to and from the function via parameters.

The declaration for the function tells the compiler what the return-type is for the function (what type of value it returns, e.g., int, float, etc.), and the number and data-types for each of the values passed as parameters (which appear between the "(" and ")"). The declaration tells the compiler what it needs to know in order to correctly handle a call to the function, and any arguments passed.

The definition for the function is where you define the inner workings of the function. Any statements which make up the action to be performed by the function are part of the definition of the function, and are executed when the function is called. The parameters of the function receive their values from the arguments passed in the call to the function.

Function Declaration

For each function, we need to specify the data type for the return value and the data type for each of the arguments. We specify this early in the program file so that when we compile the program, the compiler will know what to expect for calls to that particular function. Unless you declare the function, the compiler will assume that the return value and any parameters are of type "int".

The format for a declaration:

data-type function-name ( data-type parameter-name , ... ) ;

Note the trailing semicolon.

Here are some sample declarations:

float payment( float principal , float rate , int months ) ;
void print_grade( float grade ) ;

Note that the names of the parameters are irrelevant in the function declaration. The following declarations are equivalent to those listed in the above sample:

float payment( float , float , int ) ;
void print_grade( float ) ;

Remember, the function declaration must appear before the first call to the function in the program file.

Function Definition

Of course, we must define the function itself. With C, the function may be defined in the same file with the function that calls it, or it may be defined in a separate file. In either case, the format of the definition is the same:
data-type function-name( data-type parameter-name, ... )
{
  statement ; ...
}

The statements which perform the actions of the function appear between the "{" and "}".

If the function returns a value, it does so using the return statement.

return value ;

Here, then, is a more complete example. The "payment" function calculates the payment amount for a loan, given the principal amount, the percentage rate of interest, and the number of months for the loan. Note that the funtion returns a float value (the amount of each monthly payment) and that it accepts three parameters, "principal", "rate", and "months".

#include <stdio.h>

float payment( float , float , int ) ;

main()
{
printf( "payment = %.2f\n" , payment( 6000.00 , 8.0 , 60 ) ) ;
}

float payment( float principal , float rate , int months ) 
{
float mrate ;
float low ;
float high ;
float balance ;
float pmt ;
int m ;

mrate = 1.0 + ( rate / 100.0 ) / 12.0 ;
low = principal / (float)months ;
high = low + principal * mrate ;

pmt = ( high + low ) / 2.0 ;
while ( ( high - low ) > 0.005 )
  {
  balance = principal ;
  for ( m = 0 ; m < months ; m ++ )
    {
    balance *= mrate ;
    balance -= pmt ;
    }
  if ( balance < 0.0 )
    high = pmt ;
  else
    low = pmt ;
  pmt = ( high + low ) / 2.0 ;
  }
return pmt ;
}

The output from the above program, if you're curious:

payment = 121.66

Passing Values to Functions

You can pass a value to a function by giving an expression representing that value as the argument to the function in the function call. For example, "print_grade( 100.0 ) ;" passes the value 100.0 to the print_grade function as that function's first (and only) parameter. "print_grade( final_grade ) ;" passes the value of the variable final_grade.

A value passed to a function is used to initialize the parameter variable in that function at the time the function is invoked. For example,

#include <stdio.h>

void print_grade( float grade ) ;

main()
{
  float p2 = -23.5 ;

  print_grade( 100.0 ) ; 
  printf( "\n" ) ;
  print_grade( p2 ) ;
  printf( "\n" ) ;
}

void print_grade( float grade )
{
  if ( ( grade > 90.0 ) && ( grade <= 100.0 ) )
    printf( "A" ) ;
  else if ( ( grade > 80.0 ) && ( grade <= 90.0 ) )
    printf( "B" ) ;
  else if ( ( grade > 70.0 ) && ( grade <= 80.0 ) )
    printf( "C" ) ;
  else if ( ( grade > 60.0 ) && ( grade <= 70.0 ) )
    printf( "D" ) ;
  else if ( ( grade > 0.0 ) && ( grade <= 60.0 ) )
    printf( "NP" ) ;
  else
    printf( "error: unknown grade %f\n" , grade ) ;
}

In the program fragment above, "grade" has the value 100.0 the first time "print_grade" is called, and -23.5 the second time. The output from the program:

A
error: unknown grade -23.500000

Copyright © 1999, Ray Ontko (rayo@ontko.com).