Function pointers are easy!
Function pointers in C are pointers that point to functions. In other words, while a regular pointer holds the address of a variable, a function pointer holds the address of a function. Function pointers are used for dynamic function calls - the function to be called can be decided at runtime.
Syntax
The syntax for declaring a function pointer is similar to a function declaration, with the name of the pointer wrapped in parentheses and preceded by an asterisk. For example, if you have a function int func(int, int)
, a pointer to this function is declared as int (*func_ptr)(int, int)
.
Sample Code
Here's a basic example:
#include <stdio.h>
// A simple function that adds two integers
int add(int a, int b) {
return a + b;
}
// A simple function that subtracts two integers
int subtract(int a, int b) {
return a - b;
}
// A function that takes a function pointer as an argument
void print_operation(int (*operation)(int, int), int a, int b) {
printf("Result: %d\n", operation(a, b));
}
int main() {
// Declaring function pointers for add and subtract
int (*func_ptr)(int, int);
int choice, a, b;
printf("Enter two numbers: ");
scanf("%d %d", &a, &b);
printf("Choose the operation:\n");
printf("1. Add\n");
printf("2. Subtract\n");
scanf("%d", &choice);
// Assigning the appropriate function to the function pointer
if (choice == 1) {
func_ptr = add;
} else if (choice == 2) {
func_ptr = subtract;
} else {
printf("Invalid choice\n");
return 1;
}
// Passing the function pointer to another function
print_operation(func_ptr, a, b);
return 0;
}
The provided C program demonstrates the use of function pointers to dynamically select and execute a function based on user input. The program has two basic arithmetic functions (add
and subtract
) and allows the user to choose which operation to perform at runtime. Let's break down and explain each part of the program:
Function Definitions
add
Function: This function takes two integers (a
andb
) as arguments and returns their sum (a + b
).subtract
Function: Similar toadd
, this function takes two integers and returns their difference (a - b
).
The print_operation
Function
Purpose: This function demonstrates the power of function pointers. It takes a function pointer (
operation
) as an argument along with two integers (a
andb
).Function Pointer Argument: The function pointer
operation
is expected to point to a function that takes two integers and returns an integer.Execution: Inside
print_operation
, the function pointed to byoperation
is called witha
andb
as arguments, and the result is printed.
The main
Function
Variable Declarations:
func_ptr
: A function pointer that can point to functions likeadd
andsubtract
.choice
,a
,b
: Variables to store user input.
User Input: The program asks the user to input two numbers and then choose an operation (1 for addition, 2 for subtraction).
Assigning the Function Pointer:
Based on the user's choice,
func_ptr
is assigned to point to either theadd
orsubtract
function.This assignment is crucial as it determines which function will be called later. The decision of which function
func_ptr
points to is made at runtime, not at compile time.
Dynamic Function Call:
The program then calls
print_operation
, passing it the function pointerfunc_ptr
and the user-provided numbersa
andb
.Since
func_ptr
can point to eitheradd
orsubtract
(based on the user's choice), the actual function call is dynamically determined at runtime.This demonstrates a key aspect of function pointers: the ability to defer the decision of which function to execute until runtime.
Runtime vs Compile Time
Compile Time: When the program is compiled, it's not determined which function (add or subtract) will be executed. The program is compiled knowing only that
func_ptr
will point to some function that matches the signatureint func(int, int)
.Runtime: It's only during the program's execution, after the user makes a choice, that
func_ptr
is assigned to a specific function (add
orsubtract
). Thus, the actual function call is resolved at runtime based on user input.
Use Cases
Function pointers are particularly useful in scenarios where behavior needs to be decided at runtime. They are commonly used in:
Callback Functions: Passing a function to another function to be called later.
Implementing Functionality Similar to Polymorphism: In scenarios where different functionalities need to be executed based on the context.
Table of Function Pointers: Often used in implementing state machines or lookup tables.
Example: Callback Functions
#include <stdio.h>
void greet(void (*callback)(const char*)) {
callback("Hello World!");
}
void englishGreeting(const char* message) {
printf("English: %s\n", message);
}
void spanishGreeting(const char* message) {
printf("Spanish: Hola Mundo!\n");
}
int main() {
greet(englishGreeting);
greet(spanishGreeting);
return 0;
}
In this example:
greet
is a function that takes a function pointer as a parameter. It calls this function, passing "Hello World!" as an argument.englishGreeting
andspanishGreeting
are callback functions.In
main
,greet
is called with different callback functions, demonstrating how behavior can be changed dynamically.
Function pointers add a lot of flexibility to C programs, enabling more dynamic and adaptable code structures.
Subscribe to my newsletter
Read articles from Jyotiprakash Mishra directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Jyotiprakash Mishra
Jyotiprakash Mishra
I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class. At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out. In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.