理解函数指针的基本概念
函数指针是指向函数的指针变量,可以像普通指针一样存储函数的地址。通过函数指针,可以动态调用不同的函数,实现回调机制、策略模式等灵活的设计。
#include <stdio.h>
void greet() {
printf("Hello, World!\n");
}
int main() {
void (*funcPtr)() = greet;
funcPtr(); // 输出: Hello, World!
return 0;
}
函数指针的声明与初始化
函数指针的声明需要明确函数的返回类型和参数列表。格式为:返回类型 (*指针名)(参数列表)
。
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int (*operation)(int, int) = add;
printf("Sum: %d\n", operation(3, 5)); // 输出: Sum: 8
return 0;
}
通过函数指针实现回调
函数指针常用于回调机制,允许将函数作为参数传递给其他函数。
#include <stdio.h>
void process(int a, int b, int (*callback)(int, int)) {
printf("Result: %d\n", callback(a, b));
}
int multiply(int a, int b) {
return a * b;
}
int main() {
process(4, 5, multiply); // 输出: Result: 20
return 0;
}
函数指针数组
函数指针可以存储在数组中,便于批量调用不同的函数。
#include <stdio.h>
void func1() { printf("Function 1\n"); }
void func2() { printf("Function 2\n"); }
void func3() { printf("Function 3\n"); }
int main() {
void (*funcArray[3])() = {func1, func2, func3};
for (int i = 0; i < 3; i++) {
funcArray[i]();
}
// 输出:
// Function 1
// Function 2
// Function 3
return 0;
}
函数指针与结构体结合
函数指针可以作为结构体的成员,实现类似面向对象的行为。
#include <stdio.h>
typedef struct {
int (*calculate)(int, int);
} Calculator;
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
Calculator calc;
calc.calculate = add;
printf("Add: %d\n", calc.calculate(10, 5)); // 输出: Add: 15
calc.calculate = subtract;
printf("Subtract: %d\n", calc.calculate(10, 5)); // 输出: Subtract: 5
return 0;
}
使用函数指针实现策略模式
通过函数指针动态切换算法,实现策略模式。
#include <stdio.h>
typedef int (*Strategy)(int, int);
int addStrategy(int a, int b) { return a + b; }
int multiplyStrategy(int a, int b) { return a * b; }
void executeStrategy(int a, int b, Strategy strategy) {
printf("Result: %d\n", strategy(a, b));
}
int main() {
executeStrategy(3, 4, addStrategy); // 输出: Result: 7
executeStrategy(3, 4, multiplyStrategy); // 输出: Result: 12
return 0;
}
函数指针的高级用法:返回函数指针
函数可以返回函数指针,进一步增加灵活性。
#include <stdio.h>
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
typedef int (*Operation)(int, int);
Operation getOperation(char op) {
if (op == '+') return add;
if (op == '-') return subtract;
return NULL;
}
int main() {
Operation operation = getOperation('+');
printf("Addition: %d\n", operation(5, 3)); // 输出: Addition: 8
operation = getOperation('-');
printf("Subtraction: %d\n", operation(5, 3)); // 输出: Subtraction: 2
return 0;
}
函数指针与动态链接库(DLL)
在动态链接库中使用函数指针加载和调用外部函数。
#include <stdio.h>
#include <dlfcn.h>
int main() {
void *handle = dlopen("./libexample.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
int (*dynamicFunc)(int, int) = dlsym(handle, "add");
if (!dynamicFunc) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
printf("Dynamic Add: %d\n", dynamicFunc(3, 4)); // 假设输出: Dynamic Add: 7
dlclose(handle);
return 0;
}
函数指针的注意事项
- 类型匹配:函数指针必须与目标函数的返回类型和参数列表完全匹配。
- NULL检查:调用函数指针前应检查是否为NULL,避免段错误。
- 可读性:复杂的函数指针声明可使用
typedef
简化。
#include <stdio.h>
typedef void (*SimpleFunc)();
void example() { printf("Example\n"); }
int main() {
SimpleFunc func = example;
if (func != NULL) {
func(); // 输出: Example
}
return 0;
}