C Programming: Callback Functions 🎯

beginner
22 min

C Programming: Callback Functions 🎯

Welcome to a comprehensive guide on Callback Functions in C Programming! In this lesson, we'll dive deep into understanding what callback functions are, why they're important, and how to effectively use them. Let's get started!

Understanding Callback Functions πŸ“

Callback functions, often referred to as "higher-order functions," are functions that are passed as arguments to other functions or returned from other functions. They allow you to build modular and reusable code by enabling functions to interact with each other more efficiently.

Why Callback Functions? πŸ’‘

  • Flexibility: Callbacks provide the ability to customize the behavior of functions in a modular way.
  • Asynchronous Programming: Callbacks are essential for handling asynchronous operations like network requests, file I/O, and timers.

Defining and Using Callback Functions 🎯

Let's start with a simple example of a callback function:

c
#include <stdio.h> void printNumber(int num) { printf("The number is: %d\n", num); } void callPrintNumber(int num, void (*callback)(int)) { callback(num); } int main() { int myNumber = 42; callPrintNumber(myNumber, printNumber); return 0; }

In the example above, we have defined a function printNumber and a function callPrintNumber. The printNumber function is the callback that takes an integer as an argument and prints it. The callPrintNumber function accepts two argumentsβ€”an integer and a callback functionβ€”and calls the callback with the provided integer.

Callback Function with Asynchronous Operations πŸ’‘

Callback functions are often used with asynchronous operations. Let's explore an example of a callback function with a network request:

c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> void callback(const char* data) { printf("Received data: %s\n", data); } int create_socket(int *socket_desc) { int sock = 0, val = 1; struct sockaddr_in serv_addr; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("Socket creation error\n"); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); // Zero-out the struct for initialization memset((char *) &serv_addr, '\0', sizeof(serv_addr)); serv_addr.sin_addr.s_addr = INADDR_ANY; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { printf("Setsockopt error\n"); return -1; } if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { printf("bind failed. Error is: %d\n", errno); return -1; } listen(sock, 3); if (*socket_desc != 0) close(*socket_desc); *socket_desc = sock; return 0; } int main(int argc, char *argv[]) { int socket_desc, addrlen = sizeof(struct sockaddr_in); create_socket(&socket_desc); struct sockaddr_in client; memset((char *) &client, '\0', sizeof(client)); client.sin_family = AF_INET; client.sin_port = htons(8080); // convert IPv4 address from text to binary form if (inet_pton(AF_INET, "127.0.0.1", &client.sin_addr) <= 0) { printf("Invalid address/ Address not supported\n"); return 1; } socklen_t client_len = sizeof(client); int new_socket = accept(socket_desc, (struct sockaddr *) &client, &client_len); if (new_socket < 0) { printf("accept failed\n"); return 1; } char buffer[1024] = {0}; read(new_socket, buffer, 1024); printf("Received data: %s\n", buffer); return 0; }

In this example, we have a callback function that accepts a string and prints it. The create_socket function creates a socket and waits for a connection. When a connection is established, it reads data from the client and calls the callback function to print the received data.

Quick Quiz
Question 1 of 1

What is the main purpose of callback functions in C programming?

That's it for our comprehensive guide on C Callback Functions! We've covered the basics of callback functions, their importance, and how to define and use them. Happy coding! πŸš€