Function Pointer in C

Filed Under: C Programming
C Function Pointer

A function pointer in C is a pointer that points to a function.

The C language has given a way for us to making certain statements execute faster, by allowing us to reference executable code within a function.

This reference involves the function pointer, which points to this code in memory (RAM).

Since we’re calling this function through a variable, such a call is called an indirect call to this function.

Let’s understand this, by illustrating how this reference is made to a simple swap() function.

C Swap Function Reference Asm
C Swap Function Reference Asm

If we were to make a function pointer that references the swap() function, it will point to the executable code, which is shown in the assembly language.

This will make the overall execution speed much faster, since we directly refer to a lower level code.

Now that we have our concepts covered, let’s look at how we can actually write a function pointer for our swap function.


Defining a Function Pointer

Before defining the function pointer, let’s break down what any function consists of.

Any function will have a return type, arguments passed to it, and a name, such as:

int function_name(char arg1, int arg2);

The function pointer simply points to such a function, so we can define a function pointer like this:

int (*function_ptr)(char, char);

This says that function_ptr is a function pointer which points to a function that takes 2 char arguments and returns an int.

Notice the enclosing parenthesis (*function_ptr). This is because we must explicitly specify that it is a pointer. Otherwise, the compiler may think that we are pointing to a function that returns int* and throw an error.

Similarly, for a function that is defined like this:

char* str_concat(char* a, char* b);

The function pointer is defined in this way:

char* (*function_ptr_2)(char*, char*);

Now that we’ve defined our function pointers, let’s now make a reference to the functions, by pointing to the function name.

function_ptr = &function_name;
function_ptr_2 = &str_concat;

Note that you don’t need to explicitly mention the referencing ampersand (&), since functions are implicitly passed as pointers anyway, so the following code is still valid.

function_ptr = function_name;
function_ptr_2 = str_concat;

Direct Initialization

Alternatively, we can directly point to the function during declaration itself, like any other pointer.

int (*function_ptr)(char, char) = function_name;
char* (*function_ptr_2)(char*, char*) = str_concat;

Now that we’ve looked at initializing the pointer, let’s now see it in action!


Using Function Pointers

This is really simple! We just need to de-reference our function pointer by passing appropriate arguments, and it will run the executable code which it is pointing to. That’s it!

return_value = (*function_ptr)(arg1, arg2);

Again, you don’t need to explicitly mention the de-referencing asterisk (*), since functions are implicitly passed as pointers anyway. But if you do, you must explicitly mention the parenthesis (*function_ptr)(arg1, arg2), since a function call has a higher precedence over a de-reference.

return_value = function_ptr(arg1, arg2);

If the function takes no arguments, you can pass void to the parameter list.

Let’s do this for our swap() function.

#include <stdio.h>

void swap(int* a, int* b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}

int main() {
    int a = 20;
    int b = 10;
    // swap(&a, &b);
    
    // Using function pointers
    void (*swap_ptr)(int*, int*) = swap;
    printf("Dereferencing the function pointer...\n");
    swap_ptr(&a, &b);

    printf("a = %d, b = %d\n", a, b);
    return 0;
}

Another Example

To complete this article, we’ll show you a complete example.

This is a simple calculator program that utilizes function pointers to handle cases easily. Elegant, isn’t it?

#include <stdio.h>

double add(double a, double b) {
    return a + b;
}

double sub (double a, double b) {
    return a - b;
}

double mul(double a, double b) {
    return a * b;
}

double div (double a, double b) {
    return a / b;
}

double zero(double a, double b) {
    return 0.0;
}

double calculator(double a, double b, char option) {
    double result = 0.0;
    double (*funct_ptr)(double, double);
    if (option == 'A')
        funct_ptr = add;
    else if (option == 'S')
        funct_ptr = sub;
    else if (option == 'M')
        funct_ptr = mul;
    else if (option == 'D')
        funct_ptr = div;
    else
        funct_ptr = zero;
    result = funct_ptr(a, b);
    return result;
}

int main() {
    printf("%lf\n", calculator(10, 5, 'A'));
    printf("%lf\n", calculator(10, 5, 'S'));
    printf("%lf\n", calculator(10, 5, 'M'));
    printf("%lf\n", calculator(10, 5, 'D'));
    return 0;
}

Output

15.000000
5.000000
50.000000
2.000000

Another way to make a function pointer point to multiple other function codes is with the use of a function pointer array. Have a look at the sample code below.

#include <stdio.h>

double add(double a, double b) {
    return a + b;
}
double sub (double a, double b) {
    return a - b;
}
double mul(double a, double b) {
    return a * b;
}
double div (double a, double b) {
    return a / b;
}
double zero(double a, double b) {
    return 0.0;
}

int main() {
    double (*funct_ptr[])(double, double)={add,sub,mul,div};
    printf("%lf\n", funct_ptr[0](5,6));
    printf("%lf\n", funct_ptr[1](5,6));
    printf("%lf\n", funct_ptr[2](5,6));
    printf("%lf\n", funct_ptr[3](5,6));
    return 0;
}
11.000000                                                                                                                                     
-1.000000                                                                                                                                     
30.000000                                                                                                                                     
0.833333

Conclusions

Hopefully, you’ve learned how you can use a function pointer in C. If you have any queries, do ask them on the comment section below!


References


Comments

  1. James says:

    The only one I don’t understand is why the following has an output of 1 instead of 11:

    funct_ptr[0](5,6));
    printf(“%lf\n”

    1. Pankaj says:

      Yes, you are right. I think the initial “1” missed while copy-pasting the output of the program. I have fixed it. Thanks for letting us know.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages