由于指针可以指向任何存储器位置中的地址,因此它们也可以指向可执行代码的开头。
函数指针或函数指针指向内存中函数的可执行代码。函数指针可以存储在数组中,也可以作为参数传递给其他函数。
函数指针声明使用 * 就像使用任何指针一样:
return_type (*func_name)(parameters)
(*func_name) 周围的括号很重要。没有括号,编译器会认为函数在返回指针。
声明函数指针后,必须将其分配给函数。
下面的简短程序声明一个函数,声明一个函数指针,将该函数指针分配给该函数,然后通过该指针调用该函数:
#include
void say_hello(int num_times); /* function */
int main() {
void (*funptr)(int); /* function pointer */
funptr = say_hello; /* pointer assignment */
funptr(3); /* function call */
return 0;
}
void say_hello(int num_times) {
int k;
for (k = 0; k < num_times; k++)
printf("Hello\n");
}
函数名称指向可执行代码的开头,就像数组名称指向其第一个元素一样。
因此,尽管诸如 funptr = &say_hello 和 (*funptr)(3) 之类的语句是正确的,但在函数分配和函数调用中不必包括地址运算符&和间接运算符*。
【选词填空】声明一个函数sum,该函数返回其参数之和,并声明一个指向sum的函数指针psum。
int sum(int a, int b) {
return a b;
}
int ( psum)(int, ) = ;
*
sum
int
+
函数指针数组可以替换开关或if语句以选择动作,如以下程序所示:
#include
int add(int num1, int num2);
int subtract(int num1, int num2);
int multiply(int num1, int num2);
int divide(int num1, int num2);
int main()
{
int x, y, choice, result;
int (*op[4])(int, int);
op[0] = add;
op[1] = subtract;
op[2] = multiply;
op[3] = divide;
printf("Enter two integers: ");
scanf("%d%d", &x, &y);
printf("Enter 0 to add, 1 to subtract, 2 to multiply, or 3 to divide: ");
scanf("%d", &choice);
result = op[choice](x, y);
printf("%d", result);
return 0;
}
int add(int x, int y) {
return(x + y);
}
int subtract(int x, int y) {
return(x - y);
}
int multiply(int x, int y) {
return(x * y);
}
int divide(int x, int y) {
if (y != 0)
return (x / y);
else
return 0;
}
int (*op[4])(int, int); 语句声明函数指针的数组。每个数组元素必须具有相同的参数和返回类型。
在这种情况下,分配给数组的函数具有两个int参数并返回一个int。
【填空题】调用funcs数组指向的函数。
// suppose f1, f2, and f3 are declared
void (*funcs[3])() = {f1, f2, f3};
for (int ix = 0; ix < ; ix++) {
[ix]();
}