Generic programming is a programming paradigm where algorithms and data structures are written in terms of types that are specified later, allowing the same code to work with different data types. Generic code increases code reuse and reduces duplication.
C achieves generic programming through function pointers and void* pointers, allowing functions to operate on any data type:
void map(int (*fn)(int, int), int n, int *s0, int *s1, int *dest) {
for (int i = 0; i < n; i++)
dest[i] = fn(s0[i], s1[i]);
}
int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
map(add, 3, array1, array2, result); // Add arrays
map(mul, 3, array1, array2, result); // Multiply arrays
The C standard library's qsort function is fully generic:
void qsort(void *base, size_t nel, size_t width,
int (*compare)(const void*, const void*));
Usage examples:
// Sort integers
int cmpInt(const void *a, const void *b) {
int ia = *(int*)a;
int ib = *(int*)b;
return ia - ib;
}
qsort(intArray, n, sizeof(int), cmpInt);
// Sort strings
int cmpString(const void *a, const void *b) {
char *sa = *(char**)a;
char *sb = *(char**)b;
return strcmp(sa, sb);
}
qsort(strArray, n, sizeof(char*), cmpString);
The typedef statement creates type aliases that make generic code more readable:
typedef void* element_t;
int partition(element_t* array, int left, int right,
int (*cmp)(element_t, element_t)) {
element_t pivotValue, t;
// ... implementation
}
Without typedef, this would use confusing void** and void* throughout.
Function pointers enable generic operations on data structures:
struct node {
int key;
int value;
struct node *next;
};
void traverse_list(struct node *list, void (*fn)(int, int)) {
while (list) {
fn(list->key, list->value);
list = list->next;
}
}
void print_element(int key, int value) {
printf("%d: %d\n", key, value);
}
void sum_values(int key, int value) {
total += value;
}
traverse_list(myList, print_element); // Print all
traverse_list(myList, sum_values); // Sum all
void* loses compile-time type checkingOther languages provide better generic programming support:
map, foldl, filterGeneric programming is related to polymorphism but distinct:
Both use function pointers in C but serve different purposes.