Question
I want to write a C function that applies another function, passed in as a parameter, to a set of data. How can a function be passed as an argument in C?
Short Answer
By the end of this page, you will understand how C passes functions indirectly using function pointers. You will learn the syntax, how to declare and use function-pointer parameters, how calls work step by step, and where this pattern appears in real programs such as callbacks, sorting, and data processing.
Concept
In C, you do not pass a function directly in the same way you pass an int or a double. Instead, you pass a pointer to the function.
A function pointer stores the address of a function. If another function receives that address, it can call the pointed-to function later.
This matters because it lets you write generic and reusable code. Instead of hardcoding one behavior, you can let the caller decide what operation should happen.
For example, imagine you have a list of numbers and want to:
- print each number
- square each number
- check whether each number is even
Rather than writing three separate loops, you can write one reusable function that loops through the data and calls a passed-in function for each item.
In C, this pattern is common in:
- callback-based APIs
- sorting with
qsort - signal handlers
- event systems
- data transformation utilities
The key idea is:
- function name often acts like a pointer to that function
- function pointer type must match the function signature
- signature means return type + parameter types
If the signatures do not match, the behavior is incorrect and may cause warnings or bugs.
Mental Model
Think of a function pointer like a remote control with one programmed button.
- The function itself is the device that performs the action.
- The function pointer is the remote that knows which device to activate.
- Passing the function pointer to another function is like handing someone the remote so they can trigger that action when needed.
Another way to think about it:
- normal data variable: holds a value
- normal pointer: holds the address of data
- function pointer: holds the address of executable code
So instead of saying, "do this exact task," you are saying, "when the time comes, call whatever function lives at this address."
Syntax and Examples
Basic syntax
A function pointer must match the function's signature.
For a function like this:
int square(int x) {
return x * x;
}
A pointer to that function can be declared as:
int (*func_ptr)(int);
This means:
- returns
int - points to a function
- function takes one
int
You can assign the function to the pointer:
func_ptr = square;
And call it in either of these ways:
int result1 = func_ptr(5);
int result2 = (*func_ptr)(5);
Both are valid.
Passing a function as a parameter
#include <stdio.h>
int {
x * x;
}
{
operation(value);
}
{
result = apply(, square);
(, result);
;
}
Step by Step Execution
Consider this example:
#include <stdio.h>
int increment(int x) {
return x + 1;
}
int apply(int value, int (*fn)(int)) {
return fn(value);
}
int main(void) {
int result = apply(10, increment);
printf("%d\n", result);
return 0;
}
Step-by-step
mainstarts running.apply(10, increment)is called.- The value
10is passed intoapplyasvalue. - The function
incrementis passed intoapplyasfn.
Real World Use Cases
Function pointers are used whenever code needs to be flexible about what action should happen.
Common real-world uses
1. Sorting with custom rules
The C standard library function qsort accepts a comparison function pointer.
qsort(array, count, sizeof(int), compare_ints);
This lets you define how two items should be compared.
2. Callbacks in libraries
A library may let you register a function to be called later when something happens.
Examples:
- when data arrives
- when a timer expires
- when a button is clicked in a GUI toolkit
3. Processing collections
You can write reusable loops that apply different actions to each item.
- print each item
- validate each item
- transform each item
4. Error handling hooks
A framework may accept a custom error-reporting function.
5. Strategy selection
Different algorithms can be plugged into the same code path by passing different functions.
Real Codebase Usage
In real C codebases, function pointers often appear in patterns rather than isolated examples.
Common patterns
Guarding against NULL
A function pointer parameter may be optional. Developers often check it before calling.
void run_if_present(int value, void (*fn)(int)) {
if (fn == NULL) {
return;
}
fn(value);
}
This avoids crashes from calling a null function pointer.
Callbacks for configurable behavior
Instead of hardcoding behavior, code accepts a callback.
void process_event(void (*handler)(int), int code) {
if (handler != NULL) {
handler(code);
}
}
Separating iteration from action
One function handles looping; another handles what to do with each element.
void for_each(int *arr, int size, (*action)()) {
( i = ; i < size; i++) {
action(arr[i]);
}
}
Common Mistakes
1. Forgetting the parentheses in the declaration
This is one of the most common errors.
Broken code:
int *fn(int);
This does not mean “pointer to a function.” It means a function returning int *.
Correct code:
int (*fn)(int);
The parentheses are important because *fn must be grouped together.
2. Using the wrong function signature
Broken code:
int square(int x) {
return x * x;
}
void apply(void (*fn)(int)) {
fn(5);
}
apply(square);
Here, apply expects a function returning void, but square returns int.
Comparisons
Function pointer vs normal pointer
| Concept | Stores | Example |
|---|---|---|
| Normal pointer | Address of data | int *p |
| Function pointer | Address of a function | int (*fn)(int) |
Direct call vs function pointer call
| Style | Example | When used |
|---|---|---|
| Direct function call | square(5) | When the function is known in advance |
| Function pointer call | fn(5) | When the function is chosen dynamically |
Without vs with
Cheat Sheet
Quick syntax
Declare a function
int square(int x);
Declare a pointer to that function
int (*fn)(int);
Assign a function to the pointer
fn = square;
Call through the pointer
fn(5);
(*fn)(5);
Function as parameter
int apply(int value, int (*op)(int)) {
return op(value);
}
Using typedef
typedef int (*operation_fn)(int);
int {
op(value);
}
FAQ
How do you pass a function to another function in C?
You pass a function pointer. The receiving function declares a parameter whose type matches the passed function's signature.
What is the syntax for a function pointer in C?
A function pointer to a function returning int and taking one int looks like this:
int (*fn)(int);
Can I call a function pointer like a normal function?
Yes. If fn is a function pointer, you can write:
fn(5);
Do I need to use & when passing a function in C?
Usually no. Writing the function name is enough:
apply(5, square);
Why are parentheses required in function pointer declarations?
Without parentheses, C reads the declaration differently because of operator precedence. int (*fn)(int) means pointer to function, while int *fn(int) means function returning pointer.
Where are function pointers used in C?
They are commonly used in callbacks, , event handling, dispatch tables, and reusable processing functions.
Mini Project
Description
Build a small C program that processes an array of integers using a passed-in function. This demonstrates how one reusable loop can perform different actions depending on which function pointer it receives.
Goal
Create a reusable array-processing function that accepts a callback and applies it to each element.
Requirements
- Create at least two functions that each take one
intparameter. - Write a reusable function that accepts an integer array, its size, and a function pointer.
- Call the reusable function with different callback functions.
- Print output so the different behaviors are easy to see.
Keep learning
Related questions
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.
C printf Format Specifier for bool: How to Print Boolean Values
Learn how to print bool values in C with printf, why no %b/%B specifier exists, and the common patterns to print true/false or 0/1.
Calling C or C++ from Python: Building Python Bindings
Learn the quickest ways to call C or C++ from Python, including ctypes, C extensions, Cython, and binding tools with practical examples.