Introduction
A pointer to a function points to the address of the executable code of the function. You can use pointers to call functions and to pass functions as arguments to other functions. You cannot perform pointer arithmetic on pointers to functions. It is useful in techniques such as callback functions, event-driven programs, and polymorphism (a concept where a function or operator behaves differently based on the context).
The type of a pointer to a function is based on both the return type and parameter types of the function.
Properties of Function Pointer
Function pointer points to the code instead of the data so there are some restrictions on the function pointers as compared to other pointers. Following are some important properties of function pointer:
- Points to the memory address of a function in the code segment.
- Requires the exact function signature (return type and parameter list).
- Can point to different functions with matching signatures.
- Cannot perform arithmetic operations like increment or decrement.
- Supports array-like functionality for tables of function pointers.
Declaration
A declaration of a pointer to a function must have the pointer name in parentheses. Function parameters have precedence over pointers in declarations, so parentheses are required to alter the precedence and declare a pointer to a function. Without them, the compiler interprets the declaration as a function that returns a pointer to a specified return type. For example:
int *f(int a); /* function f returning an int* */
int (*g)(int a); /* pointer g to a function returning an int */
f```
In the first declaration, f is interpreted as a function that takes an int as argument, and returns a pointer to an int. In the second declaration, g is interpreted as a pointer to a function that takes an int argument and that returns an int.
#### Example
```c
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
// Declare a function pointer that matches
// the signature of add() fuction
int (*fptr) (int, int);
// Assign to add()
fptr = &add;
// Call the function via ptr
printf("%d", fptr(10, 5));
return 0;
}You can use a trailing return type in the declaration or definition of a pointer to a function. For example:
auto(*fp)()->int;In this example, fp is a pointer to a function that returns int. You can rewrite the declaration of fp without using a trailing return type as int (*fp)(void). For more information on trailing return type, see Trailing return type (C++11).
References to functions
A reference to a function is an alias or an alternative name for a function. You must initialize all references to functions after they are defined. Once defined, a reference to a function cannot be reassigned. You can use references to call functions and to pass functions as arguments to other functions. For example:
int g();
// f is a reference to a function that has no parameters and returns int.
int bar(int(&f)()){
// call function f that is passed as an argument.
return f();
}
int x = bar(g);You can also use a trailing return type in the declaration or definition of a reference to a function. In the following example, fp is a reference to a function that returns int.
auto(&fp)()->int;Examples
Function Pointer as Arguments (Callbacks)
#include <stdio.h>
// A simple addition function
int add(int a, int b) {
return a + b;
}
// A simple subtraction function
int subtract(int a, int b) {
return a - b;
}
void calc(int a, int b, int (*op)(int, int)) {
printf("%d\n", op(a, b));
}
int main() {
// Passing different
// functions to 'calc'
calc(10, 5, add);
calc(10, 5, subtract);
return 0;
}Emulate Member Functions in Structure
#include <stdio.h>
// Define the Rectangle struct that contains pointers
// to functions as member functions
typedef struct Rect {
int w, h;
void (*set)(struct Rect*, int, int);
int (*area)(struct Rect*);
void (*show)(struct Rect*);
} Rect;
// Function to find the area
int area(Rect* r) {
return r->w * r->h;
}
// Function to print the dimensions
void show(Rect* r) {
printf("Rectangle's Width: %d, "
"Height: %d\n", r->w, r->h);
}
// Function to set width
// and height (setter)
void set(Rect* r, int w, int h) {
r->w = w;
r->h = h;
}
// Initializer/constructor
// for Rectangle
void constructRect(Rect* r) {
r->w = 0;
r->h = 0;
r->set = set;
r->area = area;
r->show = show;
}
int main() {
// Create a Rectangle object
Rect r;
constructRect(&r);
// Use r as a Rectangle
r.set(&r, 10, 5);
r.show(&r);
printf("Rectangle Area: %d", r.area(&r));
return 0;
}