函数指针是指向函数的指针变量,它存储的是一个函数的地址,允许通过指针间接调用函数。使用函数指针可以动态地选择和调用函数,或者将函数作为参数传递给其他函数。
1. 函数指针的定义
函数指针的定义与普通指针稍有不同。它需要声明指向特定类型函数的指针。
基本格式:
返回类型 (*指针名称)(参数类型);
示例:
int add(int a, int b) {return a + b;
}//定义指向该函数的指针:
int (*func_ptr)(int, int);
int
是函数返回的类型。(*func_ptr)
是指针变量的声明。(int, int)
是该函数的参数类型。
2. 使用函数指针
定义完函数指针后,可以通过指针调用对应的函数。
指针赋值:
func_ptr = &add; // 或直接:func_ptr = add;
通过指针调用函数:
int result = func_ptr(3, 4); // 相当于 add(3, 4)
std::cout << "Result: " << result << std::endl;
完整代码示例
#include <iostream>// 定义函数
int add(int a, int b) {return a + b;
}// 定义函数指针
int (*func_ptr)(int, int);int main() {// 赋值函数指针func_ptr = &add;// 使用函数指针调用函数int result = func_ptr(3, 4);std::cout << "Result: " << result << std::endl; // 输出:Result: 7return 0;
}
3. 函数指针的应用场景
(1) 回调函数(Callback Functions)
函数指针常用于实现回调函数机制。在很多库中,回调函数是传递给函数的指针,用于在某些条件下调用回调函数。
例子:
例如,一个排序函数可以接受一个回调函数,来决定排序的规则:
#include <iostream>
#include <algorithm>
#include <vector>// 定义一个回调函数
bool compare(int a, int b) {return a < b;
}// 排序函数接受一个函数指针
void sortArray(std::vector<int>& arr, bool (*cmp)(int, int)) {std::sort(arr.begin(), arr.end(), cmp); // 使用回调函数来排序
}int main() {std::vector<int> arr = {5, 3, 8, 1, 2};// 传递回调函数指针sortArray(arr, compare);for (int num : arr) {std::cout << num << " "; // 输出排序后的数组:1 2 3 5 8}return 0;
}
(2) 实现策略模式(Strategy Pattern)
策略模式是一种行为设计模式,允许在运行时选择不同的算法(函数)。函数指针可以作为策略的一部分,根据不同情况选择不同的函数执行。
#include <iostream>// 定义不同的操作
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }// 使用函数指针作为策略
int operate(int a, int b, int (*operation)(int, int)) {return operation(a, b);
}int main() {int result1 = operate(5, 3, add); // 使用加法策略int result2 = operate(5, 3, multiply); // 使用乘法策略std::cout << "Addition: " << result1 << std::endl; // 输出:Addition: 8std::cout << "Multiplication: " << result2 << std::endl; // 输出:Multiplication: 15return 0;
}
(3) 动态加载函数
函数指针可以实现动态加载函数,根据不同的条件加载不同的函数。这个应用场景在插件系统或者需要动态决定调用哪些函数的情况下非常有用。
#include <iostream>// 定义两个函数
void greetMorning() {std::cout << "Good morning!" << std::endl;
}void greetEvening() {std::cout << "Good evening!" << std::endl;
}int main() {void (*greetFunc)();// 根据用户输入动态选择函数int choice;std::cout << "Enter 1 for morning, 2 for evening: ";std::cin >> choice;if (choice == 1) {greetFunc = greetMorning;} else {greetFunc = greetEvening;}greetFunc(); // 调用选择的函数return 0;
}
(4) 函数作为参数
函数指针还可以作为函数参数,将一个函数传递给另一个函数。这个场景可以用于算法抽象、事件处理等场景。
例子:
#include <iostream>void printMessage(const std::string& message) {std::cout << message << std::endl;
}// 函数接受一个函数指针作为参数
void executeFunction(void (*func)(const std::string&), const std::string& msg) {func(msg);
}int main() {executeFunction(printMessage, "Hello, world!"); // 使用函数指针调用return 0;
}
4. 总结
函数指针的关键点:
- 定义:
返回类型 (*指针变量)(参数类型);
- 使用:通过函数指针调用函数(
*func_ptr()
),可以动态决定调用哪个函数。 - 应用:回调函数、策略模式、动态加载、事件处理等。
5.函数指针和指针函数的区别
- 函数指针:是指向函数的指针,允许通过指针调用不同的函数,通常用于回调函数、动态函数选择等场景。
- 指针函数:是返回指针的函数,通常用于返回数组、指向堆内存的指针等用途。