Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Industrial programming >> C Language

Function Pointers in C: Practical Examples and Best Practices

Function pointers unlock powerful capabilities in C, allowing functions to manipulate data directly through memory addresses rather than copying values. By passing addresses to pointer parameters, a function can modify the original variables, enabling patterns such as in‑place swapping, dynamic callbacks, and higher‑order functions.

Function Pointers Example

The classic swap routine demonstrates how a function can exchange the values of two variables by operating on their addresses.

void swap (int *a, int *b);
int main() {
  int m = 25;
  int n = 100;
  printf("m is %d, n is %d\n", m, n);
  swap(&m, &n);
  printf("m is %d, n is %d\n", m, n);
  return 0;
}
void swap (int *a, int *b) {
  int temp;
  temp = *a;
  *a = *b;
  *b = temp;
}

Output:

m is 25, n is 100
m is 100, n is 25

Function Pointers in C: Practical Examples and Best Practices

  1. Declare swap with two integer pointers.
  2. Initialize m and n in main and print them.
  3. Call swap(&m, &n) to pass the addresses.
  4. Inside swap, use a temporary variable to exchange the values.
  5. Dereference pointers to read/write the actual data.

Functions with Array Parameters

Arrays decay to pointers when passed to functions. The following program sums an array’s elements by iterating over the pointer.

int add_array (int *a, int num_elements);
int main() {
  int Tab[5] = {100, 220, 37, 16, 98};
  printf("Total summation is %d\n", add_array(Tab, 5)); 
  return 0;
}
int add_array (int *p, int size) {
  int total = 0;
  for (int k = 0; k < size; k++) {
    total += p[k];  /* equivalent to total += *p; p++; */
  }
  return total;
}

Output:

 Total summation is 471

Function Pointers in C: Practical Examples and Best Practices

  1. Define add_array to accept a pointer and size, returning the sum.
  2. Pass the array name Tab (which decays to a pointer) and its length to the function.

Functions that Return an Array

A function can return a pointer to a static array. This approach is useful when the caller needs a temporary array without managing memory allocation.

#include <stdio.h>
int * build_array();
int main() {
  int *a;
  a = build_array(); /* get first 5 even numbers */
  for (int k = 0; k < 5; k++)
    printf("%d\n", a[k]);
  return 0;
}
int * build_array() {
  static int Tab[5] = {1,2,3,4,5};
  return Tab;
}

Output:

1
2
3
4
5

Function Pointers in C: Practical Examples and Best Practices

  1. Declare a function that returns a pointer to a static array.
  2. Use the returned pointer to iterate and print the array contents.

Function Pointers

A function pointer holds the address of a function’s entry point, allowing dynamic dispatch and callbacks. The declaration syntax requires parentheses around the asterisk to avoid misinterpretation.

return_type (*function_name)(arguments)

Example: Call a routine through a pointer.

#include <stdio.h>
void Hi_function (int times); /* function */
int main() {
  void (*function_ptr)(int);  /* function pointer */
  function_ptr = Hi_function;  /* assignment */
  function_ptr(3);  /* invocation */
  return 0;
}
void Hi_function (int times) {
  for (int k = 0; k < times; k++)
    printf("Hi\n");
}

Output:

Hi
Hi
Hi

Function Pointers in C: Practical Examples and Best Practices

  1. Define a regular function.
  2. Declare a function pointer with the correct signature.
  3. Assign the pointer to the function’s name.
  4. Invoke the function through the pointer.

Array of Function Pointers

Storing multiple function pointers in an array enables a table‑driven approach, similar to a switch statement. The following program demonstrates a simple calculator.

#include <stdio.h>
int sum(int num1, int num2);
int sub(int num1, int num2);
int mult(int num1, int num2);
int divi(int num1, int num2);
int main() {
  int x, y, choice, result;
  int (*ope[4])(int, int);
  ope[0] = sum;
  ope[1] = sub;
  ope[2] = mult;
  ope[3] = divi;
  printf("Enter two integer numbers: ");
  scanf("%d%d", &x, &y);
  printf("Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: ");
  scanf("%d", &choice);
  result = ope[choice](x, y);
  printf("%d", result);
  return 0;
}
int sum(int x, int y) {return x + y;}
int sub(int x, int y) {return x - y;}
int mult(int x, int y) {return x * y;}
int divi(int x, int y) {return y != 0 ? x / y : 0;}

Result: Enter 13 48 2 → 624

Function Pointers in C: Practical Examples and Best Practices

  1. Define four arithmetic functions.
  2. Create an array of four function pointers with matching signatures.
  3. Assign each pointer to the corresponding function.
  4. Retrieve the user’s choice and call the selected function.

Functions Using void Pointers

Void pointers provide type‑agnostic access to data. When used in function parameters, they allow the routine to accept any data type, provided the caller supplies the correct cast.

void * cube (const void *);

Example program:

#include <stdio.h>
void* cube (const void* num);
int main() {
  int x = 4;
  int cube_int = (int)cube(&x);
  printf("%d cubed is %d\n", x, cube_int);
  return 0;
}
void* cube (const void *num) {
  int result = (*(int *)num) * (*(int *)num) * (*(int *)num);
  return (void*)result;
}

Result: 4 cubed is 64

Function Pointers in C: Practical Examples and Best Practices

  1. Define a function that accepts a const void pointer and returns a void pointer.
  2. Cast the pointer to int * to access the value.
  3. Compute the cube and cast the result back to void * for return.

Function Pointers as Arguments

Passing a function pointer to another function is a common pattern for callbacks. The standard library’s qsort uses this technique to sort arrays of arbitrary types.

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *));

Example that sorts an integer array:

#include <stdio.h>
#include <stdlib.h>
int compare (const void *, const void *); 
int main() {
  int arr[5] = {52, 14, 50, 48, 13};
  size_t num = sizeof(arr)/sizeof(arr[0]);
  size_t width = sizeof(arr[0]);
  qsort((void *)arr, num, width, compare);
  for (size_t i = 0; i < num; i++)
    printf("%d ", arr[i]);
  return 0;
}
int compare (const void *elem1, const void *elem2) {
  int a = *(int *)elem1;
  int b = *(int *)elem2;
  return (a - b);
}

Result: 13 14 48 50 52

Function Pointers in C: Practical Examples and Best Practices

  1. Implement compare to return negative, zero, or positive based on the two integers.
  2. Determine array size and element width with sizeof.
  3. Call qsort with the array, count, width, and comparison function.
  4. Print the sorted array to verify the operation.

C Language

  1. Mastering User-Defined Functions in C: A Step‑by‑Step Guide
  2. Four Proven Patterns for User‑Defined Functions in C
  3. Mastering C++ Pointers: Concepts, Examples & Practical Applications
  4. C++ Functions Explained with Practical Code Examples
  5. C# Hashtable Explained: Key-Value Storage, Operations, and Practical Examples
  6. Understanding Switch‑Case in C: Syntax, Examples, and Best Practices
  7. Master C Functions: Practical Examples of Recursion & Inline Techniques
  8. Master Python Lambda Functions: Practical Examples & Best Practices
  9. Mastering C Functions: Structure, Declaration, and Best Practices
  10. Master Python Extension Programming with C: Build Fast, Native Modules