Using Function Pointers

Normally, argument lists follow function names:

f(a, b, c);

A function name that isn't followed by an argument list is similar to an array name that isn't followed by an index. For example, if nums is an array, then nums[0] is the same as *nums, but by itself, nums is a pointer to the beginning of the array. Similarly, sin(0) calls the sin function, but by itself, sin is just a pointer to the first binary instruction of the sin function. Like any pointer, it can be passed as a parameter, assigned to a variable, or returned as a value.

How would we declare a variable, f, that can hold a pointer to a function like sin? The syntax is a little tricky:

double (*f)(double);

This declares f to be a pointer to a function that expects a double argument and returns a double value. The assignment:

f = sin;

points f at the same place sin points to, namely the first instruction of the sin function. After the assignment, we can call f the same way we call sin:

cout << f(0) << endl; // prints sin(0)

Later, we can reassign another function to f:

f = cos;

Now calling f is the same as calling cos:

cout << f(0) << endl; // prints cos(0)

In a sense, treating functions like data adds another degree of flexibility to our programs beyond polymorphism. We can place a call to f in a program and each time this line is executed, a different function might be called.

Writing typedef in front of a function pointer declaration:

typedef double (*f)(double);

declares f not to be the name of a pointer to a function, but rather a name for the type of all pointers to functions. Let's change the name of the type to something a bit grander:

typedef double (*Fun)(double);

We can now declare and assign f using the syntax:

Fun f = sin;

Functional Programming

There are three great paradigms in programming:

Imperative: program = functions + data

Object-Oriented: program = data (i.e., objects)

Functional: program = functions

In functional programming, functions serve two purposes. They represent tasks that can be executed, and they represent data that can be stored in variables, passed to functions, and returned by functions.

Using function pointers we can mimic functional programming in C/C++.