Procedures and Functions

 

Contents


Procedures and Functions

A function is a section of code that has some separate functionality or does some function that will be reused over and over again.

As a basic example, if you are writing code to print out the first 5 squares of numbers, then the first 5 cubes, then the next 5 squares again, instead of writing something like

for(i=1; i <= 5; i++)
{
printf("%d ", i*i);
}
for(i=1; i <= 5; i++)
{
printf("%d ", i*i*i);
}
for(i=1; i <= 5; i++)
{
printf("%d ", i*i);
}

which duplicates the same loop twice. We may want to separate this code somehow and simply jump to this code when we want its functionality.

This is what precisely functions are for.

More on functions

A function is like a black box. It takes in an input, does something to that input, then spits out an answer.

Note that a function may not take any inputs at all, or it may not return anything at all. In the above example, if we were to make a function of that loop, we may not need any inputs, and we aren't returning anything at all (Text output doesn't count - when we speak of returning we mean to say meaningful data that the program that used the function can use).

We have some terminology to refer to functions:

* A function, call it f, that uses another function g, is said to call g. For example, f calls g to print the squares of ten numbers.
* A function's inputs are known as its arguments
* A function that wants to give f back some data that g calculated is said to return that data. For example, g returns the sum of its arguments.

Writing functions in C

It's always good to learn by example. Let's write a function that will return the square of a number.

int
square(int x)
{
int square_of_x;
square_of_x = x * x;
return square_of_x;
}

To understand how to write such a function like this, it may help to look at what this function does as a whole. It takes in an int, x, and squares it, storing it in the variable square_of_x. Now this value is returned.

The first int at the beginning of the function declaration is the type of data that the function returns. In this case when we square an integer we get an integer, and we are returning this integer, and so we write int as the return type.

Next is the name of the function. It is good practice to use meaningful and descriptive names for functions you may write. It may help to name the function after what it is written to do. In this case we name the function "square", because that's what it does - it squares a number.

Next is the function's first and only argument, an int, which will be referred to in the function as x. This is the function's input.

Inbetween the braces is the actual guts of the function. It declares an integer variable called square_of_x that will be used to hold the value of the square of x. Note that the variable square_of_x can only be used within this function, and not outside. We'll learn more about this sort of thing later, and we will see that this property is very useful.

We then assign x multiplied by x, or x squared, to the variable square_of_x, which is what this function is all about. Following this is a return statement. We want to return the value of the square of x, so we must say that this function returns the contents of the variable square_of_x.

Our brace to close, and we have finished the declaration.

Note this should look familiar - you have been writing functions already, in fact - main is a function that is always written.

In general

In general, if we want to declare a function, we write

type
name(type1 arg1, type2 arg2, ...)
{
/* code */
}

We've previously said that a function can take no arguments, or can return nothing, or both. What do we write for the type of nothing? We use C's void keyword. void basically means "nothing" - so if we want to write a function that returns nothing, for example, we write

void
sayhello(int number_of_times)
{
int i;
for(i=1; i <= number_of_times; i++)
printf("Hello!\n");
}

Notice that there is no return statement in the function above. Since there's none, we write void as the return type.

What about a function that takes no arguments? If we want to do this, we can write for example

float
calculate_number(void)
{
float to_return=1; int i;
for(i=0; i < 100; i++)
{
to_return += 1;
to_return = 1/to_return;
}
return to_return;
}

Notice this function doesn't take any inputs, but merely returns a number calculated by this function.

Naturally, you can combine both void return and void in arguments together to get a valid function, also.

Recursion

Here's a simple function that does an infinite loop. It prints a line and calls itself, which again prints a line and calls itself again, and this continues until the stack overflows and the program crashes. A function calling itself is called recursion, and normally you will have a conditional that would stop the recursion after a small, finite number of steps.

void infinite_recursion()
\\ don't run that!
{
printf("Infinite loop!\n");
infinite_recursion();
}

A simple check can be done like this. Note that ++depth is used so the increment will take place before the value is passed into the function. Alternatively you can increment on a separate line before the recursion call. If you say print_me(3,0); the function will print the line Recursion 3 times.

void print_me(int j, int depth)
{
if(depth < j)
{
printf("Recursion! depth = %d j = %d\n",depth,j);//j always the same
print_me(j, ++depth);
}
}

Recursion is most often used for jobs such as directory tree scans, seeking for the end of a linked list, parsing a tree structure in a database and factorising numbers (and finding primes) among other things.

Static Functions

If a function is to be called only from within the file in which it is declared, it is appropriate to declare it as a static function. When a function is declared static, the compiler will now compile to an object file in a way that prevents the function from being called from code in other files. Example:

static short compare( short a, short b )
{
return (a+4 < b)? a : b;
}

Using C functions

We can now write functions, but how do we use them? When we write main, we place the function outside the braces that encompass main.

When we want to use that function, say, using our calculate_number function above, we can write something like

float f;
f = calculate_number();

If a function takes in arguments, we can write something like

int square_of_10;
square_of_10 = square(10);

If a function doesn't return anything, we can just say

say_hello();

since we don't need a variable to catch its return value


 

All text is available under the terms of the GNU Free Documentation License
Source : Wikibooks