C 语言 - 函数指针
函数指针
函数指针类似于普通指针,但它不是指向变量,而是指向函数。
这意味着它存储了一个函数的地址,允许您使用该指针来调用那个函数。
函数指针让您可以在程序运行时决定运行哪个函数,或者当您想将一个函数作为参数传递给另一个函数时使用。
可以把它想象成保存一个电话号码 - 指针知道函数在内存中的位置,这样您以后就可以 "呼叫" 它。
声明函数指针
声明函数指针的一般语法是:
returnType (*pointerName)(parameterType1, parameterType2, ...);
例如:
int (*ptr)(int, int);
这意味着 ptr 是一个指向函数的指针,该函数接受两个 int 值并返回一个 int。
将函数赋值给指针
您可以通过两种方式将函数赋值给指针:
ptr = add; ptr = &add;
两种方式相同,因为函数名本身已经代表了它在内存中的地址。
通过指针调用函数
一旦指针被赋值,您可以通过两种方式调用函数:
ptr(5, 3); (*ptr)(5, 3);
两种方式都有效,并且做的事情相同。
函数指针示例
既然您知道了如何声明和赋值函数指针,让我们看一个完整的例子:
实例
一个指向将两个数相加的函数的指针:
int add(int a, int b) {
return a + b;
}
int main() {
int (*ptr)(int, int) = add;
int result = ptr(5, 3);
printf("Result: %d", result);
return 0;
}
在这里:
ptr是一个指向函数add()的指针。ptr(5, 3)使用指针调用函数。
这与直接调用 add(5, 3) 的效果完全相同。
注意:函数名本身指向其代码在内存中的起始位置。这意味着函数名本身已经起到了指针的作用!声明函数指针只是为您提供了一个可以保存该地址的变量——因此您可以更改它或传递它。
将函数作为参数传递
函数指针可以传递给其他函数 - 这被称为回调。
它允许一个函数调用您作为输入提供的另一个函数。
实例
将函数指针传递给另一个函数:
void greetMorning() { printf("Good morning!\n"); }
void greetEvening() { printf("Good evening!\n"); }
void greet(void (*func)()) {
func();
}
int main() {
greet(greetMorning);
greet(greetEvening);
return 0;
}
在这里,greet() 将另一个函数作为参数并调用它。这常用于事件驱动的程序或需要用户提供回调函数的库中。
函数指针数组
您还可以将多个函数指针存储在一个数组中,这样您就可以在程序运行时选择要运行的函数。
此例使用函数指针数组运行三个不同的函数:
实例
void add() { printf("Add\n"); }
void subtract() { printf("Subtract\n"); }
void multiply() { printf("Multiply\n"); }
int main() {
void (*operations[3])() = { add, subtract, multiply };
for (int i = 0; i < 3; i++) {
operations[i]();
}
return 0;
}
这常用于简单的菜单、命令列表或计算器 - 任何您想根据用户输入调用不同函数的地方。
实例
一个使用函数指针数组的简单计算器:
void add(int a, int b) { printf("Result: %d\n", a + b); }
void subtract(int a, int b) { printf("Result: %d\n", a - b); }
void multiply(int a, int b) { printf("Result: %d\n", a * b); }
int main() {
int choice, x = 10, y = 5;
void (*operations[3])(int, int) = { add, subtract, multiply };
printf("x = %d, y = %d\n\n", x, y);
printf("Choose an operation:\n");
printf("0: Add\n1: Subtract\n2: Multiply\n");
scanf("%d", &choice);
if (choice >= 0 && choice < 3) {
operations[choice](x, y);
} else {
printf("Invalid choice!\n");
}
return 0;
}
在这个程序中:
- 三个数学函数(
add()、subtract()和multiply())存储在一个数组中。 - 用户通过输入数字选择运行哪一个。
- 然后使用指针数组调用正确的函数。
这是一个简单的例子,展示了函数指针数组如何使程序更灵活和可重用。
函数指针 vs 普通函数
| 普通函数 | 函数指针 |
|---|---|
| 通过其名称直接调用 | 通过指针调用 |
| 函数在程序运行前决定 | 可以在程序运行时选择要调用的函数 |
| 适合简单代码 | 适合灵活且可重用的代码 |
总结
- 函数指针存储函数的地址。
- 您可以通过它声明、赋值和调用函数。
- 它允许将函数作为参数传递给其他函数。
- 对于回调、菜单和灵活的程序设计很有用。