C语言中函数指针和指针函数的定义及用法
在C/C++中,函数指针和指针函数是两个容易混淆但完全不同的概念。以下是它们的详细对比和学习指南,结合代码示例帮助你彻底掌握。
1. 函数指针(Function Pointer)
本质:一个指向函数的指针变量,用于动态调用函数。
用途:回调函数、策略模式、事件处理等。
语法与示例
// 声明一个函数指针类型(指向返回int,参数为int的函数)
typedef int (*FuncPtr)(int);// 示例函数
int square(int x) { return x * x; }
int cube(int x) { return x * x * x; }int main() {// 定义函数指针变量并指向函数FuncPtr ptr = square;printf("Square of 5: %d\n", ptr(5)); // 输出 25ptr = cube; // 切换指向的函数printf("Cube of 5: %d\n", ptr(5)); // 输出 125return 0;
}
关键点
- 声明格式:返回值类型 (*指针名)(参数列表)
- 应用场景:
回调机制(如qsort的排序比较函数)。
动态选择算法(如运行时选择加密函数)。
2. 指针函数(Pointer Function)
本质:一个返回指针的函数,本质上仍是函数。
用途:动态内存分配、返回数组/结构体指针等。
语法与示例
// 指针函数:返回int*的函数
int* createArray(int size) {int* arr = (int*)malloc(size * sizeof(int));for (int i = 0; i < size; i++) {arr[i] = i + 1;}return arr; // 返回动态分配的指针
}int main() {int* array = createArray(5);for (int i = 0; i < 5; i++) {printf("%d ", array[i]); // 输出 1 2 3 4 5}free(array); // 释放内存return 0;
}
关键点
-
声明格式:返回值类型* 函数名(参数列表)
-
注意事项:
返回的指针需指向合法内存(如堆内存或静态变量)。
避免返回局部变量的指针(会导致悬垂指针)。
3. 对比总结
特性 | 函数指针 | 指针函数 |
---|---|---|
本质 | 指向函数的指针变量 | 返回指针的函数 |
声明示例 | int (*ptr)(int) | int* func(int) |
内存占用 | 存储函数地址(通常4/8字节) | 函数本身无特殊内存占用 |
典型用途 | 回调、动态绑定 | 返回动态数据结构的指针 |
危险点 | 空指针调用导致崩溃 | 内存泄漏或悬垂指针 |
4. 进阶应用
函数指针数组
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }int main() {int (*ops[2])(int, int) = {add, sub}; // 函数指针数组printf("Add: %d\n", ops[0](3, 2)); // 输出 5printf("Sub: %d\n", ops[1](3, 2)); // 输出 1return 0;
}
复杂声明解析(右左法则)
- 函数指针的指针函数:
int* (funcPtr)(int) → funcPtr是指针,指向一个返回int的函数。
5. 常见面试题
以下代码的输出是什么?
void foo() { printf("Hello"); }
int main() {void (*ptr)() = foo;ptr();return 0;
}
答案:输出Hello,函数指针调用。
找出错误:
int* badFunc() {int x = 10;return &x; // 返回局部变量的地址!
}
错误:返回局部变量指针,函数结束后x被销毁,导致悬垂指针。