Skip to main content

Section 29.2 Callback Functions

A callback function is simply a function that is passed as an argument into another function, so that the other function can “call it back” when it needs it— this is done using function pointers. Callbacks let us write generic, reusable code once, and then reuse it many times by passing in a different callback to handle the custom computation. The only strict rule is that the functions being swapped around must all share the same prototype.
Here’s the simplest possible example— a function that repeats any no-argument, no-return function three times:

Compile and run the code below in your own C environment.

#include <stdio.h>

/* callback functions */
void sayHello();
void sayGoodbye();

/* master functions */
void repeatThreeTimes( void (* messageFunction) () );

int main(void){
	
	repeatThreeTimes(sayHello);
	repeatThreeTimes(sayGoodbye);

	return 0;
}

void sayHello(){
	printf("Hello!\n");
}

void sayGoodbye(){
	printf("Goodbye!\n");
}

void repeatThreeTimes( void (* messageFunction) () ){
	int i;
	for(i=0; i<3; i++){
		messageFunction();
	}
}
Callbacks become more useful once the callback itself takes and returns values. In the example below, calculate() doesn’t know or care whether it’s squaring, cubing, or taking a square root— it just calls whatever function op currently points to:

Compile and run the code below in your own C environment.

#include <stdio.h>
#include <math.h>

/* callback functions */
float fsquare(int num);
float fcube(int num);
float fsquareroot(int num);

/* master function */
float calculate(int num, float (*op)(int));

int main(void) {
	int num = 6;
	float result;

	result = calculate(num, &fsquare);
	printf("Square of %d: %f\n", num, result);
	result = calculate(num, &fcube);
	printf("Cube of %d: %f\n", num, result);
	printf("Square roof of %d: %f\n", num, calculate(num,&fsquareroot));

	return (0);
}

float calculate(int num, float (*op)(int)){
	float result;
	result = (*op)(num);
	return result;
}

float fcube(int num){
	return num * num * num;
}

float fsquare(int num){
	return num * num;
}

float fsquareroot(int num){
	return sqrt(num);
}

Activity 29.3.

Let’s upgrade our Bubble Sort code so that it can sort numbers in either ascending or descending order. The only thing that determines the sort order is the comparison if (array[i] > array[i+1]). Write two callback functions:
  • int ascending(int a, int b)— returns 1 if a > b
  • int descending(int a, int b)— returns 1 if a < b
Modify your Bubble Sort function to accept a callback as an extra argument, and inside the sort, replace your hardcoded if statement with a call to that callback. Test your code to sort in both ascending and descending order.

Compile and run the code below in your own C environment.

#include <stdio.h>
#define N 10 
/* Prototypes for square and cube functions */
void printArray(int array[], int size);
void bubble(int array[], int size);

int main(void){
	int list[]={42, 17, -5, 88, 3, 105, -21, 56, 9, 34};

	printf("Unsorted array:\n");
	printArray(list, N);
	bubble(list, N);
	printf("Sorted array:\n");
	printArray(list, N);

	return 0;
}

void bubble(int array[], int size){
	int i,j,swap;
	for(j=0; j<size-1; j++){
		for(i=0; i<size-1; i++){ 
			if(array[i] > array[i+1]){
				swap = array[i];
				array[i] = array[i+1];
				array[i+1] = swap;
			} 
		}
	}
}
void printArray(int array[], int size){
	int i;
	for(i=0; i<size; i++){
		printf("%d ", array[i]);
	}
	printf("\n");
}