loading...

Function Pointers in C

noah11012 profile image Noah11012 ・3 min read

My last article was about a topic that most beginners found challenging when first confronted: double pointers

Well, in this post, we will take a look at another class of pointers: function pointers

At their essence, function pointers are like their normal counterparts: a variable that holds the memory address of an object. Function pointers fulfill this role but the object they refer to have a special quality: they are callable. When an object is callable, the operator () can be used. The only callable objects in C are functions but in C++ some of the additions are classes that overload the call operator.

The syntax for defining a function pointer is considered the more quirky of the language and some beginners find it difficult to discern. So, we will start with a basic example:

void (*function_pointer)(void);

To better help ourselves learn the syntax of function pointers, we will tease it apart slowly. One thing that pops out immediately is the appearance of braces around *function_pointer. These parentheses are important and without them it means something entirely different. With the exclusion of the parentheses, it means a function that takes no input and returns a void pointer.

void *function_pointer(void);

Another thing that makes a function pointer a pointer is the use of the symbol *. All pointers have them and function pointers are no different but they are within the braces. Everything else can be read the same. To help with reading function pointers, remove the braces and * and read it like it is a normal function.

Example:

int *(*function_pointer)(int *, double *);

Remove the braces and *.

int *function_pointer(int *, double *);

Cleaner and easier to parse with our eyes! We now know this function pointer points to a function that takes an int * and a double * and returns a
int *.

Now, like everything else that is learned, what are the uses for function pointers?

Function pointers can be passed as an argument to another function which will be called within. These function pointers are known as callbacks. For example, let's say we have a function that downloads something from the internet and takes a function pointer. When the download is complete or an error has happened, we would like to execute the callback.

void download_file(const char *file, void (*callback_function)(int status_code));

Using our method of stripping away the braces and * we get a function pointer that refers to a function that accepts an int but returns nothing.

Another example of where function pointers can be utilized is event programming. Event programming in its simplest form is the idea when an event happens, do this. A perfect place for function pointers!

Let's say we have a GUI widget library and we have a function that sets up a callback that is called when a click has been detected on a button.

struct Button;

void button_set_click_event(Button *button, void (*on_click)(Button *button));

I'm sure by now you can parse what the callback is pointing to.

Summary

The concept of function pointers is easy to learn, but the syntax isn't the greatest and can leave someone confused when trying to analyze them. I hope this article helped and that any confusion you might have is now gone.

Posted on by:

Discussion

markdown guide