Friday, July 6, 2012

Function Pointers in C (and C++) - What are they and How to use them

If you are using the C programming language, you have probably already worked with pointers extensively. Chances are that you have also worked with functions. So, when you put two and two together, you get a function pointer; that is a pointer to a function. Function pointers are a wonderful way to organize and use functions and can also save some space. Here are some examples of how they are used:

int func(int x){return 0;}//This will be used throughout the post.

Function pointers work just like any pointer, meaning they will hold the address of a function (for quite some time I ignorantly assumed that functions didn't have their own memory address). However, the type is a bit weird. The syntax is

primitive-type (*pointer_name) (parameters)


for our above example we would make a function pointer like this:


int (*funcPoint)(int x)=&func;

Function pointers can be returned as well as executed. Lets pretend that a function called getPoint returns a function to a pointer like this:

int (*getPoint(int x))(){return &func;}//1

To call the pointer this returns, the code would look like this:

funcPoint = getPoint();//2
funcPoint(4);//3

Let's explain what just happened in the few lines above:

1: We declared a function returning a pointer with one argument (x) that returns an int. The function itself has no parameters (thus the ()).

2: We assigned funcPoint (declared earlier) the address of the function returned by getPoint();

3: We called the function stored in funcPoint with an argument of 4.

Of course, function pointers are more powerful than just returning and calling from functions they have more uses.

1: When a function needs to get passed into another file without using an #include

2: When organization is key. For plugin systems (I made a small one called Crunch once) it is helpful to keep an array of function pointers to call. They are declared like this:

At the top of the file: typedef int (*func)(int);
Somewhere else:        func functions[10];
(Yes, you can also just do int (*func[10])(int); but I think it is a lot more organized to use typedef.)

Of course, members are added to the array as such: &function (NOTE THAT THERE ARE NO ()'s FOR PARAMETERS)

3: For something that resembled exception handling
You can fix issues by having a file named "helper.h" that returns a function based on some variables in "helpme.h". All you would need is a function that gets some information from helpme.h (possibly with a function pointer to a function returning an array pointer like this:
char** (*func(int))(){};
)
and a function in helper.h that returns a function to aid helpme.h in whatever it needs.

----
Pointers have an endless amount of possibilities. Anything with a type and a memory address can and will be assigned to a pointer. I consider function pointers the "final frontier" of pointery, since variables and functions make up the whole of a C program. And yes, this also applies to C++, but I didn't want to talk about C++ because it gets even more confusing with class members and what-not. It is still possible, though. To check out the full potential of function pointers go here: http://www.newty.de/fpt/fpt.html. That is the resource that I used to learn function pointers so I owe it a shout-out.

Also, I would like to take this time to plug my complete rewrite of nAI. It contains something called crunchLand.h that uses a lot of function pointers https://github.com/dymatic/C---Dumb-AI-with-extras/blob/master/HEADER/Crunch/crunchLand.h
That is crunchLand.h

No comments:

Post a Comment