函数指针定义
函数指针的定义形式为:
返回类型 (*指针变量名)(参数类型1, 参数类型2, ...);
有些地方给出这样的定义形式,是一样的:
returnType (*pointerName)(param list);
其中returnType为函数返回类型;pointerName为函数指针名称;param list为参数列表;
参数列表中可以同时给出参数的类型和名称,也可以只给出参数的类型,省略参数的名称,这一点和函数原型非常类似。
注意:
返回类型 (*指针变量名)(参数类型1, 参数类型2, ...);
第一个括号(*指针变量名)的括号不能省略,否则就为:
返回类型 *指针变量名(参数类型1, 参数类型2, ...);
这样就是函数原型,返回类型行为 返回类型*
使用方式如下:
#include <stdio.h>
int max(int a,int b){
return a>b?a:b;
}
int main() {
int (*func)(int,int);
func=max;//func=&max也是可以的 注解1
printf("%d\n",func(10,5));
return 0;
}
//注解1详解:
//在C++中,函数名在被使用时会隐式转换为指向函数的指针。当你使用func=max;时,编译器
//会自动将max转换为函数指针,指向函数max的地址。相同的&max也可以直接复制给函数指针max。
//两者是等效的。
回调函数
回调函数为指针函数的使用场景之一。函数指针常常用于实现回调机制。通过将一个函数指针作为参数传递给另一个函数,可以在特定事件发生时调用回调函数,实现定制化的处理逻辑。
下面是一个简单的示例演示如何编写一个回调函数:
#include <iostream>
// 回调函数类型定义
typedef void (*CallbackFunc)(int);
class EventServer {
public:
EventServer() {}
// 注册回调函数
void registerCallback(CallbackFunc callback) {
m_callback = callback;
}
// 模拟事件触发
void triggerEvent(int data) {
if (m_callback != nullptr) {
m_callback(data);
}
}
private:
CallbackFunc m_callback;
};
// 回调函数定义
void handleEvent(int data) {
std::cout << "事件处理函数被调用,数据为:" << data << std::endl;
}
int main() {
// 创建事件服务器对象
EventServer server;
// 注册回调函数
server.registerCallback(handleEvent);
// 模拟事件触发
server.triggerEvent(42);
return 0;
}
使用动态库
在程序运行时使用动态库,也是通过函数指针方式。
下面是在windows平台的使用动态库中函数的示例:
#include <iostream>
#include <windows.h>
// 声明动态库中的函数
typedef int (*AddFunc)(int, int);
typedef void (*PrintFunc)(const char*);
int main() {
// 加载动态库
HINSTANCE dllHandle = LoadLibrary("example.dll");
if (dllHandle == NULL) {
std::cerr << "无法加载动态库" << std::endl;
return 1;
}
// 获取动态库中的函数地址
AddFunc add = (AddFunc)GetProcAddress(dllHandle, "add");
PrintFunc print = (PrintFunc)GetProcAddress(dllHandle, "print");
if (add == NULL || print == NULL) {
std::cerr << "无法获取函数地址" << std::endl;
return 1;
}
// 调用动态库中的函数
int result = add(3, 4);
std::cout << "3 + 4 = " << result << std::endl;
print("Hello, dynamic library!");
// 卸载动态库
FreeLibrary(dllHandle);
return 0;
}