Function Pointers
Void * Pitfalls
- void *s are powerful, but dangerous - C cannot do as much checking!
- E.g. with int, C would never let you swap half of an int. With void *s, this can happen!
int x = 0xffffffff;
int y = 0xeeeeeeee;
swap(&x, &y, sizeof(short));
// now x = 0xffffeeee, y = 0xeeeeffff!
printf("x = 0x%x, y = 0x%x\n", x, y);
Stack Structs
Each node can no longer store the data itself, because it could be any size!
Instead, it stores a pointer to the data somewhere else.
typedef struct node {
struct node *next;
void *data;
} node;
typedef struct stack {
int nelems;
int elem_size_bytes;
node *top;
} stack;
stack *stack_create(int elem_size_bytes) {
stack *s = malloc(sizeof(stack));
s->nelems = 0;
s->top = NULL;
s->elem_size_bytes = elem_size_bytes;
return s;
}
void stack_push(stack *s, const void *data) {
node *new_node = malloc(sizeof(node));
new_node->data = malloc(s->elem_size_bytes);
memcpy(new_node->data, data, s->elem_size_bytes);
new_node->next = s->top;
s->top = new_node;
s->nelems++;
}
void stack_pop(stack *s, void *addr) {
if (s->nelems == 0) {
error(1, 0, "Cannot pop from empty stack");
}
node *n = s->top;
memcpy(addr, n->data, s->elem_size_bytes);
s->top = n->next;
free(n->data);
free(n);
s->nelems--;
}
Function Pointers
Definition: A function pointer is a variable that stores the address of a function. This allows functions to be passed as arguments to other functions.
Syntax: The syntax for declaring a function pointer includes the return type and parameter types of the function it can point to.
return_type (*function_pointer_name)(parameter_types);
Generic Bubble Sort
// Comparison function for integers
int int_compare(const void *a, const void *b) {
return *(int*)a - *(int*)b;
}
void bubble_sort(void *arr, int n, int elem_size_bytes, int (*compare_fn)(const void *, const void *)) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
void *a = (char *)arr + j * elem_size_bytes;
void *b = (char *)arr + (j + 1) * elem_size_bytes;
if (compare_fn(a, b) > 0) {
// Swap elements
char temp[elem_size_bytes];
memcpy(temp, a, elem_size_bytes);
memcpy(a, b, elem_size_bytes);
memcpy(b, temp, elem_size_bytes);
}
}
}
}
int main() {
int nums[] = {5, 2, 9, 1, 5, 6};
int n = sizeof(nums) / sizeof(nums[0]);
bubble_sort(nums, n, sizeof(int), int_compare);
for (int i = 0; i < n; i++) {
printf("%d ", nums[i]); // Output: 1 2 5 5 6 9
}
printf("\n");
return 0;
}