CTF: Function Pointers & Generics
8 challenges — Week 9
Function Pointers & Generics Challenges
| 8 challenges | Week 9 | Week 9 (Function Pointers & Generic Programming) |
Function pointer and generic programming challenges covering declaration and typedef syntax, callback functions, qsort comparators, void pointer basics, generic swap with memcpy, callback-driven struct lifecycle (build/print/compare/clean), dispatch tables, and tracing generic container code. These exercises build on the pointer and dynamic memory foundations from Weeks 6-7, the struct patterns from Week 8, and directly scaffold Lab 8’s callback-based architecture.
Difficulty Breakdown
| Level | Count |
|---|---|
| Beginner | 2 |
| Intermediate | 3 |
| Advanced | 3 |
Challenges
1. Function Pointer Declaration
| Difficulty: Beginner | Time: ~10 min | Type: bare code |
This exercise has three parts.
Part A: Read each function pointer declaration below. For each one, state the return type, the parameter types, and write a one-line example function that the pointer could point to.
int (*fptr)(int, int)void (*fptr)(const char *)- `double (*fptr)…
Concepts: reading function pointer declarations, identifying return type and parameter types from declaration syntax, writing functions that match a given function pointer signature, typedef aliases for function pointer types, distinguishing function pointer from function returning pointer
2. Simple Callback
| Difficulty: Beginner | Time: ~10 min | Type: function |
Write a function void applyToArray(int arr, int size, int (transform)(int)) that applies the given transform function to every element of the array, storing the result back in the same position.
Then write three transform functions:
- int doubleIt(int x) — returns x * 2
- int squareIt(int x) —…
Concepts: function pointer as parameter, callback pattern: passing behavior as an argument, calling a function through a function pointer, writing functions that match a given signature, passing function name without parentheses
3. Qsort Comparator
| Difficulty: Intermediate | Time: ~15 min | Type: function |
The C standard library function qsort has the following signature:
void qsort(void base, size_t nmemb, size_t size, int (compar)(const void *, const void *));
qsort passes pointers to individual elements to the comparator. The comparator must cast these void pointers to the correct…
Concepts: qsort function signature and usage, void pointer casting in comparator functions, int comparator via subtraction, double comparator via explicit comparison (cannot subtract and cast to int), string comparator with char** double dereference
4. Void Pointer Basics
| Difficulty: Intermediate | Time: ~10 min | Type: bare code |
Trace the following program and predict the output for each of the four printValue calls.
#include
void printValue(void *data, char type) { switch (type) { case ‘i’: printf(“int: %d\n”, *(int *)data); break; case ‘d’: printf(“dou…
Concepts: void pointer as generic data pointer, explicit casting from void* to typed pointer, type mismatch through incorrect void* cast causes undefined behavior, void* erases type information — compiler cannot check correctness, type-tag pattern (passing type indicator alongside void*)
5. Generic Swap
| Difficulty: Intermediate | Time: ~12 min | Type: function |
In Week 6 (US-1.1.3), you wrote typed swap functions like void swapInts(int *a, int *b). Those functions only work for one type. Now write a single generic swap function that works for ANY type:
void genericSwap(void *a, void *b, size_t size)
Since void* cannot be dereferenced, you must use mem…
Concepts: void pointer as generic data parameter, memcpy for type-agnostic byte copying, size_t parameter to communicate element size, generic programming without templates (C’s manual approach), connection between typed swap (Week 6) and generic swap
6. Callback Set
| Difficulty: Advanced | Time: ~20 min | Type: bare code |
Given the following Student struct:
typedef struct { char *name; int id; double gpa; } Student;
Implement four callback functions that operate through void* for generic compatibility:
- void *buildStudent(const char *name, int id, double gpa) — Allocate a Student on the heap, deep…
Concepts: callback set pattern: build/print/compare/clean, void* as generic interface for struct operations, deep copy with malloc + strcpy for string members, inside-out free pattern (free inner allocations before outer struct), qsort on void* array with double-dereference in comparator
7. Dispatch Table
| Difficulty: Advanced | Time: ~12 min | Type: bare code |
A dispatch table is an array of function pointers that replaces a long switch/if-else chain with direct array indexing.
Implement a calculator using a dispatch table:
- Define four functions:
- double add(double a, double b)
- double subtract(double a, double b)
- double multiply(doub…
Concepts: function pointer array (dispatch table), typedef for function pointer types, calling functions through array-indexed function pointers, dispatch table vs switch statement trade-offs, extensibility: adding operations without modifying control flow
8. Generic Container Tracing
| Difficulty: Advanced | Time: ~15 min | Type: bare code |
Trace the following ~40-line program carefully and answer the questions below.
#include
typedef struct { char *name; int value; } Item;
void *buildItem(const char *name) { Item *item = malloc(sizeof(Item)); item->name = malloc(s…
Concepts: tracing through a complete generic container program, void** collection (array of void pointers), build/print/compare/clean callback pattern in action, qsort on void** with double-dereference comparator, malloc/free counting to verify memory balance