C Callback Functions
In this page:
void function_name(return_type (*callback)(parameter_types)) {
callback(arguments);
}
function_name(callback_function);
What is a Callback?
A callback is a function you hand to another function as an argument, so that receiving function can call it back at the appropriate moment during its own execution, rather than the caller controlling exactly when it runs.
This inversion of control is what lets library code stay generic while still letting your specific logic run at the right point.
Example: What is a Callback?
// Include standard input/output (printf, scanf)
#include <stdio.h>
void sayHello() {
// Print formatted text to the screen
printf("Hello");
}
void runCallback(void (*callback)()) {
callback();
}
// Program execution starts in main()
int main() {
runCallback(sayHello);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Creating a Simple Callback
To accept a callback, a function declares one of its parameters as a function pointer type, then invokes that parameter like a normal function call wherever the customizable behavior should happen.
This separates the fixed control-flow logic (like iterating over a list) from the variable part (what to do with each element), which the caller supplies.
Example: Creating a Simple Callback
// Include standard input/output (printf, scanf)
#include <stdio.h>
void greet() {
// Print formatted text to the screen
printf("Hi there");
}
void doAction(void (*action)()) {
action();
}
// Program execution starts in main()
int main() {
doAction(greet);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Callbacks with Parameters
A callback's own signature can include parameters, letting the calling function pass computed values — like the current array element or an index — directly into your custom logic each time it's invoked.
This lets one generic driver function support many different callbacks that each need different pieces of context to do their job.
Example: Callbacks with Parameters
// Include standard input/output (printf, scanf)
#include <stdio.h>
void printSquare(int x) {
// Print formatted text to the screen
printf("%d", x * x);
}
void process(int value, void (*callback)(int)) {
callback(value);
}
// Program execution starts in main()
int main() {
process(5, printSquare);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Filtering Arrays with Callbacks
Passing a callback into a generic array-processing function lets that same function filter, transform, or inspect elements differently depending only on which callback was supplied, without duplicating the loop logic for each use case.
This is the same pattern behind functions like a custom filterArray(arr, n, predicateFn).
Example: Filtering Arrays with Callbacks
// Include standard input/output (printf, scanf)
#include <stdio.h>
int isEven(int n) {
// Send n % 2 == 0 back to the caller
return n % 2 == 0;
}
void filterPrint(int arr[], int size, int (*test)(int)) {
// Loop: repeat while the condition holds
for (int i = 0; i < size; i++) {
// Check whether test(arr[i])
if (test(arr[i])) {
// Print formatted text to the screen
printf("%d ", arr[i]);
}
}
}
// Program execution starts in main()
int main() {
int nums[4] = {1, 2, 3, 4};
filterPrint(nums, 4, isEven);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Benefits and Use Cases of Callbacks
Callbacks are what make library functions like qsort() genuinely general-purpose: qsort() itself has no idea how to compare your specific data, so it delegates that decision entirely to the comparison callback you pass in.
This lets a single sorting implementation work correctly on integers, strings, structs, or anything else you define a comparator for.
Example: Benefits and Use Cases of Callbacks
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
int compareInts(const void *a, const void *b) {
// Send (*(int*)a - *(int*)b) back to the caller
return (*(int*)a - *(int*)b);
}
// Program execution starts in main()
int main() {
int arr[3] = {3, 1, 2};
qsort(arr, 3, sizeof(int), compareInts);
// Print formatted text to the screen
printf("%d %d %d", arr[0], arr[1], arr[2]);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
- Passing a callback whose signature does not match what the receiving function expects.
- Calling a callback pointer that is
NULLwithout checking it first. - Writing the function name with parentheses when passing it, which calls it instead of passing the address.
Chapter Quiz — Complete all 20 topics to unlock
0/20 topics done
Complete these topics first:
- C typedef
- C Type Casting
- C Bit Fields
- C Variable Length Arrays
- C Command Line Arguments
- C Function Pointers
- C Callback Functions
- C Multidimensional Pointer
- C string.h Functions
- C stdlib.h Functions
- C math.h Functions
- C time.h Functions
- C ctype.h Functions
- C errno.h
- C assert.h
- C Error Handling
- C Debugging Techniques
- C Code Style & Best Practices
- C Common Mistakes
- C Interview Questions