Function Pointers in C

Mar 4, 2022

Introduction

Welcome! If you're reading this, you're probably curious about function pointers in C. This topic can seem tricky at first, but once you understand it, it opens up a whole new level of flexibility in your programming. Function pointers allow you to create dynamic and reusable code, making your programs more efficient and modular.

This article is part of Byte-Sized Learning, a series where I explore essential programming concepts in a concise and practical way. Whether you're revisiting this topic or learning it for the first time, I hope you find it useful.

Understanding Function Pointers

In C, functions themselves are not variables, but you can create pointers to functions. These function pointers can be assigned, passed as arguments, or even stored in data structures. They are commonly used in callbacks, event-driven programming, and for implementing efficient lookup tables.

To make things clearer, let's go through an example where we implement a basic calculator that uses function pointers to dynamically select operations.

Function Pointer Basics

A function pointer in C is declared as follows:

return_type (*pointer_name)(parameter_list);
return_type (*pointer_name)(parameter_list);

For example, a pointer to a function that takes two integers and returns an integer is declared as:

int (*operation)(int, int);
int (*operation)(int, int);

Now, let’s implement a small calculator using function pointers.

Implementing a Simple Calculator

We'll create functions for addition, subtraction, multiplication, and division, and use a function pointer to select the appropriate operation at runtime.

#include <stdio.h>
 
// Function declarations
int add(int, int);
int subtract(int, int);
int multiply(int, int);
int divide(int, int);
 
// Function pointer typedef
typedef int (*operation_func)(int, int);
 
// Function to select and apply an operation
int calculate(int a, int b, operation_func op) {
    return op(a, b);
}
 
int main() {
    int choice, a, b;
    operation_func operations[] = {add, subtract, multiply, divide};
 
    printf("Select operation:\n");
    printf("0: Add\n1: Subtract\n2: Multiply\n3: Divide\n");
    scanf("%d", &choice);
 
    if (choice < 0 || choice > 3) {
        printf("Invalid choice!\n");
        return 1;
    }
 
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);
 
    if (choice == 3 && b == 0) {
        printf("Error: Division by zero!\n");
        return 1;
    }
 
    int result = calculate(a, b, operations[choice]);
    printf("Result: %d\n", result);
 
    return 0;
}
 
// Function definitions
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }
#include <stdio.h>
 
// Function declarations
int add(int, int);
int subtract(int, int);
int multiply(int, int);
int divide(int, int);
 
// Function pointer typedef
typedef int (*operation_func)(int, int);
 
// Function to select and apply an operation
int calculate(int a, int b, operation_func op) {
    return op(a, b);
}
 
int main() {
    int choice, a, b;
    operation_func operations[] = {add, subtract, multiply, divide};
 
    printf("Select operation:\n");
    printf("0: Add\n1: Subtract\n2: Multiply\n3: Divide\n");
    scanf("%d", &choice);
 
    if (choice < 0 || choice > 3) {
        printf("Invalid choice!\n");
        return 1;
    }
 
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);
 
    if (choice == 3 && b == 0) {
        printf("Error: Division by zero!\n");
        return 1;
    }
 
    int result = calculate(a, b, operations[choice]);
    printf("Result: %d\n", result);
 
    return 0;
}
 
// Function definitions
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }

Breakdown of the Code

  • We declare four functions (add, subtract, multiply, and divide) that perform basic arithmetic operations.
  • We use a typedef for operation_func, making it easier to define function pointers.
  • We store function pointers in an array operations[], allowing us to select the operation dynamically.
  • The calculate function takes two integers and a function pointer, applying the selected operation.
  • The main function prompts the user for input and calls calculate with the appropriate function pointer.

Sample Output

Select operation:
0: Add
1: Subtract
2: Multiply
3: Divide
1
Enter two numbers: 10 3
Result: 7
Select operation:
0: Add
1: Subtract
2: Multiply
3: Divide
1
Enter two numbers: 10 3
Result: 7

This example demonstrates how function pointers enable flexibility in choosing functions dynamically, making the program more modular and extensible.

Conclusion

Function pointers are a powerful feature in C, allowing for dynamic function selection, modular code design, and efficient implementations of common patterns like callback functions. By understanding their syntax and applications, you can write more flexible and reusable code.

Try modifying the calculator to add more operations or error handling! If you have any questions or feedback, feel free to reach out to me on Twitter @prashantjoshi09. Happy coding! 😎