承接基础篇,本文聚焦指针在模块化设计、动态多态与封装中的高级用法。
// 定义函数指针类型
typedef int (*cmp_func_t)(const void *, const void *);
// 通用排序框架(类似 qsort)
void my_sort(void *base, size_t nmemb, size_t size, cmp_func_t cmp) {
// ... 交换元素时调用 cmp(a, b) ...
}
// 具体比较函数
int cmp_int(const void *a, const void *b) {
return *(const int*)a - *(const int*)b;
}
// 使用
int arr[] = {5,2,9,1};
my_sort(arr, 4, sizeof(int), cmp_int);
函数指针实现了“策略模式”,将算法骨架与具体比较逻辑解耦。
头文件 stack.h
#ifndef STACK_H
#define STACK_H
typedef struct Stack Stack; // 前向声明,隐藏定义
Stack *stack_create(void);
void stack_push(Stack *, int value);
int stack_pop(Stack *);
void stack_destroy(Stack *);
#endif
实现文件 stack.c
#include "stack.h"
#include <stdlib.h>
struct Stack {
int *data;
size_t top, capacity;
};
Stack *stack_create(void) {
Stack *s = malloc(sizeof(Stack));
s->data = malloc(16 * sizeof(int));
s->top = 0; s->capacity = 16;
return s;
}
// ... push/pop/destroy 实现 ...
使用者只见 Stack *,完全不知内部结构,实现变更无需重新编译调用方,实现了真正的接口与实现分离。
int a[5] = {10,20,30,40,50};
int *p = a;
for (; p != a+5; ++p) printf("%d ", *p); // 标准遍历
// 等价于 for (int i=0; i<5; ++i) printf("%d ", a[i]);
指针版本在汇编层面常生成更紧凑的代码,且便于处理动态分配的内存块。
void copy(int *restrict dst, const int *restrict src, size_t n) {
for (size_t i=0; i
restrict 告诉编译器 dst 与 src 不重叠,允许向量化、重排序等激进优化。
free(p); p = NULL; 防止二次释放或误用。int *p = (int*)malloc(n); 强转可能掩盖类型错误,C 语言中 void* 可隐式转换,无需强转。ptrdiff_t。指针是 C 语言的灵魂,也是系统级编程的基石。熟练掌握函数指针、不透明指针、restrict 等进阶特性,能写出更模块化、高性能且可维护的代码。建议配合 valgrind、AddressSanitizer 等工具,在开发期彻底消灭指针相关 Bug。