C语言——函数指针详解
简介
类似变量在内存中会分配一个空间,函数在内存中也会分配一个空间,这个空间的入口(或者叫首地址)称为函数的地址。用整型指针可以保存整形变量的地址,同样地,用函数指针可以保存函数的地址。
类比讲解
- 声明指针
- 整型指针:int *int_ptr; 表示一个指向整型变量的指针。
- 函数指针:int (*func_ptr)(int, int); 表示一个指向返回类型为int,参数为两个int的函数的指针。
- 赋值指针
- 整型指针:int_ptr = &value; 将整型变量的地址赋值给指针。
- 函数指针:func_ptr = &add; 将函数的地址赋值给函数指针。
func_ptr = add;写法与func_ptr = &add;等价
在C语言中,函数的名字本身就代表了函数的地址。因此,&add 和 add 都表示函数add的地址。
- 通过指针使用
- 整型指针:*int_ptr 通过指针访问或修改整型变量的值。
- 函数指针:func_ptr(5, 3) 通过指针调用函数,就像直接调用add(5, 3)一样。
示例
整型指针示例
#include <stdio.h>
int main() {
int value = 42; // 整型变量
int *int_ptr = &value; // 声明并初始化整型指针
// 通过指针访问整型变量
printf("Value: %d\n", *int_ptr); // 输出 42
// 通过指针修改整型变量
*int_ptr = 58;
printf("New Value: %d\n", value); // 输出 58
return 0;
}
函数指针示例
#include <stdio.h>
// 一个简单的函数
int add(int a, int b) {
return a + b;
}
int main() {
// 1. 声明函数指针
int (*func_ptr)(int, int); // 指向返回类型为int,参数为两个int的函数的指针
// 2. 赋值函数指针
func_ptr = &add; // 将函数add的地址赋值给函数指针
// 3. 通过函数指针调用函数
int result = func_ptr(5, 3); // 等同于调用 add(5, 3)
printf("Result: %d\n", result); // 输出 8
return 0;
}
将函数指针作为函数的传入参数
函数指针作为函数的传入参数,可以让函数内部调用外部实现的函数。在保证主逻辑不变的情况下,通过改变传入函数的逻辑,最终影响主逻辑的输出。
#include <stdio.h>
// 定义一个函数,返回两个整数中较大的那个
int Max(int x, int y) {
return x > y ? x : y;
}
// 定义一个函数,接收两个整数和一个函数指针作为参数
int GetValue(int x, int y, int (*p)(int, int)) {
return (*p)(x, y); // 通过函数指针调用传入的函数
}
int main(void) {
int a = 1, b = 0; // 定义两个变量a和b
// 将Max函数的指针传递给GetValue函数
int maxValue = GetValue(a, b, Max);
printf("The max value is: %d\n", maxValue); // 输出最大值
return 0;
}
这种设计在许多实际应用中都非常有用。例如,C标准库中的qsort函数就是一个典型的例子。qsort函数需要一个比较函数来决定排序的顺序。通过传递不同的比较函数,我们可以实现不同的排序方式(升序或降序)。
#include <stdio.h>
#include <stdlib.h>
// 升序比较函数
int compare_asc(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
// 降序比较函数
int compare_desc(const void *a, const void *b) {
return (*(int*)b - *(int*)a);
}
int main() {
int array[] = {5, 2, 9, 1, 5, 6};
int size = sizeof(array) / sizeof(array[0]);
// 使用升序比较函数排序
qsort(array, size, sizeof(int), compare_asc);
printf("Sorted array (ascending): ");
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 使用降序比较函数排序
qsort(array, size, sizeof(int), compare_desc);
printf("Sorted array (descending): ");
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
return 0;
}