c

examples

examples.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;
}
Examples - C Programming Tutorial | DeepML