function pointer

What is and How to use function pointer in C- A detail Guide

A pointer to function in C is one of the most important pointer tools which is often ignored and misunderstood by the people. Generally, people face the problem with function pointer due to an improper declaration, assignment and dereferencing the function pointer.

Misunderstanding of the fundamental concept of function pointers can create issues in the project. This issue can waste a lot of your time and can be the cause of project failure. The problem with a pointer to a function is that it is one of the most difficult topics in C language. Only a few people understand the proper utilization of pointer to function in C.

So In this blog post, I will explain the basic concept of a function pointer and how you can use a function pointer in C programming. So let us come on the topics.

 

What is a function pointer or pointer to function?

A function pointer is similar to the other pointers but the only difference is that it stores the address of a function instead of a variable. In the program whenever required we can invoke the pointed function using the function pointer. So using the function pointer we can provide the run time binding in C programming which resolves the many problems.

 

function pointer
aticleworld

 

How to declare function pointer in C?

The syntax for declaring function pointers are very straightforward. It seems difficult in the beginning but once you are familiar with function pointer then it becomes easy. Its declaration is almost similar to the function declaration, it means you need to write return type, argument list, and function pointer name.  Let us see the syntax of the function pointer declaration.

Function_return_type(*Function_Pointer_name)(Function argument list);

 

Here is an example :

//It can point to function which takes an int as an argument and return nothing.
void ( *fpData )( int );

//It can point to function which takes a const char * as an argument and return nothing.
void ( *pfDisplayMessage) (const char *);

 

Note: The function pointer name is preceded by the indirection operator ( * ).

Braces have a lot of importance when you declare a pointer to function in C programming. If in the above example, I remove the braces, then the meaning of the above expression will be changed. It becomes the declaration of a function that takes the const character pointer as arguments and returns a void pointer.

void *pfDisplayMessage(const char *);

 

 

List of some function pointers

A function pointer must have the same signature to the function that it is pointing to. In a simple word, we can say that the function pointer and its pointed function should be the same in the parameters list and return type.

So there can be a lot of possibility of a function pointer in C. In the below section, I am listing some function pointers and I want you to write the explanation of these function pointers in the comment box.

void (*fpData)(void);

int  (*fpData)(int);

int  (*fpData)(char *);

int* (*fpData)(char *);

int  (*fpData)(int, char *);

int* (*fpData)(int, int *, char *);

int* (*fpData)(int , char, int (*paIndex)[3]);

int* (*fpData)(int , int (*paIndex)[3] , int (* fpMsg) (const char *));

int* (*fpData)(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));

int* (*fpData[2])(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));

int* (*(*fpData)(const char *))(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));

 

 

Initialization of function pointer in C:

We have already discussed that a function pointer is similar to normal pointers. So after the declaration of a function pointer, we need to initialize it like normal pointers. A function pointer is initialized to the address of a function but the signature of function pointer should be the same as the function.

Let consider an example,

Before using the function pointer we need to declare it and the prototype must be similar to the function which addresses you want to store.  In the below example, I want to store the address of a function (AddTwoNumber) which takes two integers as an argument and returns an integer.

So below I am creating a function pointer that takes two integers as an argument and returns an integer.

//declaration of function pointer

int (* pfAddTwoNumber) (int, int);

 

Now its time to initialize the function pointer with function address. There is two way to initialize the function pointer with function address. You can use the address-of operator ( &) with function name or you can use directly function name (Function name also represents the beginning address of the function).

pfAddTwoNumber = &AddTwoNumber;

            or

pfAddTwoNumber = AddTwoNumber;

 

If you want like another pointer you can initialize the function pointer at the time of declaration, like the below code. Some times it is useful and saves your extra line code.

int (* pfAddTwoNumber) (int, int) = AddTwoNumber;

 

Let see an example that shows the declaration and initialization of function pointer. It also explains how to function pointer is used to invoke the pointed function.

#include <stdio.h>

// A function with an const char pointer parameter
// and void return type
void DisplayMessage(const char *msg)
{
    printf("Message  =>>  %s\n", msg);
}

int main()
{
    // pfDisplayMessage is a pointer to function DisplayMessage()
    void ( *pfDisplayMessage) (const char *) = &DisplayMessage;

    // Invoking DisplayMessage() using pfDisplayMessage
    (*pfDisplayMessage)("Hello Aticleworld.com");

    return 0;
}

Output: Message =>> Hello Aticleworld.com

 

If you want to learn more about the c language, here 10 Free days (up to 200 minutes) C video course for you.

Your free trial is waiting

 

Some important concept related to pointer to function:

 

1) Memory allocation and deallocation for function pointer:

Dynamic memory allocation is not useful for function pointers. We create the function pointer only to point to a function. So if you allocate the dynamic memory for the function pointer then there is no importance to create the function pointer.

// Not useful expression
void (*pfData) (int)  = malloc(sizeof(pfData));

 

2) Comparing function pointers:

We can use the comparison operators (== or != ) with function pointer. These operators are useful to check that the function pointer is pointing to a valid memory or not. Before calling a function pointer in the program you must check its validity and it is very good practice to check the validity of function pointer.

When we compare two function pointers then we have to remember that two pointers of the same type compare equal if and only if they are both null, both points to the same function or both represent the same address

In your program, if the function pointers are not initialized by the valid address and your application wants to execute the function pointer then the application might be crashed. In the case of drivers, you might face BSOD (Blue screen of death ) or system hangs issues.

So whenever you create function pointer in your program then at the time of creation you must initialize it NULL. Also before executing the function pointer, you must check its validity by comparing it with the null pointer ( != NULL ).

For Example,

Here, pfLedOnOff is a function pointer, which is called to make led On or Off.

if( pfLedOnOff!= NULL)
{
    // calling of function function
    (*pfLedOnOff) (iLedState); 
}
else
{
    retrun Invalid;
}

 

 

3) Assigning function address to a function pointer:

There is two way to assign the address of the function to a pointer to function. You can use the address-of operator ( &) with function name or you can use directly function name (Function name also represents the beginning address of the function).

//Assigning function address to the function pointer
Function_Pointer = Function_Name;
                 or
//Assigning function address to the function pointer
Function_Pointer = &Function_Name;

 

 

4) Calling a function using the function pointer:

After assigning the function address to the function pointer, you can call the function using the function pointer. Bellow, we are describing the function calling by function pointer in a few steps. So let see the mentioned steps to how to use a pointer to function for calling a function.

  • Like another pointer, you need to dereference the function pointer using the indirection operator ( *).  Let us consider the below statement,
*Function_Name

 

  • The second step is to cover the function pointer with braces.
(*Function_Name)

 

  • The third step to pass the argument list in function pointer if available. If there is no argument list then left argument braces empty.
//Function pointer which has argument list
(*Function_Name)(ArgumentList);

         or
//Function pointer without argument list
(*Function_Name)();

 

Let’s see an example, for better understanding. In this example code, I am calling a function using the function pointer. This function is used to add the value of two integers.

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

//function used to add two numbers
int AddTwoNumber(int iData1,int iData2)
{
    return (iData1 + iData2);
}

int main(int argc, char *argv[])
{

    int iRetValue = 0;

    //Declaration of function pointer
    int (*pfAddTwoNumber)(int,int) = NULL;

    //initialize the function pointer
    pfAddTwoNumber = AddTwoNumber;

    //Calling the function using the function pointer

    iRetValue = (*pfAddTwoNumber)(10,20);

    //display addition of two number
    printf("\n\nAddition of two number = %d\n\n",iRetValue);

    return 0;
}

OutPut:

 

 

 

Explanation of the above program:

In the above program first I am declaring a function pointer pfAddTwoNumber and initializing it with NULL. It can store the address of a function that takes two integers as an argument and returns an integer.

//Declaration of function pointer
int (*pfAddTwoNumber)(int,int) = NULL;

 

After the declaration of the function pointer next step is to initialize it with function address.

pfAddTwoNumber = AddTwoNumber;

 

Now we can call the function using the function pointer with the help of indirection operator ( * )and braces.

//Calling the function using the function pointer
iRetValue = (*pfAddTwoNumber)(10,20);

        or
//Calling the function using the function pointer			  
iRetValue = pfAddTwoNumber(10,20);

 

Note: You can omit the indirection operator at the time of function call using the function pointer.

 




5) Function pointer as arguments

We can pass the function pointer as an argument into the function. Let’s take an example to understand how to pass a function pointer in a function and what its benefits.

In the below example code, I am creating a function ArithMaticOperation that takes three arguments two integers and one function pointer. This function will invoke the passed function using the function pointer which performs the arithmetic operation on the passed integer variable.

The benefit is that using one function user can perform multiple arithmetic operations. Like addition, subtraction, multiplication, and division of two numbers.

#include <stdio.h>

typedef  int (*pfunctPtr)(int, int); /* function pointer */

//function pointer as arguments
int ArithMaticOperation(int iData1,int iData2, pfunctPtr Calculation)
{
    int iRet =0;

    iRet = Calculation(iData1,iData2);

    return iRet;
}

/*function add two number*/
int AddTwoNumber(int iData1,int iData2)
{
    return (iData1 + iData2);
}

/*function subtract two number*/
int SubTwoNumber(int iData1,int iData2)
{
    return (iData1 - iData2);
}

/*function multiply two number*/
int MulTwoNumber(int iData1,int iData2)
{
    return (iData1 * iData2);
}


int main()
{
    int iData1 = 0;
    int iData2 = 0;
    int iChoice = 0;
    int Result = 0;

    printf("Enter two Integer Data \n\n");
    scanf("%d%d",&iData1,&iData2);

    printf("Enter 1 for Addition \n\n");
    printf("Enter 2 for Subtraction \n\n");
    printf("Enter 3 for Multiplication \n\n");

    printf("User choice :");
    scanf("%d",&iChoice);

    switch(iChoice)
    {
    case 1:
        Result = ArithMaticOperation(iData1,iData2,AddTwoNumber);
        break;

    case 2:
        Result = ArithMaticOperation(iData1,iData2,SubTwoNumber);
        break;

    case 3:
        Result = ArithMaticOperation(iData1,iData2,MulTwoNumber);
        break;

    default:
        printf("Enter Wrong Choice\n\n");
    }

    printf("\n\nResult  = %d\n\n",Result);

    return 0;
}

OutPut:

 

 

 

 

 

6) Return a function pointer from the function

Yes, we can return function pointer from the function. See the below code where I am returning a function pointer from the function. In the example code, I am using a typedef for defining a type for a function pointer. If you are new and want to learn about the typedef you can see below articles,

 

#include <stdio.h>

/* type declartion of function pointer */
typedef  int (*pfunctPtr)(int, int);

/*function add two number*/
int AddTwoNumber(int iData1,int iData2)
{
    return (iData1 + iData2);
}

/*function subtract two number*/
int SubTwoNumber(int iData1,int iData2)
{
    return (iData1 - iData2);
}

/*function multiply two number*/
int MulTwoNumber(int iData1,int iData2)
{
    return (iData1 * iData2);
}

//Return function pointer
pfunctPtr ArithMaticOperation(int iChoice)
{
    //function pointer
    pfunctPtr pArithmaticFunction = NULL;

    switch(iChoice)
    {
    case 1:

        pArithmaticFunction = AddTwoNumber;

        break;

    case 2:

        pArithmaticFunction = SubTwoNumber;

        break;

    case 3:

        pArithmaticFunction = MulTwoNumber;

        break;

    }


    return pArithmaticFunction;
}



int main(void)
{
    int iData1 = 0;
    int iData2 = 0;
    int iChoice = 0;
    int Result = 0;
    pfunctPtr pArithmaticFunction = NULL; //function pointer

    printf("Enter two Integer Data \n\n");
    scanf("%d%d",&iData1,&iData2);

    printf("Enter 1 for Addition \n\n");
    printf("Enter 2 for Subtraction \n\n");
    printf("Enter 3 for Multiplication \n\n");

    scanf("%d",&iChoice);

    pArithmaticFunction = ArithMaticOperation(iChoice);

    //verify the pointers
    if(pArithmaticFunction != NULL)
    {
        Result = (*pArithmaticFunction) (iData1,iData2);
        printf("Result  = %d\n\n",Result);
    }
    else
    {
        printf("Please enter the valid choice\n");
    }

    return 0;
}

 

OutPut:

 

 

 

 

 

 

7) Use of array of function pointers

We can create an array of function pointers like another pointer. The array of function pointers offers the facility to access the function using the index of the array.

Let us see an example where we are creating an array of function pointers and initializing it with functions. The signature of the function pointer and function must be the same. In this example, each function takes two integers and returns one integer. So let see the code,

 

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

//Add two number
int AddTwoNumber(int iData1,int iData2)
{
    return (iData1 + iData2);
}

//Subtract two number
int SubTwoNumber(int iData1,int iData2)
{
    return (iData1 - iData2);
}

//Multilply two number
int MulTwoNumber(int iData1,int iData2)
{
    return (iData1 * iData2);
}


// Main function
int main(int argc, char *argv[])
{

    int iRetValue = 0;

    //Declaration of array of function pointer
    int (*apfArithmatics [3])(int,int) = {AddTwoNumber,SubTwoNumber,MulTwoNumber};


    //Calling the Add function using index of array

    iRetValue = (*apfArithmatics [0])(20,10);

    //display addition of two number
    printf("\n\nAddition of two number = %d\n\n",iRetValue);

    //Calling the subtract function using index of array

    iRetValue = (*apfArithmatics[1])(20,10);

    //display subtraction of two number
    printf("\n\nsubtraction of two number = %d\n\n",iRetValue);

    //Calling the multiply function using index of array

    iRetValue = (*apfArithmatics[2])(20,10);

    //display multiplication  of two number
    printf("\n\nmultiplication of two number = %d\n\n",iRetValue);


    return 0;
}

OutPut:

 

 

 

 

 

8) Use of typedef with the function pointer

Using a typedef, we can make the declaration of function pointer easy and readable. The typedef is very helpful when we create an array of the function pointer or a function returns a function pointer. Let us see the example,

//typedef of array of function pointers
typedef int (*apfArithmatics[3])(int,int);

 

Now, apfArithmatics is a type of array of a function pointer and we can create a variable using this created type. Let us see the example where we have created a variable and initializing it by three functions AddTwoNumber, SubTwoNumber, and MulTwoNumber.

apfArithmatics aArithmaticOperation = { AddTwoNumber,SubTwoNumber,MulTwoNumber };

 

Some times in the code we need to typecast the address using the function pointer. It also becomes easy using the typedef.

void *pvHandle = NULL;
int (*pf)(int) = (int (*)(int)) pvHandle;

 

Now using typedef,

typedef int (*pf)(int);
pf JumptoApp  =  (pf)pvHandle;

 

For more knowledge, you can see below articles,

 

 

9) function pointers in the structure

C is not an object-oriented language, so it does not contain the member functions like C++. In short, In C language we can’t create the function in structure the C language. But using the function pointer we can provide these features. These function pointer will treat like the member function and we can also support polymorphism in C.

For more detail, you see below articles,

 

struct SERVER_COM
{
    int iLenData;

    void (*pfSend)(const char *pcData,const int ciLen);

    int (*pfRead)(char *pData);

} GATEWAYCOM;

 

10) Function pointer as a callback function

For windows, in a kernel-mode driver (KMDF), we use a lot of call back functions for the plug and play and device preparation. Each callback function is invoked by the operating system at specific events but we need to register to call back function using the function pointer.

Let’s take an example, suppose there is a callback function MyUsbEvtDevicePrepareHardware. In this callback function, the driver does whatever is necessary to make the hardware ready to use. In the case of a USB device, this involves reading and selecting descriptors.

// callback function
NTSTATUS
MyUsbEvtDevicePrepareHardware (
    _In_ WDFDEVICE Device,
    _In_ WDFCMRESLIST ResourceList,
    _In_ WDFCMRESLIST ResourceListTranslated
)
{
    //Code as per the requirements
}

 

Function pointer use to register the above call-back function.

NTSTATUS (*pfPrepareHardware) (

    _In_ WDFDEVICE Device,
    _In_ WDFCMRESLIST ResourceList,
    _In_ WDFCMRESLIST ResourceListTranslated

);

 

We know that the name of the function is the beginning address of the function, so we can initialize the function pointer using the function name.

pfPrepareHardware = MyUsbEvtDevicePrepareHardware;

Now we can use pfPrepareHardware for the registration of MyUsbEvtDevicePrepareHardware.

 

Advantage of function pointers in C:

There are a lot of advantages to the function pointers. Below we have mentioned some advantages of a function pointer. If you know more advantages of the function pointer, you can write in the comment box.

  • A function pointer can point to a function of the same signature and it can invoke the pointed function whenever required in the program. Check this article for more details, Application of function pointers.
  • A function pointer can pass as an argument in function so we can create a generic function that performs the operation as per the user choice. Like the qsort function, it can sort the numbers in increasing or decreasing order.
  • Using the function pointer we can jump from one application to another.
  • A function pointer helps to access the function of the DLL in windows. Check this article for more detail, How to create DLL?
  • A Function pointer provides the run time binding (polymorphism). Check this article for more details, How to use a function pointer in structure?
  • Using the function pointer, you can create a state machine in C. You can check Article, How to implement state machine in C?
  • You can replace the nested switch with the array using the function pointer. Check this article for more details, Replace nested switch case with the array using function pointers.

 

 

You want to learn more about C Pointers, you can check the below articles.

Your opinion matters

Although here I have tried to discuss a lot of points regarding the function pointer I would like to know your opinion on the function pointer in structure. So please don’t forget to write a comment in the comment box.