Function Pointer in C

Firstly, let's see how to declare a pointer in C.

int *ptr;                                                                                                                                                  

Adding a * between the datatype (int) and the variable (ptr) makes the "ptr" variable as pointer variable.

int func(int);                                                                                                                                           

With the above statement, we declare a function which accepts an integer as an argument and returns an integer.

Now, let's see how to declare a pointer to a function. What if we add an * between the datatype and the function.

int *func(int);                                                                                                                                         

But, with the above statement, () take much precedence than *. So, it meant that func will take the argument as integer and return an integer pointer.

So, we have to bind the * with func. Hence, we used ()

int (*func)(int);                                                                                                                                        

I will ensure that it will not be a tad hard.

Example 1


#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
    srand(time(NULL));

    int a = rand() % 100;
    int b = rand() % 100;
    
    printf("The product of %d and  %d is %d", a, b, a*b);
    
    return 0;
}

Output:
1
The product of 96 and  14 is 1344

The above is simple function which calculates the product, and now I'm gonna write a separate function to calculate the product.

Example 2 

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int prod (int a, int b) 
{
    return a*b;
}

int sum (int a, int b) 
{
    return a+b;
}

int main()
{
    srand(time(NULL));

    int a = rand() % 100;
    int b = rand() % 100;
    
    printf("The product of %d and  %d is %d", a, b, prod(a, b));
    
    return 0;
}

Output:
1
The product of 77 and  32 is 2464

Without modifying the main driver code, I want to call different functions. 

Example 3

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int prod (int a, int b) 
{
    return a*b;
}

int sum (int a, int b) 
{
    return a+b;
}

void noChangeFunction(int (*operation)(int a, int b)) 
{
    srand(time(NULL));

    int a = rand() % 100;
    int b = rand() % 100;
    
    printf("The product of %d and  %d is %d\n", a, b, operation(a, b));
    return;
}

int main()
{
    noChangeFunction(prod);
    noChangeFunction(&prod);
    noChangeFunction(sum);
    return 0;
}

Output:
1
2
3
The product of 60 and  19 is 1140
The product of 60 and  19 is 1140
The product of 60 and  19 is 79

As this produces same number, I moved the srand() to main.

Example 4

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int prod (int a, int b) 
{
    return a*b;
}

int sum (int a, int b) 
{
    return a+b;
}

void noChangeFunction(int (*operation)(int a, int b)) 
{
    int a = rand() % 100;
    int b = rand() % 100;
    
    printf("The product of %d and  %d is %d\n", a, b, operation(a, b));
    return;
}

int main()
{
    srand(time(NULL));

    noChangeFunction(prod);
    noChangeFunction(&prod);
    noChangeFunction(sum);
    return 0;
}

Output:
1
2
3
The product of 66 and  98 is 6468
The product of 23 and  64 is 1472
The product of 38 and  29 is 67

Click here to debug.

Example 5

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int prod (int a, int b) 
{
    return a*b;
}

int sum (int a, int b) 
{
    return a+b;
}

int (*operation)(int a, int b);

int main()
{
    srand(time(NULL));
    
    operation = &sum;
    int a = rand() % 100;
    int b = rand() % 100;
    int sum = (*operation) (a, b);
    printf("The sum of two numbers %d and %d is %d\n", a, b, sum);
    
    operation = &prod;
    int result = (*operation) (a, b);
    printf("The product of two numbers %d and %d is %d\n", a, b, result);
    
    return 0;
}

Output:
1
2
The sum of two numbers 23 and 57 is 80
The product of two numbers 23 and 57 is 1311

Click here to debug.

There is a significant difference between example 5 & 4. In example 4, the function pointer is called as 

operation(a, b)

But, we can call it as (*operation)(a, b) as well.

However, in example 5, it is invoked as 

    int sum = (*operation) (a, b);

This is because, the function 'noChangeFunction' already receives the operation as function pointer, so just calling as operation is enough in example 4. 

Example 6

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int prod (int a, int b) 
{
    return a*b;
}

int sum (int a, int b) 
{
    return a+b;
}

int (*functionFactory(int a, int b))(int, int)
{
    int (*operation)(int , int) = &sum;
    return (*operation)(a, b);
}

int main()
{
    srand(time(NULL));

    int a = rand() % 100;
    int b = rand() % 100;
    printf("The sum of two numbers %d and %d is %d\n", a, b, (*functionFactory)(a, b));
    
    return 0;
}

Output:

1
The sum of two numbers 59 and 99 is 158

The above program is wrong somehow. 

Example 7

#include <stdio.h>
#define MAX_NUM 15 
static int global_var = 0;

void ignoreNumber(int nbr)  
{
    int favour = 7;
    int i;
    printf("Fucntion %s\n",__func__);
    if (nbr > favour)
        return;
    for (i = 0; i < favour; i++) {
       if (i == nbr) {
           continue;
       }
       printf("Value[%d] %d\n", i, i); 
    }
}

void printNumber(int nbr)  
{
    printf("Fucntion %s\n",__func__);
    printf("%d\n", nbr);
}

void myFunction(void (*f)(int), int data)  
{   
    printf("Fucntion %s\n",__func__);
    if (data < MAX_NUM) {
        func(f, data);
    } else {
        func(f, MAX_NUM);
    }
}

void func(void (*f)(int), int max)  
{
    int i = 0;
    printf("Fucntion %s\n",__func__);
    if (f) {
        for(; i < max; i++) 
        {
            (*f)(i);
        }
    }
}
int main(void)  
{
    int num = 10;
    printf("Fucntion %s\n",__func__);
    myFunction(printNumber, num);
    myFunction(ignoreNumber, num);
    return (0);
}

Output:
Fucntion main
Fucntion myFunction
Fucntion func
Fucntion printNumber
0
Fucntion printNumber
1
Fucntion printNumber
2
Fucntion printNumber
3
Fucntion printNumber
4
Fucntion printNumber
5
Fucntion printNumber
6
Fucntion printNumber
7
Fucntion printNumber
8
Fucntion printNumber
9
Fucntion myFunction
Fucntion func
Fucntion ignoreNumber
Value[1] 1
Value[2] 2
Value[3] 3
Value[4] 4
Value[5] 5
Value[6] 6
Fucntion ignoreNumber
Value[0] 0
Value[2] 2
Value[3] 3
Value[4] 4
Value[5] 5
Value[6] 6
Fucntion ignoreNumber
Value[0] 0
Value[1] 1
Value[3] 3
Value[4] 4
Value[5] 5
Value[6] 6
Fucntion ignoreNumber
Value[0] 0
Value[1] 1
Value[2] 2
Value[4] 4
Value[5] 5
Value[6] 6
Fucntion ignoreNumber
Value[0] 0
Value[1] 1
Value[2] 2
Value[3] 3
Value[5] 5
Value[6] 6
Fucntion ignoreNumber
Value[0] 0
Value[1] 1
Value[2] 2
Value[3] 3
Value[4] 4
Value[6] 6
Fucntion ignoreNumber
Value[0] 0
Value[1] 1
Value[2] 2
Value[3] 3
Value[4] 4
Value[5] 5
Fucntion ignoreNumber
Value[0] 0
Value[1] 1
Value[2] 2
Value[3] 3
Value[4] 4
Value[5] 5
Value[6] 6
Fucntion ignoreNumber
Fucntion ignoreNumber


Advantages


It stores the start of the executable code, not the data.

This doesn't require memory allocation and de-allocation unlike normal pointers.

It used for the callback functions which is a function, passed as a parameter to another function. 
used in signals, threads, and array of function pointers. 

It avoids the code redundancy.

It used for state machine calls.



Comments