c
exercises
exercises.c🔧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);
}