c

exercises

exercises.c🔧
/**
 * =============================================================================
 * POINTERS AND FUNCTIONS - EXERCISES
 * =============================================================================
 * 
 * This file contains exercises to practice pointers with functions in C.
 * 
 * Difficulty Levels:
 *   ⭐         - Beginner
 *   ⭐⭐       - Elementary
 *   ⭐⭐⭐     - Intermediate
 *   ⭐⭐⭐⭐   - Advanced
 *   ⭐⭐⭐⭐⭐ - Expert
 * 
 * Instructions:
 *   1. Complete the TODO sections
 *   2. Compare your output with expected output
 *   3. Solutions are at the end of the file
 * 
 * Compile: gcc -o exercises exercises.c -Wall
 * Run: ./exercises
 * =============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/* =============================================================================
 * EXERCISE 1: Basic Swap Function (⭐)
 * =============================================================================
 * 
 * Write a swap function using pointers.
 * 
 * Expected Output:
 *   Before: a = 10, b = 20
 *   After:  a = 20, b = 10
 */

// TODO: Complete this function
void swap(int *a, int *b) {
    // Your code here...
}

void exercise1_swap(void) {
    printf("=== EXERCISE 1: Basic Swap Function ===\n\n");
    
    int a = 10, b = 20;
    
    printf("Before: a = %d, b = %d\n", a, b);
    swap(&a, &b);
    printf("After:  a = %d, b = %d\n", a, b);
}


/* =============================================================================
 * EXERCISE 2: Increment Through Pointer (⭐)
 * =============================================================================
 * 
 * Write a function that increments a value by a given amount.
 * 
 * Expected Output:
 *   Before: value = 10
 *   After incrementBy 5: value = 15
 *   After incrementBy 3: value = 18
 */

// TODO: Complete this function
void incrementBy(int *value, int amount) {
    // Your code here...
}

void exercise2_increment(void) {
    printf("=== EXERCISE 2: Increment Through Pointer ===\n\n");
    
    int value = 10;
    
    printf("Before: value = %d\n", value);
    incrementBy(&value, 5);
    printf("After incrementBy 5: value = %d\n", value);
    incrementBy(&value, 3);
    printf("After incrementBy 3: value = %d\n", value);
}


/* =============================================================================
 * EXERCISE 3: Calculate Area and Perimeter (⭐⭐)
 * =============================================================================
 * 
 * Write a function that calculates both area and perimeter of a rectangle.
 * Return both values through pointer parameters.
 * 
 * Expected Output:
 *   Rectangle: width=5, height=3
 *   Area: 15
 *   Perimeter: 16
 */

// TODO: Complete this function
void calculateRectangle(int width, int height, int *area, int *perimeter) {
    // Your code here...
}

void exercise3_rectangle(void) {
    printf("=== EXERCISE 3: Calculate Area and Perimeter ===\n\n");
    
    int width = 5, height = 3;
    int area, perimeter;
    
    calculateRectangle(width, height, &area, &perimeter);
    
    printf("Rectangle: width=%d, height=%d\n", width, height);
    printf("Area: %d\n", area);
    printf("Perimeter: %d\n", perimeter);
}


/* =============================================================================
 * EXERCISE 4: Array Statistics (⭐⭐)
 * =============================================================================
 * 
 * Write a function that returns sum, min, and max of an array.
 * 
 * Expected Output:
 *   Array: 5 2 8 1 9 3
 *   Sum: 28
 *   Min: 1
 *   Max: 9
 */

// TODO: Complete this function
void arrayStats(const int *arr, int size, int *sum, int *min, int *max) {
    // Your code here...
}

void exercise4_array_stats(void) {
    printf("=== EXERCISE 4: Array Statistics ===\n\n");
    
    int arr[] = {5, 2, 8, 1, 9, 3};
    int size = 6;
    int sum, min, max;
    
    arrayStats(arr, size, &sum, &min, &max);
    
    printf("Array: ");
    for (int i = 0; i < size; i++) printf("%d ", arr[i]);
    printf("\n");
    printf("Sum: %d\n", sum);
    printf("Min: %d\n", min);
    printf("Max: %d\n", max);
}


/* =============================================================================
 * EXERCISE 5: Reverse Array In-Place (⭐⭐)
 * =============================================================================
 * 
 * Write a function to reverse an array in-place using pointers.
 * 
 * Expected Output:
 *   Before: 1 2 3 4 5
 *   After:  5 4 3 2 1
 */

// TODO: Complete this function
void reverseArray(int *arr, int size) {
    // Your code here...
}

void exercise5_reverse_array(void) {
    printf("=== EXERCISE 5: Reverse Array In-Place ===\n\n");
    
    int arr[] = {1, 2, 3, 4, 5};
    int size = 5;
    
    printf("Before: ");
    for (int i = 0; i < size; i++) printf("%d ", arr[i]);
    printf("\n");
    
    reverseArray(arr, size);
    
    printf("After:  ");
    for (int i = 0; i < size; i++) printf("%d ", arr[i]);
    printf("\n");
}


/* =============================================================================
 * EXERCISE 6: Find Element and Return Pointer (⭐⭐⭐)
 * =============================================================================
 * 
 * Write a function that searches for an element and returns pointer to it.
 * Return NULL if not found.
 * 
 * Expected Output:
 *   Searching for 30: Found at index 2
 *   Searching for 99: Not found
 */

// TODO: Complete this function
int* findElement(int *arr, int size, int target) {
    // Your code here...
    return NULL;
}

void exercise6_find_element(void) {
    printf("=== EXERCISE 6: Find Element and Return Pointer ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int size = 5;
    
    int *result = findElement(arr, size, 30);
    if (result != NULL) {
        printf("Searching for 30: Found at index %ld\n", result - arr);
    } else {
        printf("Searching for 30: Not found\n");
    }
    
    result = findElement(arr, size, 99);
    if (result != NULL) {
        printf("Searching for 99: Found at index %ld\n", result - arr);
    } else {
        printf("Searching for 99: Not found\n");
    }
}


/* =============================================================================
 * EXERCISE 7: Dynamic Array Creation (⭐⭐⭐)
 * =============================================================================
 * 
 * Write a function that creates a dynamically allocated array with given values.
 * 
 * Expected Output:
 *   Created array: 10 20 30 40 50
 */

// TODO: Complete this function
int* createFilledArray(int size, int startValue, int increment) {
    // Allocate array, fill with startValue, startValue+increment, ...
    // Return the array (caller must free)
    return NULL;
}

void exercise7_create_array(void) {
    printf("=== EXERCISE 7: Dynamic Array Creation ===\n\n");
    
    int *arr = createFilledArray(5, 10, 10);
    
    if (arr != NULL) {
        printf("Created array: ");
        for (int i = 0; i < 5; i++) printf("%d ", arr[i]);
        printf("\n");
        free(arr);
    } else {
        printf("Allocation failed!\n");
    }
}


/* =============================================================================
 * EXERCISE 8: Basic Function Pointer (⭐⭐⭐)
 * =============================================================================
 * 
 * Use function pointers to perform different operations.
 * 
 * Expected Output:
 *   add(10, 5) = 15
 *   subtract(10, 5) = 5
 *   multiply(10, 5) = 50
 */

int add_ex(int a, int b) { return a + b; }
int subtract_ex(int a, int b) { return a - b; }
int multiply_ex(int a, int b) { return a * b; }

void exercise8_function_pointer(void) {
    printf("=== EXERCISE 8: Basic Function Pointer ===\n\n");
    
    // TODO: Declare function pointer and use it
    // Call each of the three functions using the same function pointer
    
    // Your code here...
    
}


/* =============================================================================
 * EXERCISE 9: Calculator with Function Array (⭐⭐⭐)
 * =============================================================================
 * 
 * Create an array of function pointers for a calculator.
 * 
 * Expected Output:
 *   Calculator: 20 [op] 4
 *   Add: 24
 *   Sub: 16
 *   Mul: 80
 *   Div: 5
 */

int calc_add(int a, int b) { return a + b; }
int calc_sub(int a, int b) { return a - b; }
int calc_mul(int a, int b) { return a * b; }
int calc_div(int a, int b) { return b != 0 ? a / b : 0; }

void exercise9_calculator(void) {
    printf("=== EXERCISE 9: Calculator with Function Array ===\n\n");
    
    // TODO: Create array of function pointers
    // TODO: Use the array to perform all operations
    
    int a = 20, b = 4;
    printf("Calculator: %d [op] %d\n", a, b);
    
    // Your code here...
    
}


/* =============================================================================
 * EXERCISE 10: Callback for Array Processing (⭐⭐⭐)
 * =============================================================================
 * 
 * Write a function that applies a callback to each array element.
 * 
 * Expected Output:
 *   Original: 1 2 3 4 5
 *   Squared:  1 4 9 16 25
 */

// TODO: Complete this function - apply callback to each element
void applyToEach(int *arr, int size, int (*transform)(int)) {
    // Your code here...
}

int squareNum(int x) { return x * x; }

void exercise10_callback(void) {
    printf("=== EXERCISE 10: Callback for Array Processing ===\n\n");
    
    int arr[] = {1, 2, 3, 4, 5};
    int size = 5;
    
    printf("Original: ");
    for (int i = 0; i < size; i++) printf("%d ", arr[i]);
    printf("\n");
    
    applyToEach(arr, size, squareNum);
    
    printf("Squared:  ");
    for (int i = 0; i < size; i++) printf("%d ", arr[i]);
    printf("\n");
}


/* =============================================================================
 * EXERCISE 11: Custom Comparison Sort (⭐⭐⭐⭐)
 * =============================================================================
 * 
 * Implement bubble sort that uses a comparison callback.
 * 
 * Expected Output:
 *   Original: 64 34 25 12 22 11 90
 *   Ascending:  11 12 22 25 34 64 90
 *   Descending: 90 64 34 25 22 12 11
 */

// TODO: Complete this function
void customSort(int *arr, int size, int (*compare)(int, int)) {
    // Implement bubble sort using the compare callback
    // compare(a, b) > 0 means a should come after b
    
    // Your code here...
}

int ascending(int a, int b) { return a - b; }
int descending(int a, int b) { return b - a; }

void exercise11_custom_sort(void) {
    printf("=== EXERCISE 11: Custom Comparison Sort ===\n\n");
    
    int arr1[] = {64, 34, 25, 12, 22, 11, 90};
    int arr2[] = {64, 34, 25, 12, 22, 11, 90};
    int size = 7;
    
    printf("Original: ");
    for (int i = 0; i < size; i++) printf("%d ", arr1[i]);
    printf("\n");
    
    customSort(arr1, size, ascending);
    printf("Ascending:  ");
    for (int i = 0; i < size; i++) printf("%d ", arr1[i]);
    printf("\n");
    
    customSort(arr2, size, descending);
    printf("Descending: ");
    for (int i = 0; i < size; i++) printf("%d ", arr2[i]);
    printf("\n");
}


/* =============================================================================
 * EXERCISE 12: Function Dispatcher (⭐⭐⭐⭐)
 * =============================================================================
 * 
 * Create a dispatch table that maps operation names to functions.
 * 
 * Expected Output:
 *   Dispatching 'add' on 10, 5: Result = 15
 *   Dispatching 'mul' on 10, 5: Result = 50
 *   Dispatching 'mod' on 10, 5: Result = 0
 */

typedef int (*BinaryOperation)(int, int);

typedef struct {
    const char *name;
    BinaryOperation func;
} OperationEntry;

int op_add(int a, int b) { return a + b; }
int op_sub(int a, int b) { return a - b; }
int op_mul(int a, int b) { return a * b; }
int op_mod(int a, int b) { return a % b; }

// TODO: Complete this function - find and execute operation by name
int dispatch(OperationEntry *table, int count, const char *name, int a, int b) {
    // Your code here...
    return 0;
}

void exercise12_dispatcher(void) {
    printf("=== EXERCISE 12: Function Dispatcher ===\n\n");
    
    OperationEntry operations[] = {
        {"add", op_add},
        {"sub", op_sub},
        {"mul", op_mul},
        {"mod", op_mod}
    };
    int count = 4;
    
    int a = 10, b = 5;
    
    printf("Dispatching 'add' on %d, %d: Result = %d\n", 
           a, b, dispatch(operations, count, "add", a, b));
    printf("Dispatching 'mul' on %d, %d: Result = %d\n", 
           a, b, dispatch(operations, count, "mul", a, b));
    printf("Dispatching 'mod' on %d, %d: Result = %d\n", 
           a, b, dispatch(operations, count, "mod", a, b));
}


/* =============================================================================
 * EXERCISE 13: Generic Comparison (⭐⭐⭐⭐)
 * =============================================================================
 * 
 * Write a generic comparison function using void pointers.
 * 
 * Expected Output:
 *   Comparing integers: 10 and 20
 *   Result: 10 < 20
 *   Comparing doubles: 3.14 and 2.71
 *   Result: 3.14 > 2.71
 */

// TODO: Implement these comparison functions
int compareInts(const void *a, const void *b) {
    // Your code here...
    return 0;
}

int compareDoubles(const void *a, const void *b) {
    // Your code here...
    return 0;
}

void exercise13_generic_compare(void) {
    printf("=== EXERCISE 13: Generic Comparison ===\n\n");
    
    int i1 = 10, i2 = 20;
    printf("Comparing integers: %d and %d\n", i1, i2);
    int result = compareInts(&i1, &i2);
    printf("Result: %d %s %d\n\n", i1, 
           result < 0 ? "<" : (result > 0 ? ">" : "=="), i2);
    
    double d1 = 3.14, d2 = 2.71;
    printf("Comparing doubles: %.2f and %.2f\n", d1, d2);
    result = compareDoubles(&d1, &d2);
    printf("Result: %.2f %s %.2f\n", d1, 
           result < 0 ? "<" : (result > 0 ? ">" : "=="), d2);
}


/* =============================================================================
 * EXERCISE 14: Map Function (⭐⭐⭐⭐)
 * =============================================================================
 * 
 * Create a map function that creates a new array by applying a function.
 * 
 * Expected Output:
 *   Original:  1 2 3 4 5
 *   Doubled:   2 4 6 8 10
 *   Cubed:     1 8 27 64 125
 */

// TODO: Complete this function
int* mapArray(const int *arr, int size, int (*func)(int)) {
    // Create new array with func applied to each element
    // Your code here...
    return NULL;
}

int doubleVal(int x) { return x * 2; }
int cubeVal(int x) { return x * x * x; }

void exercise14_map_function(void) {
    printf("=== EXERCISE 14: Map Function ===\n\n");
    
    int arr[] = {1, 2, 3, 4, 5};
    int size = 5;
    
    printf("Original:  ");
    for (int i = 0; i < size; i++) printf("%d ", arr[i]);
    printf("\n");
    
    int *doubled = mapArray(arr, size, doubleVal);
    if (doubled) {
        printf("Doubled:   ");
        for (int i = 0; i < size; i++) printf("%d ", doubled[i]);
        printf("\n");
        free(doubled);
    }
    
    int *cubed = mapArray(arr, size, cubeVal);
    if (cubed) {
        printf("Cubed:     ");
        for (int i = 0; i < size; i++) printf("%d ", cubed[i]);
        printf("\n");
        free(cubed);
    }
}


/* =============================================================================
 * EXERCISE 15: Event Handler System (⭐⭐⭐⭐⭐)
 * =============================================================================
 * 
 * Implement a simple event handler system with callbacks.
 * 
 * Expected Output:
 *   Registering handlers...
 *   Triggering event 0: onClick
 *     Handler executed: Button clicked!
 *   Triggering event 1: onHover
 *     Handler executed: Mouse hovering!
 *   Triggering event 2: onExit
 *     Handler executed: Exiting application!
 */

#define MAX_EVENTS 10

typedef void (*EventHandler)(void);

typedef struct {
    const char *name;
    EventHandler handler;
} Event;

Event eventTable[MAX_EVENTS];
int eventCount = 0;

// TODO: Complete these functions
void registerEvent(const char *name, EventHandler handler) {
    // Your code here...
}

void triggerEvent(const char *name) {
    // Your code here...
}

void onClickHandler(void) { printf("    Handler executed: Button clicked!\n"); }
void onHoverHandler(void) { printf("    Handler executed: Mouse hovering!\n"); }
void onExitHandler(void) { printf("    Handler executed: Exiting application!\n"); }

void exercise15_event_handler(void) {
    printf("=== EXERCISE 15: Event Handler System ===\n\n");
    
    eventCount = 0;  // Reset
    
    printf("Registering handlers...\n");
    registerEvent("onClick", onClickHandler);
    registerEvent("onHover", onHoverHandler);
    registerEvent("onExit", onExitHandler);
    
    const char *events[] = {"onClick", "onHover", "onExit"};
    
    for (int i = 0; i < 3; i++) {
        printf("Triggering event %d: %s\n", i, events[i]);
        triggerEvent(events[i]);
    }
}


/* =============================================================================
 * MAIN FUNCTION
 * =============================================================================
 */

int main() {
    printf("╔══════════════════════════════════════════════════════════╗\n");
    printf("║     POINTERS AND FUNCTIONS - EXERCISE FILE               ║\n");
    printf("╚══════════════════════════════════════════════════════════╝\n");
    
    // Uncomment exercises to test:
    
    // exercise1_swap();
    // exercise2_increment();
    // exercise3_rectangle();
    // exercise4_array_stats();
    // exercise5_reverse_array();
    // exercise6_find_element();
    // exercise7_create_array();
    // exercise8_function_pointer();
    // exercise9_calculator();
    // exercise10_callback();
    // exercise11_custom_sort();
    // exercise12_dispatcher();
    // exercise13_generic_compare();
    // exercise14_map_function();
    // exercise15_event_handler();
    
    printf("\n[Uncomment exercises in main() to test them]\n");
    
    return 0;
}


/* =============================================================================
 * SOLUTIONS
 * =============================================================================
 * 
 * Scroll down for solutions...
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * =============================================================================
 */


/* ----- SOLUTION 1 ----- */
void solution_swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}


/* ----- SOLUTION 2 ----- */
void solution_incrementBy(int *value, int amount) {
    *value += amount;
}


/* ----- SOLUTION 3 ----- */
void solution_calculateRectangle(int width, int height, int *area, int *perimeter) {
    *area = width * height;
    *perimeter = 2 * (width + height);
}


/* ----- SOLUTION 4 ----- */
void solution_arrayStats(const int *arr, int size, int *sum, int *min, int *max) {
    *sum = 0;
    *min = *max = arr[0];
    
    for (int i = 0; i < size; i++) {
        *sum += arr[i];
        if (arr[i] < *min) *min = arr[i];
        if (arr[i] > *max) *max = arr[i];
    }
}


/* ----- SOLUTION 5 ----- */
void solution_reverseArray(int *arr, int size) {
    int *start = arr;
    int *end = arr + size - 1;
    
    while (start < end) {
        int temp = *start;
        *start = *end;
        *end = temp;
        start++;
        end--;
    }
}


/* ----- SOLUTION 6 ----- */
int* solution_findElement(int *arr, int size, int target) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == target) {
            return &arr[i];
        }
    }
    return NULL;
}


/* ----- SOLUTION 7 ----- */
int* solution_createFilledArray(int size, int startValue, int increment) {
    int *arr = (int*)malloc(size * sizeof(int));
    if (arr == NULL) return NULL;
    
    for (int i = 0; i < size; i++) {
        arr[i] = startValue + (i * increment);
    }
    return arr;
}


/* ----- SOLUTION 8 ----- */
void solution8_function_pointer(void) {
    printf("=== EXERCISE 8: Basic Function Pointer ===\n\n");
    
    int (*op)(int, int);
    
    op = add_ex;
    printf("add(10, 5) = %d\n", op(10, 5));
    
    op = subtract_ex;
    printf("subtract(10, 5) = %d\n", op(10, 5));
    
    op = multiply_ex;
    printf("multiply(10, 5) = %d\n", op(10, 5));
}


/* ----- SOLUTION 9 ----- */
void solution9_calculator(void) {
    printf("=== EXERCISE 9: Calculator with Function Array ===\n\n");
    
    int (*ops[4])(int, int) = {calc_add, calc_sub, calc_mul, calc_div};
    const char *names[] = {"Add", "Sub", "Mul", "Div"};
    
    int a = 20, b = 4;
    printf("Calculator: %d [op] %d\n", a, b);
    
    for (int i = 0; i < 4; i++) {
        printf("%s: %d\n", names[i], ops[i](a, b));
    }
}


/* ----- SOLUTION 10 ----- */
void solution_applyToEach(int *arr, int size, int (*transform)(int)) {
    for (int i = 0; i < size; i++) {
        arr[i] = transform(arr[i]);
    }
}


/* ----- SOLUTION 11 ----- */
void solution_customSort(int *arr, int size, int (*compare)(int, int)) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - 1 - i; j++) {
            if (compare(arr[j], arr[j+1]) > 0) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}


/* ----- SOLUTION 12 ----- */
int solution_dispatch(OperationEntry *table, int count, const char *name, int a, int b) {
    for (int i = 0; i < count; i++) {
        if (strcmp(table[i].name, name) == 0) {
            return table[i].func(a, b);
        }
    }
    return 0;  // Not found
}


/* ----- SOLUTION 13 ----- */
int solution_compareInts(const void *a, const void *b) {
    return *(const int*)a - *(const int*)b;
}

int solution_compareDoubles(const void *a, const void *b) {
    double diff = *(const double*)a - *(const double*)b;
    if (diff < 0) return -1;
    if (diff > 0) return 1;
    return 0;
}


/* ----- SOLUTION 14 ----- */
int* solution_mapArray(const int *arr, int size, int (*func)(int)) {
    int *result = (int*)malloc(size * sizeof(int));
    if (result == NULL) return NULL;
    
    for (int i = 0; i < size; i++) {
        result[i] = func(arr[i]);
    }
    return result;
}


/* ----- SOLUTION 15 ----- */
void solution_registerEvent(const char *name, EventHandler handler) {
    if (eventCount < MAX_EVENTS) {
        eventTable[eventCount].name = name;
        eventTable[eventCount].handler = handler;
        eventCount++;
    }
}

void solution_triggerEvent(const char *name) {
    for (int i = 0; i < eventCount; i++) {
        if (strcmp(eventTable[i].name, name) == 0) {
            eventTable[i].handler();
            return;
        }
    }
    printf("    Event '%s' not found!\n", name);
}
Exercises - C Programming Tutorial | DeepML