c
examples
examples.c🔧c
/**
* =============================================================================
* Function Pointers in C - Comprehensive Examples
* =============================================================================
*
* This file demonstrates function pointer concepts and patterns in C.
*
* Compile: gcc -Wall -Wextra -std=c99 -o examples examples.c -lm
* Run: ./examples
*
* =============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
// =============================================================================
// Example 1: Basic Function Pointer Declaration and Usage
// =============================================================================
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }
void example1_basic_function_pointers(void) {
printf("=== Example 1: Basic Function Pointer Declaration and Usage ===\n\n");
// Declare a function pointer
int (*operation)(int, int);
// Assign and use different functions
operation = add;
printf("add(10, 5) = %d\n", operation(10, 5));
operation = subtract;
printf("subtract(10, 5) = %d\n", operation(10, 5));
operation = multiply;
printf("multiply(10, 5) = %d\n", operation(10, 5));
operation = divide;
printf("divide(10, 5) = %d\n", operation(10, 5));
// Print function addresses
printf("\nFunction addresses:\n");
printf(" add: %p\n", (void*)add);
printf(" subtract: %p\n", (void*)subtract);
printf(" multiply: %p\n", (void*)multiply);
printf(" divide: %p\n", (void*)divide);
printf("\n");
}
// =============================================================================
// Example 2: Function Pointers as Parameters (Callbacks)
// =============================================================================
// Apply an operation to all elements
void transform_array(int *arr, int size, int (*transform)(int)) {
for (int i = 0; i < size; i++) {
arr[i] = transform(arr[i]);
}
}
// Transform functions
int double_value(int x) { return x * 2; }
int square_value(int x) { return x * x; }
int negate_value(int x) { return -x; }
int increment_value(int x) { return x + 1; }
void print_array(const char *label, int *arr, int size) {
printf("%s: [", label);
for (int i = 0; i < size; i++) {
printf("%d%s", arr[i], i < size - 1 ? ", " : "");
}
printf("]\n");
}
void example2_callbacks(void) {
printf("=== Example 2: Function Pointers as Parameters (Callbacks) ===\n\n");
int arr1[] = {1, 2, 3, 4, 5};
int arr2[] = {1, 2, 3, 4, 5};
int arr3[] = {1, 2, 3, 4, 5};
int arr4[] = {1, 2, 3, 4, 5};
int size = 5;
printf("Original: [1, 2, 3, 4, 5]\n\n");
transform_array(arr1, size, double_value);
print_array("Double ", arr1, size);
transform_array(arr2, size, square_value);
print_array("Square ", arr2, size);
transform_array(arr3, size, negate_value);
print_array("Negate ", arr3, size);
transform_array(arr4, size, increment_value);
print_array("Increment", arr4, size);
printf("\n");
}
// =============================================================================
// Example 3: Array of Function Pointers
// =============================================================================
void example3_array_of_function_pointers(void) {
printf("=== Example 3: Array of Function Pointers ===\n\n");
// Array of function pointers
int (*operations[])(int, int) = {add, subtract, multiply, divide};
const char *names[] = {"add", "subtract", "multiply", "divide"};
int count = sizeof(operations) / sizeof(operations[0]);
int a = 20, b = 4;
printf("Performing all operations on %d and %d:\n", a, b);
for (int i = 0; i < count; i++) {
printf(" %s(%d, %d) = %d\n", names[i], a, b, operations[i](a, b));
}
// Using index to select operation
printf("\nSelecting operation by index:\n");
int op_index = 2; // multiply
printf(" Operation[%d] is %s: %d\n",
op_index, names[op_index], operations[op_index](a, b));
printf("\n");
}
// =============================================================================
// Example 4: Typedef with Function Pointers
// =============================================================================
// Define function pointer types
typedef int (*BinaryOp)(int, int);
typedef void (*Callback)(const char*);
typedef double (*MathFunc)(double);
// Function returning function pointer (using typedef)
BinaryOp get_operation(char symbol) {
switch (symbol) {
case '+': return add;
case '-': return subtract;
case '*': return multiply;
case '/': return divide;
default: return NULL;
}
}
void example4_typedef_function_pointers(void) {
printf("=== Example 4: Typedef with Function Pointers ===\n\n");
// Using typedef makes code cleaner
BinaryOp op;
char symbols[] = {'+', '-', '*', '/'};
int a = 15, b = 3;
for (int i = 0; i < 4; i++) {
op = get_operation(symbols[i]);
if (op) {
printf("%d %c %d = %d\n", a, symbols[i], b, op(a, b));
}
}
// Array using typedef
printf("\nArray of MathFunc:\n");
MathFunc math_funcs[] = {sin, cos, tan, sqrt, log};
const char *func_names[] = {"sin", "cos", "tan", "sqrt", "log"};
double x = 1.0;
for (int i = 0; i < 5; i++) {
printf(" %s(%.1f) = %.6f\n", func_names[i], x, math_funcs[i](x));
}
printf("\n");
}
// =============================================================================
// Example 5: Generic Sorting with Comparators
// =============================================================================
// Generic comparison function type
typedef int (*CompareFunc)(const void*, const void*);
// Generic bubble sort (for demonstration)
void generic_bubble_sort(void *base, size_t count, size_t size, CompareFunc cmp) {
char *arr = (char*)base;
char *temp = malloc(size);
for (size_t i = 0; i < count - 1; i++) {
for (size_t j = 0; j < count - i - 1; j++) {
void *a = arr + j * size;
void *b = arr + (j + 1) * size;
if (cmp(a, b) > 0) {
memcpy(temp, a, size);
memcpy(a, b, size);
memcpy(b, temp, size);
}
}
}
free(temp);
}
// Comparator functions
int cmp_int_asc(const void *a, const void *b) {
return *(int*)a - *(int*)b;
}
int cmp_int_desc(const void *a, const void *b) {
return *(int*)b - *(int*)a;
}
int cmp_string(const void *a, const void *b) {
return strcmp(*(char**)a, *(char**)b);
}
int cmp_string_len(const void *a, const void *b) {
return strlen(*(char**)a) - strlen(*(char**)b);
}
void example5_generic_sorting(void) {
printf("=== Example 5: Generic Sorting with Comparators ===\n\n");
// Sort integers ascending
int numbers[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(numbers) / sizeof(numbers[0]);
printf("Original integers: ");
for (int i = 0; i < n; i++) printf("%d ", numbers[i]);
printf("\n");
generic_bubble_sort(numbers, n, sizeof(int), cmp_int_asc);
printf("Sorted ascending: ");
for (int i = 0; i < n; i++) printf("%d ", numbers[i]);
printf("\n");
generic_bubble_sort(numbers, n, sizeof(int), cmp_int_desc);
printf("Sorted descending: ");
for (int i = 0; i < n; i++) printf("%d ", numbers[i]);
printf("\n\n");
// Sort strings alphabetically
char *names[] = {"Charlie", "Alice", "Eve", "Bob", "David"};
int name_count = 5;
printf("Original strings: ");
for (int i = 0; i < name_count; i++) printf("%s ", names[i]);
printf("\n");
generic_bubble_sort(names, name_count, sizeof(char*), cmp_string);
printf("Sorted alphabetically: ");
for (int i = 0; i < name_count; i++) printf("%s ", names[i]);
printf("\n");
generic_bubble_sort(names, name_count, sizeof(char*), cmp_string_len);
printf("Sorted by length: ");
for (int i = 0; i < name_count; i++) printf("%s ", names[i]);
printf("\n");
printf("\n");
}
// =============================================================================
// Example 6: Function Pointers in Structures
// =============================================================================
// "Object" with methods
typedef struct {
char name[32];
int value;
// "Methods"
void (*print)(struct Counter*);
void (*increment)(struct Counter*);
void (*decrement)(struct Counter*);
void (*reset)(struct Counter*);
int (*get_value)(struct Counter*);
} Counter;
// Method implementations
void counter_print(Counter *self) {
printf("Counter '%s': value = %d\n", self->name, self->value);
}
void counter_increment(Counter *self) {
self->value++;
}
void counter_decrement(Counter *self) {
self->value--;
}
void counter_reset(Counter *self) {
self->value = 0;
}
int counter_get_value(Counter *self) {
return self->value;
}
// Constructor
Counter counter_create(const char *name, int initial) {
Counter c;
strncpy(c.name, name, sizeof(c.name) - 1);
c.name[sizeof(c.name) - 1] = '\0';
c.value = initial;
// Assign "methods"
c.print = counter_print;
c.increment = counter_increment;
c.decrement = counter_decrement;
c.reset = counter_reset;
c.get_value = counter_get_value;
return c;
}
void example6_function_pointers_in_structures(void) {
printf("=== Example 6: Function Pointers in Structures ===\n\n");
Counter c1 = counter_create("PageViews", 100);
Counter c2 = counter_create("Downloads", 50);
// Use "method" syntax
c1.print(&c1);
c2.print(&c2);
printf("\nIncrementing PageViews 3 times:\n");
c1.increment(&c1);
c1.increment(&c1);
c1.increment(&c1);
c1.print(&c1);
printf("\nDecrementing Downloads:\n");
c2.decrement(&c2);
c2.print(&c2);
printf("\nResetting PageViews:\n");
c1.reset(&c1);
c1.print(&c1);
printf("\nGetting value: %d\n", c2.get_value(&c2));
printf("\n");
}
// =============================================================================
// Example 7: Calculator with Dispatch Table
// =============================================================================
typedef double (*CalcOp)(double, double);
double calc_add(double a, double b) { return a + b; }
double calc_sub(double a, double b) { return a - b; }
double calc_mul(double a, double b) { return a * b; }
double calc_div(double a, double b) { return b != 0 ? a / b : 0; }
double calc_pow(double a, double b) { return pow(a, b); }
double calc_mod(double a, double b) { return fmod(a, b); }
typedef struct {
char symbol;
const char *name;
CalcOp func;
} Operation;
void example7_calculator_dispatch(void) {
printf("=== Example 7: Calculator with Dispatch Table ===\n\n");
Operation ops[] = {
{'+', "add", calc_add},
{'-', "subtract", calc_sub},
{'*', "multiply", calc_mul},
{'/', "divide", calc_div},
{'^', "power", calc_pow},
{'%', "modulo", calc_mod}
};
int op_count = sizeof(ops) / sizeof(ops[0]);
double a = 10.0, b = 3.0;
printf("Calculating with a=%.1f, b=%.1f:\n", a, b);
for (int i = 0; i < op_count; i++) {
double result = ops[i].func(a, b);
printf(" %.1f %c %.1f = %.4f (%s)\n",
a, ops[i].symbol, b, result, ops[i].name);
}
// Lookup by symbol
printf("\nLooking up operation by symbol:\n");
char symbol = '^';
for (int i = 0; i < op_count; i++) {
if (ops[i].symbol == symbol) {
printf(" %c is '%s': %.1f %c %.1f = %.4f\n",
symbol, ops[i].name, a, symbol, b, ops[i].func(a, b));
break;
}
}
printf("\n");
}
// =============================================================================
// Example 8: Event System with Callbacks
// =============================================================================
#define MAX_HANDLERS 5
typedef enum {
EVENT_STARTUP,
EVENT_SHUTDOWN,
EVENT_DATA_RECEIVED,
EVENT_ERROR,
EVENT_COUNT
} EventType;
typedef struct {
void *data;
const char *message;
} EventData;
typedef void (*EventHandler)(EventType, EventData*);
typedef struct {
EventHandler handlers[EVENT_COUNT][MAX_HANDLERS];
int handler_count[EVENT_COUNT];
} EventSystem;
void event_system_init(EventSystem *es) {
memset(es, 0, sizeof(EventSystem));
}
int event_system_subscribe(EventSystem *es, EventType type, EventHandler handler) {
if (es->handler_count[type] >= MAX_HANDLERS) {
return -1;
}
es->handlers[type][es->handler_count[type]++] = handler;
return 0;
}
void event_system_emit(EventSystem *es, EventType type, EventData *data) {
for (int i = 0; i < es->handler_count[type]; i++) {
if (es->handlers[type][i]) {
es->handlers[type][i](type, data);
}
}
}
// Event handlers
const char *event_names[] = {"STARTUP", "SHUTDOWN", "DATA_RECEIVED", "ERROR"};
void logger_handler(EventType type, EventData *data) {
printf("[LOGGER] Event: %s - %s\n", event_names[type],
data->message ? data->message : "(no message)");
}
void alert_handler(EventType type, EventData *data) {
if (type == EVENT_ERROR) {
printf("[ALERT] *** ERROR: %s ***\n",
data->message ? data->message : "Unknown error");
}
}
void startup_handler(EventType type, EventData *data) {
(void)type;
printf("[STARTUP] System initialized: %s\n",
data->message ? data->message : "ready");
}
void example8_event_system(void) {
printf("=== Example 8: Event System with Callbacks ===\n\n");
EventSystem es;
event_system_init(&es);
// Subscribe handlers
event_system_subscribe(&es, EVENT_STARTUP, logger_handler);
event_system_subscribe(&es, EVENT_STARTUP, startup_handler);
event_system_subscribe(&es, EVENT_SHUTDOWN, logger_handler);
event_system_subscribe(&es, EVENT_DATA_RECEIVED, logger_handler);
event_system_subscribe(&es, EVENT_ERROR, logger_handler);
event_system_subscribe(&es, EVENT_ERROR, alert_handler);
// Emit events
printf("Emitting events:\n");
EventData startup_data = {NULL, "Version 1.0"};
event_system_emit(&es, EVENT_STARTUP, &startup_data);
EventData data_event = {NULL, "Received 100 bytes"};
event_system_emit(&es, EVENT_DATA_RECEIVED, &data_event);
EventData error_event = {NULL, "Connection failed"};
event_system_emit(&es, EVENT_ERROR, &error_event);
EventData shutdown_data = {NULL, "Graceful shutdown"};
event_system_emit(&es, EVENT_SHUTDOWN, &shutdown_data);
printf("\n");
}
// =============================================================================
// Example 9: Simple State Machine
// =============================================================================
typedef enum {
STATE_IDLE,
STATE_STARTING,
STATE_RUNNING,
STATE_STOPPING,
STATE_STOPPED,
STATE_MACHINE_COUNT
} MachineState;
typedef enum {
CMD_START,
CMD_STOP,
CMD_PAUSE,
CMD_RESUME,
CMD_COUNT
} Command;
const char *state_names[] = {"IDLE", "STARTING", "RUNNING", "STOPPING", "STOPPED"};
const char *cmd_names[] = {"START", "STOP", "PAUSE", "RESUME"};
typedef MachineState (*StateHandler)(Command cmd);
MachineState handle_idle(Command cmd) {
if (cmd == CMD_START) {
printf(" [IDLE] Starting up...\n");
return STATE_STARTING;
}
printf(" [IDLE] Ignoring command: %s\n", cmd_names[cmd]);
return STATE_IDLE;
}
MachineState handle_starting(Command cmd) {
(void)cmd;
printf(" [STARTING] Initialization complete, now running\n");
return STATE_RUNNING;
}
MachineState handle_running(Command cmd) {
if (cmd == CMD_STOP) {
printf(" [RUNNING] Stopping...\n");
return STATE_STOPPING;
}
printf(" [RUNNING] Processing...\n");
return STATE_RUNNING;
}
MachineState handle_stopping(Command cmd) {
(void)cmd;
printf(" [STOPPING] Cleanup complete\n");
return STATE_STOPPED;
}
MachineState handle_stopped(Command cmd) {
if (cmd == CMD_START) {
printf(" [STOPPED] Restarting...\n");
return STATE_STARTING;
}
printf(" [STOPPED] System is stopped\n");
return STATE_STOPPED;
}
void example9_state_machine(void) {
printf("=== Example 9: Simple State Machine ===\n\n");
StateHandler handlers[] = {
handle_idle,
handle_starting,
handle_running,
handle_stopping,
handle_stopped
};
MachineState current = STATE_IDLE;
Command commands[] = {CMD_STOP, CMD_START, CMD_RESUME, CMD_STOP, CMD_START};
int cmd_count = sizeof(commands) / sizeof(commands[0]);
printf("Initial state: %s\n\n", state_names[current]);
for (int i = 0; i < cmd_count; i++) {
printf("Command: %s (current state: %s)\n",
cmd_names[commands[i]], state_names[current]);
current = handlers[current](commands[i]);
printf(" New state: %s\n\n", state_names[current]);
}
printf("\n");
}
// =============================================================================
// Example 10: Plugin-like Architecture
// =============================================================================
// Plugin interface
typedef struct Plugin {
const char *name;
const char *version;
int (*init)(struct Plugin*);
void (*process)(struct Plugin*, const char*);
void (*cleanup)(struct Plugin*);
void *data; // Plugin-specific data
} Plugin;
// Plugin implementations
int uppercase_init(Plugin *p) {
printf(" [%s] Initialized\n", p->name);
return 0;
}
void uppercase_process(Plugin *p, const char *input) {
printf(" [%s] Processing: ", p->name);
while (*input) {
putchar(toupper(*input));
input++;
}
putchar('\n');
}
void uppercase_cleanup(Plugin *p) {
printf(" [%s] Cleaned up\n", p->name);
}
int reverse_init(Plugin *p) {
printf(" [%s] Initialized\n", p->name);
return 0;
}
void reverse_process(Plugin *p, const char *input) {
int len = strlen(input);
printf(" [%s] Processing: ", p->name);
for (int i = len - 1; i >= 0; i--) {
putchar(input[i]);
}
putchar('\n');
}
void reverse_cleanup(Plugin *p) {
printf(" [%s] Cleaned up\n", p->name);
}
int counter_init(Plugin *p) {
int *count = malloc(sizeof(int));
*count = 0;
p->data = count;
printf(" [%s] Initialized with counter = 0\n", p->name);
return 0;
}
void counter_process(Plugin *p, const char *input) {
int *count = (int*)p->data;
(*count)++;
printf(" [%s] Processing #%d: \"%s\"\n", p->name, *count, input);
}
void counter_cleanup(Plugin *p) {
int *count = (int*)p->data;
printf(" [%s] Cleaned up after %d operations\n", p->name, *count);
free(count);
}
void example10_plugin_architecture(void) {
printf("=== Example 10: Plugin-like Architecture ===\n\n");
Plugin plugins[] = {
{"Uppercase", "1.0", uppercase_init, uppercase_process, uppercase_cleanup, NULL},
{"Reverse", "1.0", reverse_init, reverse_process, reverse_cleanup, NULL},
{"Counter", "2.0", counter_init, counter_process, counter_cleanup, NULL}
};
int plugin_count = sizeof(plugins) / sizeof(plugins[0]);
// Initialize all plugins
printf("Initializing plugins:\n");
for (int i = 0; i < plugin_count; i++) {
plugins[i].init(&plugins[i]);
}
// Process data through all plugins
printf("\nProcessing 'Hello World':\n");
for (int i = 0; i < plugin_count; i++) {
plugins[i].process(&plugins[i], "Hello World");
}
printf("\nProcessing 'Function Pointers':\n");
for (int i = 0; i < plugin_count; i++) {
plugins[i].process(&plugins[i], "Function Pointers");
}
// Cleanup all plugins
printf("\nCleaning up plugins:\n");
for (int i = 0; i < plugin_count; i++) {
plugins[i].cleanup(&plugins[i]);
}
printf("\n");
}
// =============================================================================
// Example 11: Generic Map/Filter/Reduce
// =============================================================================
typedef void (*MapFunc)(void*);
typedef int (*FilterFunc)(const void*);
typedef void (*ReduceFunc)(void*, const void*);
// Map: apply function to each element
void array_map(void *arr, size_t count, size_t elem_size, MapFunc func) {
char *ptr = (char*)arr;
for (size_t i = 0; i < count; i++) {
func(ptr + i * elem_size);
}
}
// Filter: create new array with matching elements
size_t array_filter(void *arr, size_t count, size_t elem_size,
FilterFunc predicate, void *result) {
char *src = (char*)arr;
char *dst = (char*)result;
size_t match_count = 0;
for (size_t i = 0; i < count; i++) {
if (predicate(src + i * elem_size)) {
memcpy(dst + match_count * elem_size, src + i * elem_size, elem_size);
match_count++;
}
}
return match_count;
}
// Reduce: fold array into single value
void array_reduce(void *arr, size_t count, size_t elem_size,
void *accumulator, ReduceFunc func) {
char *ptr = (char*)arr;
for (size_t i = 0; i < count; i++) {
func(accumulator, ptr + i * elem_size);
}
}
// Functions for int arrays
void int_double(void *elem) { *(int*)elem *= 2; }
void int_square(void *elem) { int v = *(int*)elem; *(int*)elem = v * v; }
int int_is_even(const void *elem) { return *(int*)elem % 2 == 0; }
int int_is_positive(const void *elem) { return *(int*)elem > 0; }
void int_sum(void *acc, const void *elem) { *(int*)acc += *(int*)elem; }
void int_max(void *acc, const void *elem) {
if (*(int*)elem > *(int*)acc) *(int*)acc = *(int*)elem;
}
void example11_map_filter_reduce(void) {
printf("=== Example 11: Generic Map/Filter/Reduce ===\n\n");
int numbers[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int size = 10;
printf("Original: ");
for (int i = 0; i < size; i++) printf("%d ", numbers[i]);
printf("\n\n");
// Map: double each
int doubled[10];
memcpy(doubled, numbers, sizeof(numbers));
array_map(doubled, size, sizeof(int), int_double);
printf("Map (double): ");
for (int i = 0; i < size; i++) printf("%d ", doubled[i]);
printf("\n");
// Map: square each
int squared[10];
memcpy(squared, numbers, sizeof(numbers));
array_map(squared, size, sizeof(int), int_square);
printf("Map (square): ");
for (int i = 0; i < size; i++) printf("%d ", squared[i]);
printf("\n\n");
// Filter: even numbers
int evens[10];
size_t even_count = array_filter(numbers, size, sizeof(int), int_is_even, evens);
printf("Filter (even): ");
for (size_t i = 0; i < even_count; i++) printf("%d ", evens[i]);
printf("\n\n");
// Reduce: sum
int sum = 0;
array_reduce(numbers, size, sizeof(int), &sum, int_sum);
printf("Reduce (sum): %d\n", sum);
// Reduce: max
int max = numbers[0];
array_reduce(numbers, size, sizeof(int), &max, int_max);
printf("Reduce (max): %d\n", max);
printf("\n");
}
// =============================================================================
// Example 12: Comparator Factory
// =============================================================================
typedef int (*Comparator)(const void*, const void*);
// Structure field offset-based comparison
typedef struct {
const char *name;
int age;
double score;
} Student;
// Generic comparators using offset
int compare_by_int_field(const void *a, const void *b, size_t offset) {
int val_a = *(int*)((char*)a + offset);
int val_b = *(int*)((char*)b + offset);
return val_a - val_b;
}
int compare_by_double_field(const void *a, const void *b, size_t offset) {
double val_a = *(double*)((char*)a + offset);
double val_b = *(double*)((char*)b + offset);
return (val_a > val_b) - (val_a < val_b);
}
// Comparators for qsort
int compare_student_by_age(const void *a, const void *b) {
return ((Student*)a)->age - ((Student*)b)->age;
}
int compare_student_by_score(const void *a, const void *b) {
double diff = ((Student*)a)->score - ((Student*)b)->score;
return (diff > 0) - (diff < 0);
}
int compare_student_by_name(const void *a, const void *b) {
return strcmp(((Student*)a)->name, ((Student*)b)->name);
}
void print_students(Student *students, int count, const char *label) {
printf("%s:\n", label);
for (int i = 0; i < count; i++) {
printf(" %s, %d years, score: %.1f\n",
students[i].name, students[i].age, students[i].score);
}
}
void example12_comparator_factory(void) {
printf("=== Example 12: Comparator Factory ===\n\n");
Student students[] = {
{"Alice", 22, 85.5},
{"Bob", 19, 92.0},
{"Charlie", 21, 78.5},
{"Diana", 20, 95.0},
{"Eve", 23, 88.0}
};
int count = sizeof(students) / sizeof(students[0]);
print_students(students, count, "Original");
printf("\n");
// Sort by age
qsort(students, count, sizeof(Student), compare_student_by_age);
print_students(students, count, "Sorted by age");
printf("\n");
// Sort by score
qsort(students, count, sizeof(Student), compare_student_by_score);
print_students(students, count, "Sorted by score");
printf("\n");
// Sort by name
qsort(students, count, sizeof(Student), compare_student_by_name);
print_students(students, count, "Sorted by name");
printf("\n");
}
// =============================================================================
// Main Function
// =============================================================================
int main(void) {
printf("============================================================\n");
printf(" FUNCTION POINTERS IN C - COMPREHENSIVE EXAMPLES \n");
printf("============================================================\n\n");
example1_basic_function_pointers();
example2_callbacks();
example3_array_of_function_pointers();
example4_typedef_function_pointers();
example5_generic_sorting();
example6_function_pointers_in_structures();
example7_calculator_dispatch();
example8_event_system();
example9_state_machine();
example10_plugin_architecture();
example11_map_filter_reduce();
example12_comparator_factory();
printf("============================================================\n");
printf(" END OF EXAMPLES \n");
printf("============================================================\n");
return 0;
}