DEV Community

Shaikhul Islam
Shaikhul Islam

Posted on

Function Pointer in C

Taken from my personal blog post

Pointers in C are powerful and confusing at the same time. As we can point a pointer to structs, strings or arrays, we can point to function.

Signature: void (*POINTER_NAME) (args)

Say for example we have a function add that adds two number int add(int a, int b)

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

int mul(int a, int b) {
    return a * b;
}
Enter fullscreen mode Exit fullscreen mode

The function pointer for this would be

int (*fun_ptr) (int, int)
Enter fullscreen mode Exit fullscreen mode

We can assign this pointer to any function that accepts two int params and return an int.

To point to add function we can just assign it to the fun_ptr pointer as follows.

Now we can use the function pointer as follows

// assign it to add function
fun_ptr = add;
printf("2 + 3 = %d\n", fun_ptr(2, 3));

// assign it to mul function
fun_ptr = mul;
printf("2 * 3 = %d\n", fun_ptr(2, 3));
Enter fullscreen mode Exit fullscreen mode

Now if we want to use function pointer as a function param we can use it directly or use a typedef as follows

// it takes a function pointer as param
int do_op(int a, int b, int (*ptr) (int, int)) {
  return ptr(a, b);
}
printf("2 + 3 = %d \n", do_op(2, 3, add));
printf("2 + 3 = %d \n", do_op(2, 3, mul));
Enter fullscreen mode Exit fullscreen mode

As writing the function signature as a function param is hard, we can use the typedef to give it a new name

// using typedef
typedef int (*op_ptr_type) (int, int);
int do_op2(int a, int b, op_ptr_type ptr) {
  return ptr(a, b);
}
printf("2 + 3 = %d\n", do_op2(2, 3, add));
  printf("2 * 3 = %d\n", do_op2(2, 3, mul));
Enter fullscreen mode Exit fullscreen mode

Here is the complete example in repl.it

Now, lets see how qsort takes advantage of function pointer.

The method signature of qsort is

void qsort(void *ptr, size_t count, size_t size, int (*comp)(const void *, const void *));
Enter fullscreen mode Exit fullscreen mode

Here we can see the fourth param is a callback which is used to do custom comparison. If we want to sort some numbers in ascending order we need to define the comp function first using the same signature

int comp_int_asc(const void* a, const void* b) {
    // dereference to int
    int val1 = *(const int*)a;
    int val2 = *(const int*)b;

    if (val1 < val2) {
        return -1;
    } else if (val1 > val2) {
        return 1;
    }
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

we can use it in the qsort function as follows

int nums[] = {5, 1, 3, 9, 10, 8, -5, 0};
int int_size = sizeof(int);
int arr_len = sizeof(nums) / int_size;
// qsort is defined in stdlib
qsort(nums, arr_len, int_size, comp_int_asc);
Enter fullscreen mode Exit fullscreen mode

Here is the full qsort example

Top comments (0)