Next: Input-Output Up: Arrays and Pointers Previous: The command-line argument

Pointers to functions

In C function names are not themselves variables, but you can define a pointer to a function (similarly to arrays). This allows you, for example, to invoke one of several functions from a single call, reassigning the function pointer in between. To see how this works, we first introduce the syntax needed to talk about these things.

We already have something similar:

   int *int_ptr;

says that int_ptr is a pointer to an integer. It is not itself an integer, merely something which, when we follow it, we find an int.

Consider:

   int (*f_ptr)();

This says that f_ptr is a pointer to a function (and that function returns an int).

f_ptr is not itself a function, but if we follow it we will find one.

[If it was a function, returning a pointer to an int, we would have written:

   int *f_ptr()

If we had wanted a pointer to a function returning a pointer to an int, we would have written:

   int *(*f_ptr)();
]

As with array names, function names are in fact pointers to the function proper. Hence we can assign them to a function pointer. Suppose we have already got two int functions f1 and f2. We can now write:

   f_ptr= f1;

If we now ``call'' f_ptr we will invoke f1: how do we do this? We write:

   (*f_ptr)(argument_list)

As with other uses of pointers, we use the * to follow the pointer. The brackets are necessary to get the correct association (otherwise it will try to invoke f_ptr(argument_list) before applying the *). Of course we can subsequently write:

   f_ptr= f2;

and then the same call will produce a different effect. This is a very useful mechanism allowing generality of code and also portability. Like all of C's generous features it can also be used to the opposite effect!

One example: you can write a general multiply which will work as well with matrices as with scalars, by rebinding the call according to the type of object.

Another example: you can write a set_pixel routine which works with any depth of pixel, even though the address calculation and bit masking operations are radically different for, say, 1 bit pixels compared with 8 or 32 bits.

Finally, it means you can pass functions as arguments.

ANSI C also allows you to write

   f_ptr(argument_list)

just the same as an ordinary procedure call. My own preference is not to do this, simply because you normally use function pointers for some special reason and I think it is better to remind the reader that function pointers are in use with:

   (*f_ptr)(argument_list)



Next: Input-Output Up: Arrays and Pointers Previous: The command-line argument


maspjw@
Tue Sep 27 15:29:34 BST 1994