Overview
A function pointer is a variable that stores the address of a function that can be called later through that pointer
Use cases
- callback functions
- functions that are passed as arguments to other functions
- dynamic dispatch
- state machines
- pointers that are used to transfer between states
- dynamic plug-in mechanisms
- allows an application to dynamically use different plug-ins or modules at runtime
- ISRs
Syntax
ret_type (*funcptr_name)( funcargs_datatypes ) = <func_to_point_to>
Example 1
int add( int a, int b )
{
return a+b;
}
int sub( int a, int b )
{
return a-b;
}
int main()
{
int (*pFun)( int, int ) = add;
int sum = pFun( 5, 3 );
pFun = sub;
int diff = pFun( 5, 3 );
fprintf( stdout, "sum:%d, diff:%d\n", sum, diff );
}
Example 2
void* (*foo)( int* );
- Function pointer
fooreturns a void pointer and takes an integer pointer argument
Example 3
- From Example 1
int (*pFun)( int, int ) = add;
// or
int (*pFun)( int, int );
pFun = &add;
// The ampersand is optional!
int sum = pFun( 3, 2 );
// or
int sum = (*pFun)( 3, 2 );
// The dereference is optional!
Argument Syntax
// Exact same as for definitions
void function( ..., ret_type (*funcname)( funcargs_datatypes ), ... ){...}
// Where funcname only exists in the context of the function
Example
void bubble_sort( void *array[], size_t length, int(*compare)( void*, void* ) ){...}
Usage Syntax
function( ..., func_name , )
Usage Example
void bubble_sort( void* array[], size_t length, int (*compare)( const void*, const void* ) ){...}
// Will cast to char
int strcmp_nocase( const void* first, const void* second ){...}
int main()
{
char* strings[] = { "Hello", "Goodbye" };
bubble_sort( strings, 2, strcmp_nocase )
}
Typedef Definition Syntax
typedef ret_type (*funcptr_name_t)( funcargs_datatypes );
Function Arg Syntax
function( ..., funcptr_name_t funcname )
// Where funcname only exists in the context of the function
Function Use Syntax
function( ..., (funcptr_name_t)nameofactualfunc, ... )
Example
typedef int (*comp_t)( const void*, const void* );
void bubble_sort( void *array[], size_t length, comp_t compare ){...}
int strcmp_nocase( const void* first, const void* second ){...}
int main()
{
char* strings[] = { "Hello", "Goodbye" };
comp_t example = strcmp_nocase;
bubble_sort( strings, 2, example )
// or
bubble_sort( strings, 2, (comp_t)strcmp_nocase )
}
LUT Implementation
#define ERROR -1
int add( int a, int b) { return a+b; }
int sub( int a, int b) { return a-b; }
int mul( int a, int b) { return a*b; }
typedef enum ops { ADD, SUB, MUL } opt_t;
typedef int (*arithfc_t)( int, int );
int calc( opt_t operation, int x, int y )
{
static const arithfc_t ops[] = { add, sub, mul };
if ( operation > MUL || operation < ADD ) return ERROR;
return ops[operation]( x, y );
}
int main()
{
fprintf( stdout, "sum:%d\n", calc( ADD, 5, 3) );
}
State Machine Implementation
void stateA( void );
void stateB( void );
typedef int (*statefc_t)( void );
statefc_t state = state_A;
void state_A()
{
// do something
state = state_B;
}
void state_B()
{
// do something
state = state_A;
}
int main()
{
for(int i = 0; i < 5; i++ ) { state(); }
}