Function Pointers without typedef
In this chapter, you are going to learn
Uses of funcion pointers ?
Topics in this section,
Section 2 : Functions taking function pointers as an arguement
Section 3.3 : Function returns a function which returns a function which returns a function pointer
Section 4 : Function taking function pointers as an arguement and returning function pointers
Section 5.1 : Array of function pointers to implement calculator
Section 5.2 : Array of Function Pointers for handling asynchronous events
return_type (*function_pointer)(parameters_list);
In this program,
Function sum() returns sum of two integers
1#include <stdio.h>
2
3int sum(int a, int b)
4{
5 return a + b;
6}
7
8int main(void)
9{
10 int s;
11
12 s = sum(5, 6);
13
14 printf("sum = %d\n", s);
15
16 return 0;
17}
Now let us replace call to function sum() using function pointer
Step 1 : Define a function pointer
int (*calc)(int, int);
Step 2 : Define a function
int sum(int a, int b) { return a + b; }
Note that, return type and function parameters of function pointer should match with that of actual function
Step 3 : Assign function pointer with address of an actual function
calc = sum;
OR
calc = ∑
Step 4 : Use the function pointer to call the function
s = calc(5, 6);
OR
s = (*calc)(5, 6);
See full program below
1#include <stdio.h>
2
3// Step 1 : Define a function pointer
4int (*calc)(int, int);
5
6// Step 2 : Define a function
7int sum(int a, int b)
8{
9 return a + b;
10}
11
12int main(void)
13{
14 int s;
15
16 // Step 3 : Assign function pointer with address of an actual function
17 calc = sum;
18
19 // Step 4 : Use the function pointer to call the function
20 s = calc(5, 6);
21
22 printf("sum = %d\n", s);
23
24 return 0;
25}
In this section, you are going to learn
Functions taking function pointers as an arguement
Step 1 : Define a function called
fx()
Step 2 : Identify the function pointer prototype
fp
for above functionStep 3 : Define a function
fy()
taking function pointerfp
as an arguementStep 4 : Call the function
fx()
using function pointerfp
insidefy()
Step 5 : Call the function
fy()
by passingfx
as argumentStep 6 : Let us see few examples
Step 1 : Define a function called
fx()
void fx(void)
{
printf("Inside function fx()\n");
}
Step 2 : Identify the function pointer prototype
fp
for above function
void (*fp)(void)
Step 3 : Define a function
fy()
taking function pointerfp
as an arguement
void fy(void (*fp)(void))
{
}
Step 4 : Call the function
fx()
using function pointerfp
insidefy()
void fy(void (*fp)(void))
{
fp();
}
Step 5 : Call the function
fy()
by passingfx
as argument
fy(fx);
See full program below
1#include <stdio.h>
2
3void fx(void)
4{
5 printf("Inside function fx()\n");
6}
7
8void fy(void (*fp)(void))
9{
10 fp();
11}
12
13int main(void)
14{
15 fy(fx);
16
17 return 0;
18}
Inside function fx()
Step 1 : Define two functions
sum()
,sub()
int sum(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
Note that, Prototypes of sum() and sub() are matching
Step 2 : Identify the function pointer prototype for functions
sum()
,sub()
int (*calc)(int, int)
In this example,
calc
is the function pointerreturn type of
calc
isint
. Because return type ofsum
andsub
isint
Number of parameters of
calc
is two. Because Number of parameters ofsum
andsub
is twoType of first parameter is
int
. Because type of first parameter isint
insum
andsub
Type of second parameter is
int
. Because type of second parameter isint
insum
andsub
Step 3 : Define a function
do_calculation()
taking function pointercalc
as an arguement
int do_calculation(int (*calc)(int, int), int a, int b)
{
}
do_calculation
takes 3 arguementsFirst is function pointer
calc
Second is integer
a
Third is integer
b
Step 4 : Call the function pointer
calc
insidedo_calculation
int do_calculation(int (*calc)(int, int), int a, int b)
{
return calc(a, b);
}
calc
is a function pointer which can hold the address of any function whose prototype matches with that ofcalc
Step 5 : Call the function
do_calculation()
by passingsum
orsub
as argument
While calling
do_calculation()
, pass 3 arguementsFirst : Address of a function whose prototype matches with that of
calc
Second : integer
Third : integer
See full program below
Function
do_calculation
is called first time to perform addition usingsum
Function
do_calculation
is called second time to perform subtraction usingsub
In both cases, definition of function
do_calculation
is common !
1#include <stdio.h>
2
3int sum(int a, int b)
4{
5 return a + b;
6}
7
8int sub(int a, int b)
9{
10 return a - b;
11}
12
13int do_calculation(int (*calc)(int, int), int a, int b)
14{
15 return calc(a, b);
16}
17
18int main(void)
19{
20 int s;
21
22 s = do_calculation(sum, 5, 6);
23
24 printf("sum = %d\n", s);
25
26 s = do_calculation(sub, 5, 6);
27
28 printf("sub = %d\n", s);
29
30 return 0;
31}
1sum = 11
2sub = -1
In this section, you are going to learn
Functions returning function pointers
Step 1 : Define a function
fx
void fx(void) { printf("Inside function fx()\n"); }
Step 2 : Define a function
get_fx_operation
which returns function pointervoid (* get_fx_operation(void) ) (void) { return fx; }
Note the syntax !
Step 2.1 : Write the prototype of function pointer
void (*) (void) { }
Step 2.2 : Write the function name and its arguements
void (* get_fx_operation(void) ) (void) { }
Step 2.3 : Return the address of a function
void (* get_fx_operation(void) ) (void) { return fx; }
Step 3 : Call
get_fx_operation
and store the return value in function pointerfx_p
fx_p = get_fx_operation();
Where the prototype of
fx_p
should match with prototype offx()
void (*fx_p)(void);
Step 4 : Call the function using
fx_p
fx_p(); // This calls function fx()
Step 5 : See the full program below
1#include <stdio.h>
2
3void fx(void)
4{
5 printf("Inside function fx()\n");
6}
7
8void (* get_fx_operation(void) ) (void)
9{
10 return fx;
11}
12
13int main(void)
14{
15 void (*fx_p)(void);
16
17 fx_p = get_fx_operation();
18
19 fx_p(); // This calls function fx()
20
21 return 0;
22}
In this example, program decides the sorting mechanism to be used at run time based on the array size
Step 1 :
get_sort_method
returns sorting method to be used based on array size
void ( *get_sort_method(int n) ) (int *, int n)
{
if (n <= 2)
return insertion_sort;
else
return selection_sort;
}
Step 2 :
analyse_data
callsget_sort_method
function to sort
void analyse_data(int *arr, int n)
{
void (*sort_fp)(int *arr, int n);
sort_fp = get_sort_method(n);
sort_fp(arr, n);
}
Step 3 : What is the advantage ?
Whenever the array size changes the function
analyse_data
need not change !If
analyse_data
is defined in a sepratex.c
file, we need not recompilex.c
In real time,
analyse_data
can be very big function with calls to many function pointers
Step 4 : See the full program below
1#include <stdio.h>
2
3int arr[] = { 47, 13, 63, 29, 7 };
4
5void insertion_sort(int *arr, int n)
6{
7}
8
9void selection_sort(int *arr, int n)
10{
11}
12
13void ( *get_sort_method(int n) ) (int *, int n)
14{
15 if (n <= 2)
16 return insertion_sort;
17 else
18 return selection_sort;
19}
20
21void analyse_data(int *arr, int n)
22{
23 void (*sort_fp)(int *arr, int n);
24
25 sort_fp = get_sort_method(n);
26
27 sort_fp(arr, n);
28}
29
30int main(void)
31{
32 analyse_data(arr, sizeof(arr) / sizeof(arr[0]) );
33
34 return 0;
35}
Can you guess what is happening in below program ?
1#include <stdio.h>
2
3int fa(void)
4{
5 printf("Inside function fa\n");
6 return 0;
7}
8
9int (* funx(void) ) (void)
10{
11 return fa;
12}
13
14int (*(* funy(void)) (void)) (void)
15{
16 return funx;
17}
18
19int (*(*(* funz(void)) (void)) (void)) (void)
20{
21 return funy;
22}
23
24int main(void)
25{
26 funz()()()();
27 return 0;
28}
Step 1 : Define a function
get_fx_operation
which takes function pointer as arguement and returns a function pointerget_fx_operation
is written using concepts from Section 2 and Section 3get_fx_operation
takesfs_p
as arguement which is a function pointer which can hold the address of a function which returnsvoid
and takesint
as an arguementget_fx_operation
returnsfx
orgx
depending on the value ofa
void (* get_fx_operation( void (*fs_p)(int) ) ) (void)
{
int a = 5;
fs_p(a);
if (a > 0)
return fx;
else
return gx;
}
Step 2 : Call
get_fx_operation
and pass address of a functionWe are passing address of
sample_fun
as arguement toget_fx_operation
fx_p = get_fx_operation(sample_fun);
Step 3 : See the full program below
1#include <stdio.h>
2
3void fx(void)
4{
5 printf("Inside function fx() : Positive\n");
6}
7
8void gx(void)
9{
10 printf("Inside function gx() : Negative\n");
11}
12
13void sample_fun(int a)
14{
15 printf("a = %d \n", a);
16}
17
18void (* get_fx_operation( void (*fs_p)(int) ) ) (void)
19{
20 int a = 5;
21
22 fs_p(a);
23
24 if (a > 0)
25 return fx;
26 else
27 return gx;
28}
29
30int main(void)
31{
32 void (*fx_p)(void);
33
34 fx_p = get_fx_operation(sample_fun);
35
36 fx_p(); // This calls function fx()
37
38 return 0;
39}
Similar functions can be grouped into an array
We call this as array of function pointers
Array of function pointers enables asynchronous event handling
return_type ( *fp_array [ ] ) ( parameter_list ) = { functions_list };
Step 1 : Define an array of function pointers
calc
is an array of function pointersEach element in this array is a function which takes two integers as argement and returns void
void ( *calc [ ] )( int, int ) = { sum, sub, mul };
Step 2 : Find number of elements in an array generic way
Number of elements in Array = Sizeof_Array / Size of One element
Number of elements in calc
= sizeof(calc) / sizeof(calc[0])
Step 3 : Call the functions using array of function pointers
calc[i](5, 6);
// calc[0](5, 6) equals sum(5, 6)
// calc[1](5, 6) equals sub(5, 6)
// calc[2](5, 6) equals mul(5, 6)
Step 4 : See full program below
1#include <stdio.h>
2
3void sum(int a, int b)
4{
5 printf("Function sum called : a = %d, b = %d, sum = %d\n", a, b, a + b);
6}
7
8void sub(int a, int b)
9{
10 printf("Function sub called : a = %d, b = %d, sub = %d\n", a, b, a - b);
11}
12
13void mul(int a, int b)
14{
15 printf("Function mul called : a = %d, b = %d, mul = %d\n", a, b, a * b);
16}
17
18void (*calc[])(int, int) = { sum, sub, mul};
19
20int main(void)
21{
22 printf("size of array = %ld\n", sizeof(calc));
23 printf("size of one element = %ld\n", sizeof(calc[0]));
24 printf("Number of elements in array = %ld\n", sizeof(calc)/sizeof(calc[0]));
25
26 for (int i = 0; i < sizeof(calc)/sizeof(calc[0]); i++)
27 {
28 calc[i](5, 6);
29 }
30
31 return 0;
32}
Output is as below
size of array = 24
size of one element = 8
Number of elements in array = 3
Function sum called : a = 5, b = 6, sum = 11
Function sub called : a = 5, b = 6, sub = -1
Function mul called : a = 5, b = 6, mul = 30
Asynchoronous events - Can arrive at any time
In below example, events are generated randomly and handled dynamically
Step 1 : Define functions which handle specific events
void ev_connect_cb(void)
{
printf("Handled ev_connect_cb\n");
}
void ev_disconnect_cb(void)
{
printf("Handled ev_disconnect_cb\n");
}
void ev_reconnect_cb(void)
{
printf("Handled ev_reconnect_cb\n");
}
Step 2 : Map these functions to array of function pointers
void (*ev_cb[]) (void) = {
ev_connect_cb,
ev_disconnect_cb,
ev_reconnect_cb,
};
Step 3 : Call these functions based on event generated
ev_cb[ev_id]();
Step 4 : See full program below
1#include <stdio.h>
2#include <stdlib.h>
3#include <time.h>
4#include <unistd.h>
5
6void handle_event(int ev_id);
7
8enum events
9{
10 EV_INIT,
11 EV_CONNECT = EV_INIT,
12 EV_DISCONNECT,
13 EV_RECONNECT,
14 EV_MAX = EV_RECONNECT
15};
16
17void ev_connect_cb(void)
18{
19 printf("Handled ev_connect_cb\n");
20}
21
22void ev_disconnect_cb(void)
23{
24 printf("Handled ev_disconnect_cb\n");
25}
26
27void ev_reconnect_cb(void)
28{
29 printf("Handled ev_reconnect_cb\n");
30}
31
32void (*ev_cb[]) (void) = {
33 ev_connect_cb,
34 ev_disconnect_cb,
35 ev_reconnect_cb,
36 };
37
38void generate_events()
39{
40 int i;
41 for (;;) {
42 for (i = 0; i < EV_MAX; i++) {
43 int ev_id = (rand() %
44 (EV_MAX - EV_INIT + 1)) + EV_INIT;
45 handle_event(ev_id);
46 }
47 }
48}
49
50void handle_event(int ev_id)
51{
52 ev_cb[ev_id]();
53}
54
55int main(void)
56{
57 generate_events();
58 return 0;
59}
C language allows programmer to define function pointers inside a structure
After all, function pointer is another variable
Step 1 : Declare function pointers inside a structure
struct student_db
{
int id;
int age;
int marks;
char name[32];
int (*get_age_p) (struct student_db *s);
int (*get_marks_p)(struct student_db *s);
};
get_age_p
is a function pointer
get_marks_p
is a function pointer
Step 2 : Assign function pointers with actual function definitions at the time of structure object creation
struct student_db s1 = {
.id = 101,
.age = 20,
.marks = 97,
.name = "Adam",
.get_age_p = get_age,
.get_marks_p = get_marks
};
Step 3 : Call the function via function pointers using structure object
s1.get_age_p(&s1);
Step 4 : See full program below
1#include <stdio.h>
2
3struct student_db
4{
5 int id;
6 int age;
7 int marks;
8 char name[32];
9
10 int (*get_age_p) (struct student_db *s);
11 int (*get_marks_p)(struct student_db *s);
12};
13
14int get_age(struct student_db *s)
15{
16 return s->age;
17}
18
19int get_marks(struct student_db *s)
20{
21 return s->marks;
22}
23
24int main(void)
25{
26 struct student_db s1 = {
27 .id = 101,
28 .age = 20,
29 .marks = 97,
30 .name = "Adam",
31 .get_age_p = get_age,
32 .get_marks_p = get_marks
33 };
34
35 struct student_db s2 = {
36 .id = 102,
37 .age = 21,
38 .marks = 98,
39 .name = "Ram",
40 .get_age_p = get_age,
41 .get_marks_p = get_marks
42 };
43
44 printf("Age of s1 = %d\n", s1.get_age_p(&s1));
45 printf("Marks of s1 = %d\n", s1.get_marks_p(&s1));
46
47 printf("Age of s2 = %d\n", s2.get_age_p(&s2));
48 printf("Marks of s2 = %d\n", s2.get_marks_p(&s2));
49
50 return 0;
51}
Simple function Pointer : Method 1 |
|
---|---|
return_type (*fp) (parameter_list); |
Basic Function Pointer syntax |
fp = function; |
|
fp(); |
|
Simple function Pointer : Method 2 |
|
---|---|
return_type (*fp) (parameter_list); |
Basic Function Pointer syntax |
fp = &function; |
fp` is assigned with address of |
(*fp) (); |
|
Array of function Pointers |
|
---|---|
return_type (*fp [ ] ) (parameter_list); |
Basic Array of Function Pointers syntax |
fp[0] = funx, fp[1] = funy |
function pointers fp[0] and fp[1] are initialised |
fp[0]() |
|
fp[1]() |
|
Current Module
Previous Module
Next Module
Other Modules