C语言教程-C函数指针
我们知道我们可以创建指向任何数据类型的指针,如int、char、float,我们也可以创建指向函数的指针。函数的代码始终驻留在内存中,这意味着函数具有某个地址。我们可以通过使用函数指针来获取内存的地址。
让我们看一个简单的例子。
#include <stdio.h>
int main()
{
printf("main()函数的地址是%p", main);
return 0;
}
以上代码打印了main()函数的地址。
输出
从上面的输出中,我们可以观察到main()函数具有某个地址。因此,我们可以得出结论,每个函数都有一个地址。
函数指针的声明
到目前为止,我们已经知道函数有地址,因此我们可以创建指针来存储这些地址,并且可以指向它们。
函数指针的语法
return_type (*ptr_name)(type1, type2…);
例如:
int (*ip)(int);
在上面的声明中,*ip是一个指向返回int值且接受整数值作为参数的函数的指针。
float (*fp)(float);
在上面的声明中,*fp是一个指向返回float值且接受float值作为参数的函数的指针。
我们可以观察到函数的声明与函数指针的声明类似,只是指针前面有一个'*'。因此,在上面的声明中,fp被声明为函数而不是指针。
到目前为止,我们已经学会了如何声明函数指针。下一步是将函数的地址赋给函数指针。
float (*fp)(int, int); // 函数指针的声明。
float func(int, int); // 函数的声明。
fp = func; // 将func的地址赋给fp指针。
在上述声明中,'fp'指针包含'func'函数的地址。
注意:在将函数的地址赋给函数指针之前,必须先声明函数。
通过函数指针调用函数
我们已经知道如何以常规方式调用函数。现在,我们将看到如何使用函数指针调用函数。
假设我们如下声明一个函数:
float func(int, int); // 函数的声明。
使用常规方式调用上述函数如下所示:
result = func(a, b); // 使用常规方式调用函数。
使用函数指针调用函数如下所示:
result = (*fp)(a, b); // 使用函数指针调用函数。
或者
result = fp(a, b); // 使用函数指针调用函数,可以省略间接运算符。
通过函数名或函数指针调用函数的效果是相同的。如果我们使用函数指针,我们可以省略间接运算符,就像我们在第二种情况中所做的那样。但是,我们仍然使用间接运算符,因为它清楚地告诉用户我们在使用函数指针。
让我们通过一个例子来理解函数指针。
#include <stdio.h>
int add(int, int);
int main()
{
int a, b;
int (*ip)(int, int);
int result;
printf("输入a和b的值:");
scanf("%d %d", &a, &b);
ip = add;
result = (*ip)(a, b);
printf("相加后的值为:%d", result);
return 0;
}
int add(int a, int b)
{
int c = a + b;
return c;
}
输出
将函数的地址作为参数传递给其他函数
我们可以像向函数发送其他参数一样,将函数的地址作为参数传递给其他函数。
通过一个例子来理解。
#include <stdio.h>
void func1(void (*ptr)());
void func2();
int main()
{
func1(func2);
return 0;
}
void func1(void (*ptr)())
{
printf("函数1被调用");
(*ptr)();
}
void func2()
{
printf("\n函数2被调用");
}
在上面的代码中,我们创建了两个函数,即func1()和func2()。func1()函数包含函数指针作为参数。在main()方法中,调用func1()方法,其中我们传递了func2的地址。当调用func1()函数时,'ptr'包含'func2'的地址。在func1()函数内部,我们通过解引用指针'ptr'调用func2()函数,因为它包含了func2的地址。
输出
函数指针数组
函数指针在我们事先不知道将调用哪个函数的应用程序中使用。在函数指针数组中,数组接收不同函数的地址,并根据索引号调用适当的函数。
通过一个例子来理解。
#include <stdio.h>
float add(float, int);
float sub(float, int);
float mul(float, int);
float div(float, int);
int main()
{
float x; // 变量声明。
int y;
float (*fp[4])(float, int); // 函数指针数组的声明。
fp[0] = add; // 将函数指针数组的元素赋值为函数的地址。
fp[1] = sub;
fp[2] = mul;
fp[3] = div;
printf("输入x和y的值:");
scanf("%f %d", &x, &y);
float r = (*fp[0])(x, y); // 调用add()函数。
printf("\n两个值的和为:%f", r);
r = (*fp[1])(x, y); // 调用sub()函数。
printf("\n两个值的差为:%f", r);
r = (*fp[2])(x, y); // 调用mul()函数。
printf("\n两个值的乘积为:%f", r);
r = (*fp[3])(x, y); // 调用div()函数。
printf("\n两个值的除法为:%f", r);
return 0;
}
float add(float x, int y)
{
float a = x + y;
return a;
}
float sub(float x, int y)
{
float a = x - y;
return a;
}
float mul(float x, int y)
{
float a = x * y;
return a;
}
float div(float x, int y)
{
float a = x / y;
return a;
}
在上面的代码中,我们创建了一个函数指针数组,其中包含四个函数的地址。在将函数的地址存储在函数指针数组中之后,我们使用函数指针调用函数。
输出