Functions are the mainstay of C; all high level operations use them. David Matthewman explains how they work.
The C programming language depends upon functions to an almost unhealthy degree. As I explained in the first of the series back in August, C has very few keywords. There is no PRINT statement, for instance, nor a DIM statement. These operations are instead carried out by functions: printf() and malloc() respectively.
Functions, while they may look similar to keywords, are actually separate pieces of C code. When the program encounters a function, it jumps to that section of code, executes it, and then returns to whatever it was doing before. Functions can be in the same piece of code as the main program or in a completely different program. Both printf() and malloc() are part of the core library of functions provided by the compiler as ready-compiled code. Any compiler conforming to the ANSI standard must provide these and a host of other functions in a standard set of files.
no = printf("Some text");
but which is not often of any interest. With the malloc() function, however, the returned value is all-important, being a pointer to the block of memory which it has reserved. Lose this, and there was little point in reserving the memory.
The fact that functions return a value leads on to the fact that they, like variables, have a type. The type of the function is the type of the returned value and can be anything that a variable can: int, char, pointer or whattever.
The return value is given in a return statement:
return whattever;
which leaves the function and sends the value of whattever back to the main program. You should usually ensure that a function returns some value, even if it is zero, otherwise the return value will be undefined which can cause problems if you accidentally refer to it.
This is not necessary with functions which have been declared void, as these are explicitly forbidden from returning values. These behave more like PROCs in BASIC and can be used when you are sure that no return value will be needed.
A function looks like this:
function_type function(var_list) { var_type variable1; ... statement1; ... statement63; ... return some_value; }
The list of variables var_list is a list of variable declarations:
(type1 var1, type2 var2, type3 var3)
and so on, however many the function takes.
The return statement does not need to be at the end of the function, nor need it be unique.
All the programs that we have seen so far have actually been one single, special function, main(). main() is the first function called whenever a program is run, and every program must have a main() function. Strictly speaking, main() has type int and should return a value, usually zero to indicate no errors. This is because the OS running the program may check this value to ensure that the program has run correctly, and OSs which do this will complain if the return value is not defined.
This naturally applies to the variables declared in the argument list of a function, which are local to the function. Even if the variable has the same name as a variable in main(), it will occupy a different address in memory and will be treated as a different variable. (Incidentally, this applies to other C constructions which use braces, such as loops and if statements which we shall cover soon.) This can often help - for instance you can use i as a general loop variable without checking that the program that calls the function does not use i as well - but can also confuse you if you start using variables with the same name for different purposes. The program may be able to remember that they are different, but can you?
It follows from all this that a variable declared outside from any function - including main() - is a global variable and can be 'seen' by the whole program. These may be necessary but are best kept to a minimum. Functions themselves are in effect globally-declared variables.
Fortunately, the compiler will usually detect if you declare a variable 'twice' when you shouldn't, for instance by declaring a local variable in a function with the same name as a global variable.
Note also that the multiply() and divide() functions avoid using the extra result variable by doing the calculation within the return statement.
Next issue variable passing will be looked at in more depth.
char error = 'n'; int add(int x, int y) { int result; result = x + y; return result; } int subtract(int x, int y) { int result; result = x - y; return result; } int multiply(int x, int y) { return x * y; } double divide(int x, int y) { if (y == 0) { error = 'z'; return 0; } return x / y; } main() { int arg1, arg2, sum, difference, product; double dividend; arg1 = 20; arg2 = 15; sum = add(arg1, arg2); difference = subtract(arg1, arg2); product = multiply(arg1, arg2); dividend = divide(arg1, arg2); return 0; }
Source: | Acorn User - 152 - February 1995 |
Publication: | Acorn User |
Contributor: | David Matthewman |