Function pointer
From Wikipedia, the free encyclopedia
This article does not cite any references or sources. (May 2007) Please help improve this article by adding citations to reliable sources. Unverifiable material may be challenged and removed. |
A function pointer is a type of pointer in C, C++, D, and other C-like programming languages. When dereferenced, a function pointer invokes a function, passing it zero or more arguments just like a normal function. In programming languages like C, function pointers can be used to simplify code, such as replacing large switch statements[1].
Function objects, or functors, are similar to function pointers, and can be used in similar ways. A functor is an object of a class type that implements the function-call operator, allowing the object to be used within expressions using the same syntax as a function call. Functors are more powerful than simple function pointers, being able to contain their own data values, and allowing the programmer to emulate closures, among other uses.
Many "pure" object-oriented languages (such as Java) do not support function pointers. Something similar can be implemented in these kinds of languages, though, using references to interfaces that define a single member function. Microsoft .NET languages such as C# and Visual Basic .NET implement type-safe function pointers with delegates.
In other languages that support first-class functions, functions are regarded as data, and can be passed, returned, and created dynamically directly by other functions, eliminating the need for function pointers.
Extensively using function pointers to call functions may produce a slow-down for the code on modern processors, because branch prediction may not be able to figure out where to branch to (it depends on the value of the function pointer at run time).
Contents |
[edit] Examples in C
This example demonstrates the use of function pointers. Here a function pointer func
is declared, the address of the function named myfunc()
is assigned to it, and then the function is invoked by dereferencing the pointer.
#include <stdio.h>
static int myfunc(int a)
{
printf("myfunc: %d\n", a);
return (2*a + 3);
}
int main(void)
{
int (*func)(int) = myfunc;
int x;
x = (*func)(10);
printf("main: %d\n", x);
return 0;
}
Note that the syntax (*fp)(arg) is used to invoke the function indirectly through function pointer fp. C syntax also allows the simpler fp(arg) to be used, since the fp subexpression evaluates to the address of a function whether it is a function name or a pointer to a function.
The next example shows how function pointers can be used as parameters to other functions. As in the previous example, a function named function() is defined which will be called through a function pointer. A function named caller() accepts as parameters a function pointer and an integer, which will be passed as arguments to the function that will be called by caller(). The first parameter of caller
may be a pointer to any function whose prototype matches the prototype of the argument func
.
#include <stdio.h>
static void function(int a)
{
printf("function: %d\n", a);
}
static void caller(void (*func)(int), int p)
{
func(p);
}
int main(void)
{
caller(function, 10);
return 0;
}
This third example shows how function pointers can be used as parameters to other functions. Here a function f()
is passed to function integ()
which approximates an integral evaluated over an interval, , calling the function f(x)
for each value of x
. Any function taking a single double
argument and returning a double
result can be passed to integ()
for evaluation.
double integ(double a, double b, double (*f)(double))
{
double sum = 0.0;
int n;
// Evaluate integral{a,b} f(x) dx
for (n = 0; n <= 100; ++n) {
double x = a + n*(b-a)/100.0;
sum += (*f)(x) * (b-a)/101.0;
}
return sum;
}
For defining an array of function pointers, it might be useful to use a typedef to declare a new type for your function pointer.
#include <stdio.h>
#include <math.h>
typedef double (*Fx)(double);
int main(void)
{
Fx f[3]; /* or equivalently: double (*f[3])(double); */
f[0] = cos;
f[1] = sin;
f[2] = tan;
printf("From 0 to pi/4:\n");
printf("\t integ of cos = %g\n", integ(0, M_PI/4, f[0]));
printf("\t integ of sin = %g\n", integ(0, M_PI/4, f[1]));
printf("\t integ of tan = %g\n", integ(0, M_PI/4, f[2]));
return 0;
}
[edit] Method pointers
C++ is object-oriented, so classes can have methods. Non-static member functions (instance methods) have an implicit parameter (the this pointer) which is the pointer to the object it is operating on, so the type of the object must be included as part of the type of the function pointer. The method is then used on an object of that class by using one of the "pointer-to-member" operators: .*
or ->*
(for an object or a pointer to object, respectively).
#include <iostream>
class Adder
{
int x;
public:
Adder(int in) : x(in) { }
int addx(int y) { return x + y; }
};
int main()
{
int (Adder::*func)(int) = &Adder::addx;
Adder foo = Adder(3);
std::cout << (foo.*func)(5) << std::endl; // prints "8"
return 0;
}
Although function pointers in C and C++ can be implemented as simple addresses, so that typically sizeof(Fx)==sizeof(void *)
, member pointers in C++ must be implemented as "fat pointers", typically two or three times the size of a simple function pointer, in order to deal with virtual inheritance (see also virtual function).
[edit] External links
- Pointer Tutorials, C++ documentation and tutorials
- Pointer Tutorials, pointer basics
- Function Pointer Tutorials, a Guide to C/C++ function pointers, callbacks, and functors
- Member Function Pointers and the Fastest Possible C++ Delegates, CodeProject article by Don Clugston.
[edit] References
- ^ The Function Pointer Tutorials, by Lars Haendel;