函数指针单开一章,说明在MCU中,函数指针的用法较为常见,需要完全理解函数指针的各种用法,以便可以更高效的实习自己想要的功能。
函数指针概念
函数指针(Function Pointer)是指向函数的指针,换句话说,函数的地址可以被一个指针变量保存,这个指针变量就是函数指针。
在C语言中,函数也具有地址,因此可以像处理普通变量一样,获取函数的地址,并通过指针调用函数。
主要作用:
- 动态调用函数:根据不同的条件,调用不同的函数。
- 回调机制:将函数指针作为参数传递,实现回调函数。
- 实现多态性:在一定程度上实现类似面向对象的多态特性。
函数指针的声明
return_type (*pointer_name)(parameter_list);
return_type:函数的返回类型。pointer_name:函数指针的名称。parameter_list:参数列表,与函数的参数列表相同。
举例:定义一个函数指针,指向返回 int 类型、接受两个 int 参数的函数
int (*func_ptr)(int, int);
函数指针的使用
- 定义函数指针:根据目标函数的类型和参数列表,定义相应的函数指针。
- 指针赋值:将目标函数的地址赋值给函数指针。
- 通过函数指针调用函数:使用
(*pointer_name)(arguments)或pointer_name(arguments)语法调用函数。
#include <stdio.h>
// 定义一个函数,求两个整数的和
int add(int a, int b) {
return a + b;
}
int main() {
// 1. 定义函数指针
int (*func_ptr)(int, int);
// 2. 将函数地址赋值给函数指针
func_ptr = &add; // &可以省略,函数名即函数地址
// 3. 通过函数指针调用函数
int result = func_ptr(5, 3);
printf("Result: %d\n", result); // 输出:Result: 8
return 0;
}
int (*func_ptr)(int, int);:定义了一个函数指针,指向返回int类型、接受两个int参数的函数。func_ptr = &add;:将函数add的地址赋值给函数指针func_ptr。&符号可以省略,因为函数名本身就是函数的地址。
func_ptr(5, 3);:通过函数指针调用函数,传入参数5和3。
函数指针数组
定义函数指针数组,当需要存储多个函数的地址时,可以使用函数指针数组。
return_type (*array_name[N])(parameter_list);
array_name:数组名称。N:数组大小。
#include <stdio.h>
// 定义四个简单的运算函数
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int multiply(int a, int b) {
return a * b;
}
int divide(int a, int b) {
if (b != 0)
return a / b;
else {
printf("Division by zero!\n");
return 0;
}
}
int main() {
// 定义一个函数指针数组
int (*operations[4])(int, int) = {add, subtract, multiply, divide};
int choice;
int x = 20, y = 10;
int result;
printf("Select operation: 0-Add, 1-Subtract, 2-Multiply, 3-Divide: ");
scanf("%d", &choice);
if (choice >= 0 && choice < 4) {
// 调用选定的函数
result = operations[choice](x, y);
printf("Result: %d\n", result);
} else {
printf("Invalid choice!\n");
}
return 0;
}
int (*operations[4])(int, int):定义了一个大小为4的函数指针数组,每个元素都是指向返回int类型、接受两个int参数的函数。- 将
add、subtract、multiply、divide函数的地址赋值给数组元素。 - 根据用户输入,选择对应的函数进行计算。
回调函数
回调函数(Callback Function)是一种通过函数指针调用的函数,通常作为参数传递给另一个函数,以便在特定事件或条件下被调用。
回调函数的作用:
- 实现灵活的代码结构
- 提高程序的可扩展性和可重用性
#include <stdio.h>
// 比较函数,返回值类似strcmp
int compare_ascending(int a, int b) {
return a - b;
}
int compare_descending(int a, int b) {
return b - a;
}
// 冒泡排序函数,接受回调函数作为比较依据
void bubble_sort(int arr[], int n, int (*compare)(int, int)) {
int i, j, temp;
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - 1 - i; j++) {
if (compare(arr[j], arr[j + 1]) > 0) {
// 交换元素
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
int data[] = {5, 3, 8, 6, 2, 7, 4, 1};
int n = sizeof(data) / sizeof(data[0]);
// 排序,使用升序比较函数
bubble_sort(data, n, compare_ascending);
printf("Ascending order: ");
for (int i = 0; i < n; i++)
printf("%d ", data[i]);
printf("\n");
// 排序,使用降序比较函数
bubble_sort(data, n, compare_descending);
printf("Descending order: ");
for (int i = 0; i < n; i++)
printf("%d ", data[i]);
printf("\n");
return 0;
}
bubble_sort函数接受一个函数指针compare作为参数,用于比较数组元素。compare_ascending和compare_descending是符合要求的回调函数,用于实现不同的排序顺序。- 通过传递不同的比较函数,实现了排序方式的灵活切换。
函数指针是C语言中强大而灵活的特性,允许程序在运行时动态地调用函数。
通过函数指针,可以实现回调机制、函数表、多态性等高级功能,提高代码的灵活性和可扩展性。
在使用函数指针时,需要注意类型匹配、可读性和安全性,避免出现错误。