YouTip LogoYouTip

C Fun Pointer Callback

# C Function Pointers and Callback Functions In C programming, pointers are not limited to pointing to variables or memory addresses of data types (such as `int`, `char`, or arrays). They can also point to executable code in memory. These are known as **Function Pointers**. Function pointers allow you to pass functions as arguments, return them from other functions, and store them in arrays. This capability is the foundation of **Callback Functions** in C. --- ## 1. Function Pointers A **Function Pointer** is a pointer variable that stores the address of a function. Once a function pointer is assigned the address of a function, it can be used to invoke that function just like a regular function call. ### Syntax and Declaration To declare a function pointer, you must match the exact signature (return type and parameter types) of the target function. ```c /* Declaration of a function pointer type using typedef */ typedef int (*fun_ptr)(int, int); ``` * **`int`**: The return type of the function. * **`(*fun_ptr)`**: The pointer variable name. The parentheses around `*fun_ptr` are mandatory. Without them, `int *fun_ptr(int, int)` would declare a function that returns an `int*` (integer pointer). * **`(int, int)`**: The parameter list of the function. --- ### Code Example: Basic Function Pointer The following example demonstrates how to declare a function pointer, assign a function's address to it, and call the function through the pointer. ```c #include // A simple function that returns the maximum of two integers int max(int x, int y) { return x > y ? x : y; } int main(void) { /* * Declare 'p' as a pointer to a function taking two ints and returning an int. * Assign the address of 'max' to 'p'. * Note: The address-of operator '&' is optional. 'max' alone also decays to a function pointer. */ int (*p)(int, int) = &max; int a, b, c, d; printf("Please enter three numbers: "); if (scanf("%d %d %d", &a, &b, &c) != 3) { printf("Invalid input.\n"); return 1; } /* * Invoke the function using the pointer 'p'. * This is equivalent to calling: d = max(max(a, b), c) */ d = p(p(a, b), c); printf("The largest number is: %d\n", d); return 0; } ``` #### Compilation and Output ```bash Please enter three numbers: 1 2 3 The largest number is: 3 ``` --- ## 2. Callback Functions ### What is a Callback Function? A **Callback Function** is a function that is passed to another function as an argument, to be called (or "called back") during the execution of that function. In simple terms: *A callback is a function you implement, but someone else's code (or a library function) executes.* > **An Analogy to Understand Callbacks:** > > Imagine you go to a store to buy an item, but it is currently out of stock. You leave your phone number with the clerk. A few days later, the item arrives. The clerk dials your number, and you go to the store to pick up your item. > > In this scenario: > * Your **phone number** is the *callback function*. > * Leaving your number with the clerk is **registering the callback**. > * The item arriving is the **event** that triggers the callback. > * The clerk calling you is the **execution of the callback**. > * You going to the store to pick up the item is the **response to the callback event**. --- ### Code Example: Implementing a Callback In this example, the function `populate_array` accepts a function pointer as its third parameter. It uses this pointer to populate an array with values generated by the callback function. We define `getNextRandomValue` as our callback function, which returns a random integer. ```c #include #include /* * A function that populates an array. * The third parameter is a function pointer that takes no arguments and returns an int. */ void populate_array(int *array, size_t arraySize, int (*getNextValue)(void)) { for (size_t i = 0; i < arraySize; i++) { // Call the callback function to get a value for each element array = getNextValue(); } } // Callback function: Generates a random value int getNextRandomValue(void) { return rand(); } int main(void) { int myarray; /* * Pass 'getNextRandomValue' as the callback argument. * Note: Do NOT append parentheses '()' to 'getNextRandomValue' here. * Passing 'getNextRandomValue()' would pass the evaluated integer return value * instead of the function pointer itself, causing a compilation error. */ populate_array(myarray, 10, getNextRandomValue); // Print the populated array for(int i = 0; i < 10; i++) { printf("%d ", myarray); } printf("\n"); return 0; } ``` #### Compilation and Output ```bash 16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709 ``` --- ## 3. Key Considerations and Best Practices 1. **Operator Precedence**: Always wrap the pointer name and the asterisk in parentheses when declaring a function pointer (e.g., `int (*ptr)(void)`). Omitting them changes the meaning entirely: * `int (*ptr)(void);` $\rightarrow$ A pointer to a function returning `int`. * `int *ptr(void);` $\rightarrow$ A function returning a pointer to an `int`. 2. **Type Safety**: The signature of the function pointer must match the signature of the assigned function exactly (including return type, parameter types, and const-qualifiers). Mismatches can lead to undefined behavior. 3. **Using `typedef` for Readability**: Complex function pointer declarations can quickly become unreadable. Use `typedef` to define clean, reusable alias names for your function pointer types: ```c typedef void (*CallbackType)(int); void register_callback(CallbackType cb); ```
← Java Print MultiplicationtableJsref Find β†’