This C Tutorial explains Callback Functions in C with examples.
Callback function technique is useful where you need to write a function that’s able to perform several different functions at a point or can perform a function specified only by the caller. Callback Functions in C is a technique required to pass a pointer-to-function to another routine, which calls back the user function to perform some task. Function calls back user’s function is called callback function.
For example, suppose we have to write a program which has to deal with different Linked Lists with different value types and we have to search a given value of particular type in a Linked List with that type of value, say, search an integer in a Linked List with integers values, search a text string in a list with string values etc..
Of course, we can write one function each for searching a value of particular type in a list with that type of values and calling the appropriate function. For example,
To search an integer,
search_ints(root, 6);
To search a string,
search_str(root, "hello");
How beautiful would it be if we are able to write a function that can search value of any type. Here pointer-to-function plays role. Here, caller writes the required function and passes pointer to it as an argument to search function which calls back user’s function to perform the task. Also, we pass pointer to value rather than value and this is received into type void const * at called function’s side.
Let’s understand it using a program below,
/* callback.c -- program implements callback technique to search a linked * list for a given value */ #include <stdio.h> #include <stdlib.h> #include <string.h> int compare_ints(void const *, void const *); /* function prototype */ Node *search_list(Node *, void const *, int (void const *, void const *)); /* prototype */ int main(void) { int (*compare)(void const *, void const *) = compare_ints; int value, val2find; int nodes; /* nodes count*/ Node **rootp; /* pointer-to-root */ Node *desired_node; puts("\n**Program creates Singly Linked List**"); puts("**And allows users to perform various operations on the" " list**\n"); puts("User, specify number of nodes in the list, in range 1" " through some positive no."); scanf("%d", &nodes); /* let's create list with specified nodes */ rootp = create_sll(nodes); printf("Let's insert %d integers in the list...\n", nodes); insert_data(rootp); puts("**Let's show up the list**"); show_list(rootp); puts("Let's sort the list, in ascending order..."); sort_list(rootp); puts("**Let's show up the list**"); show_list(rootp); puts("**Let's use Callback() function**"); printf("User, enter an integer you want to see into the " "Singly Linked List...\n"); scanf("%d", &val2find); /* call to callback function */ desired_node = search_list(*rootp, &val2find, compare); /* Let's confirm whether desired value is found or not */ if (desired_node != NULL) puts("Desired value is found."); else puts("Desired value NOT found."); return 0; } /* search_list() is a typeless callback function in C */ /* * 3rd argument to search_list() is pointer-to-function, search_list() * calls back this function to compare values */ Node *search_list(Node *node, void const *value, int compare(void const *, void const *)) { while (node != NULL) { if (compare(&node->data, value) == 0) break; node = node->link; } return node; } /* compare_ints() compares the integers */ int compare_ints(void const *p2nv, void const *p2v) { if (*(int *)p2nv == *(int *)p2v) return 0; else return 1; }
/* sll_header.h -- here's contained all header declarations for a * singly linked list */ #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct NODE { struct NODE *link; /* ptr-to-self_ref_struct */ int data; } Node; Node **create_sll(const int); /* fun. returns ptr-to-root */ void insert_data(Node **); void show_list(Node **); /* fun. shows up data in the list */ void sort_list(Node **); /* sorting list using selection sort */ #include "sll_op.c"
/* * sll_operations.c -- here's contained all the definitions of * different operations performed on a singly linked list */ Node **create_sll(const int nodes) { int i; Node *current; static Node *root; Node **rootp = &root; /* ptr-to-root */ /* Let's allocate memory dynamically */ root = (Node *)malloc(nodes * sizeof(Node)); /* verify if dynamic allocation successful */ if (root == NULL) { puts("Error: Not Enough Memory!"); exit(1); } else { /* Create the list */ current = root; /* current set to the start of dynamic allocation */ for (i = 1; i <= nodes; i++) { if (i == nodes) { current->link = NULL; } else { current->link = current + 1; current++; } } printf("List with %d nodes created successfully!\n", nodes); puts(""); } return rootp; } /* insert_data() inserts data into successive nodes in the list */ void insert_data(Node **linkp) { Node *next = *linkp; Node *current; /* Write integers into the list */ do { current = next; scanf("%d", &(current->data)); next = current->link; } while (current->link != NULL); puts(""); } /* show up data in the list */ void show_list(Node **linkp) { Node *next = *linkp; Node *current; /* Let's read data from the list */ do { current = next; printf("%d ", current->data); next = current->link; } while (current->link != NULL); puts("\n"); } /* sorting list using Selection Sort */ void sort_list(Node **linkp) { int temp; Node *current = *linkp; Node *next = current->link; /* Let's sort the list by sorting values */ while (current->link != NULL) { /* Outer while loop terminates when */ /* there's no next node to current node in the list */ while (next != NULL) { /* Inner while loop */ /* sorts the current value */ if (current->data > next->data) { /* swap the values */ temp = next->data; next->data = current->data; current->data = temp; } /* update the next value */ next = next->link; } /* current value is sorted */ /* update the current and next values */ current = current->link; next = current->link; } }
Let’s run the program and analyse the output
**Program creates Singly Linked List** **And allows users to perform various operations on the list** User, specify number of nodes in the list, in range 1 through some positive no. 5 List with 5 nodes created successfully! Let's insert 5 integers in the list... 32 53 1 08 4556 **Let's show up the list** 32 53 1 8 4556 Let's sort the list, in ascending order... **Let's show up the list** 1 8 32 53 4556 **Let's use Callback() function** User, enter an integer you want to see into the Singly Linked List... 53 Desired value is found. User, enter an integer you want to see into the Singly Linked List... 33 Desired value NOT found.
What if user wants to search a given string in a list with values as strings, now caller has to write a function to compare strings and passes pointer-to-it in search_list(). Let’s use string comparison function strcmp() and search_list() function becomes
/* compiler converts function name into pointer-to-function */ /* strcmp is pointer to strcmp() function */ void *search_list(Node *, Void const*, strcmp) { int result; result = strcmp(node->data, "string to be searched"); if (result == 0) break; /* string in list */ }
So, we noticed that how pointer-to-function simplified search operation by calling just one search_list() function.
Sanfoundry Global Education & Learning Series – 1000 C Tutorials.
- Practice BCA MCQs
- Practice Computer Science MCQs
- Check C Books
- Apply for C Internship
- Apply for Computer Science Internship