EG2069 - Course Notes and Guides for Programming in C
Week 4


Simple functions

Instead of using the cc comand to compile your C programs, please use c89 instead. ANSI features required for defining functions below require this command. (n.b. If you learned C some time ago, or have used an old C textbook, note that the format of the functions used to be different.)

Before we look at some other simple function definitions, it's helpful to identify some functions that you have already used. In C, unlike mathematics, functions need not always return a result (ie, they return a void result)
so you will see function usage outside of expressions.
 
sin(x * 0.2) 
cos(y * y) 
printf("Hello world\n") 
scanf("%f %F",&x,&y) 
 
These functions and many others are not part of the C language and are defined in files elsewhere and coded into libraries provided by software vendors. You have already seen that in order to use sin and cos, an #include <math.h> line is required in your C program to describe how these functions are defined. Furthermore, a -lm switch is required when you use the cc command so that the body of the function (code used to calculate sines and cosines) are included when your program is being translated from C into machine code.

So far, the only function you have seen being defined is that of your program itself - main(). Main is the special function which is always looked for by Unix when it is told to run your program. For the scope of these exercises, it is enough to know little else about main. However, to define some other functions, extra information is required by C and supplied by you, the programmer.

Before we define our own function, let's look at what we'd have to do if sin wasn't already provided by Unix's environment. Just remember - things (variables AND functions) must be declared before being used. There are very few exceptions to this. The following is an example program. Just look at it for now.
 
#include <stdio.h> 

double sin ( double x ) 
{ 
  /* the C code goes here to approximate sin(x) using 
     some sort of series expansion. 
   */ 
  return ( best_result ); 
} 

main()  
{  
  double x, y, z[ROWS][COLUMNS];  
  int r,c;  

  for (r = 0; r < ROWS; r++)  
  {  
    for (c = 0; c < COLUMNS; c++)  
    {  
      x = ???????;  
      y = ???????;  
      z[r][c] = cos(2.0*x) * sin(y);  
    }  
  }  
}

 The text in red is the function definition of sin. Its body, apart from the return statement, consists only of a comment, since the actual code would obscure the example. Notice that it precedes the definition of main, the main program, because sin is called (used, as opposed to being declared) in it. So C has to know the shape (the number and type of arguments or parameters, and the type of the result, if any, before any use is made of a function.

You could define a two dimensional mathematical function as follows:
 
double func ( double x, double y ) 
{ 
  double z; 
  z = 1.0 / sqrt ( x*x + y*y ); 
  return ( z ); 
}
You could then possibly use this inside your main function:
 
p = 2.0 * sin( func( 5.0 * t, t * t ) + 2.0 );
This would be the equivalent of having executed:
 
p = 2.0 * sin( 1.0 / sqrt ( 5.0 * t * 5.0 * t + t * t * t * t ) + 2.0 );
Copy the program table.c from week 2 into a new file called func.c (remember the cp command to do this)
and define a function in func.c prior to main which will enable to you replace the expression in the
assignment where z is calculated. ie,
 
z = tabfunc (x,y);
A clue: fill in the missing bits:
 
double tabfunc (...... 
{ 
  ...... 
}
Compile and test func.c and paste a copy into your log books. Copy graph.c (last week) to a new file funcgraph.c and make similar changes there.

C functions can do a lot more than calculate numerical values. They are certainly used to specify repeated functionality in a program - you may use sin and cos, printf and scanf several times in one program. They can also be used to package up larger units of functionality. We'll consider one here: binding up the use of printf and scanf
to develop the effect of:
 
printf("Enter the starting and ending values for x: "); 
scanf("%lf %lf",&xstart,&xfinish);
within funcgraph.c so that it can be used for both x and y variables and will ultimately force the user to ensure that the starting value is less than finishing value. We'll call the function range and place its definition before
the main function in funcgraph.c.
 
void range ( char c, double *a, double *b ) 
{ 
  printf("Enter the starting and ending values for %c: ",c); 
  scanf("%lf %lf", a, b); 
}
Some things to note:

To call this for the x case, the following statement would be required:
 
range('x',&xstart,&xfinish);
Implement the function and its call for both xstart/xfinish and ystart/yfinish in your program funcgraph.c.
Test it and remember to paste a copy into your log book.

The function range doesn't quite do what it's advertised to do. It was suggested that the function repeatedly
ask the user to type starting and ending values if a > b (in the function definition). You will need a do - while
loop (see week 2's example of a "Please try again" loop when asking for non-zero inputs) and an if statement
making decisions with the following expression:
 
*a > *b
The * are necessary because of the way in which a and b are defined as parameters in the function definition of range. Don't forget to make use of your function range to replace the printf/scanf pairs in your main function.

Again, please remember to paste a copy of this program into your log books.


Back to main page
Author : Keith Halewood / Helge Nareid Current contact: Gorry Fairhurst G.Fairhurst@eng.abdn.ac.uk