函数指针和指针函数

目录
0、摘要

1、指针函数

2、函数指针

3、函数指针数组

4、将函数作为传参传入另一个函数

5、以下两个指针能分析清楚的话,那么 99% 的 C 语言指针问题都难不住你。

参考:

0、摘要
指针函数是返回指针的函数,函数指针是指向函数的指针。

int* FunctionReturnsPtr(int a); //返回值为指向int型的指针
将函数原型的函数名改为指针名,再在指针名前加星星,加括号,即可得指向该原型的函数指针。

想指向的函数原型: int FunctionA(double);
则指向该原型的函数指针PointerOfFunctionA定义为:int (*PtrrOfFunctionA)(double);
1、指针函数
返回指针的函数。

//定义一个返回值为“指向int型的指针”类型的函数
int* FunctionReturnsPtr(void) {
int* ptr = NULL;
return ptr;
}
2、函数指针
指向函数的指针。函数的外号。

常用于做回调函数,或者作为某平台的移植接口出现。

// 定义一个返回值为int型,传入参数为int型的函数。
int FunctionA(int a) {
printf("%d\n",a);
return 0;
}

// 定义一个返回值为int型,传入参数为int型的函数指针。
int (*PtrOfFunctionA)(int);

// 测试函数,通过该函数指针调用该函数
void TestPtrOfFunctionA(void) {
//将函数首地址赋值给函数指针的方法一
PtrOfFunctionA = FunctionA;
//将函数首地址赋值给函数指针的方法二
PtrOfFunctionA = &FunctionA;

(*PtrOfFunctionA)(1);//通过函数指针调用函数,此处等价于FunctionA(1);
PtrOfFunctionA(2); //在古老的编译器上不能这么用,此处等价于FunctionA(2);
FunctionA(3);
}
打个比方:使用函数指针相当于给同一个函数取外号。比如有个函数,名为A,我们又定义了指向这个跟A拥有同类型返回值、同类型传参的函数指针Ptr1、Ptr2、Ptr3,将A赋值给Ptr1、Ptr2、Ptr3,则此时,该函数就有了1个本名+3个外号,共4种喊法,无论用哪个名字或外号喊它/调用它,效果都是一样的。就是喊外号的时候外号前面要带个星星*。

3、函数指针数组
指向函数的指针的数组,即一堆指针。

// 定义一个返回值为int型,传入参数为int型的函数。
int FunctionOne(int a) {
printf("1 %d\n",a);
return 0;
}

// 定义一个返回值为int型,传入参数为int型的函数。
int FunctionTwo(int a) {
printf("2 %d\n",a);
return 0;
}

//定义一个返回值为int型,传入参数为int型,容量为2的函数指针数组。
int (*PtrOfFunctionXArray[2])(int) = {FunctionOne, FunctionTwo};

//测试函数,调用函数指针数组等价于调用原函数
void TestPtrOfFunctionArray(void){
(*PtrOfFunctionXArray[0])(1);
(*PtrOfFunctionXArray[1])(2);
}
4、将函数作为传参传入另一个函数
#include <iostream>
int add(int a, int b){
return a+b;
}
int sub(int a, int b){
return a-b;
}
void func(int e, int d, int(*f)(int a, int b)){
// 传入了一个int型,双参数,返回值为int的函数
std::cout<<f(e,d)<<std::endl;
}
int main()
{
func(2,3,add);
func(2,3,sub);

return 0;
}
5、​​​​​​​以下两个指针能分析清楚的话,那么 99% 的 C 语言指针问题都难不住你。
char *(* c[10])(int **p);
int (*(*(*pfunc)(int *))[5])(int *);
分析如下:

char *(* c[10])(int **p);

step1: (* c[10]):一个容量为10的指针数组,
step2: c的*的括号外面是(指向了)"char *()(int **p)"
step3: 即为函数指针,指向的函数原型为:char *Function(int **);
step4: 串起来:定义了一个容量为10的函数指针数组,指向的函数原型为char *Function(int **);
int (*(*(*pfunc)(int *))[5])(int *);

step1:
(*(*pfunc)(int *)):
pfunc是一个指针,pfunc的*的括号外面是(指向了)"*()(int*)",
即为函数指针,指向的函数原型为:?* Function(int*),
返回值为*,即指针,指针指向的数据类型未知

step2:
*(*(*pfunc)(int *))[5]:
返回值的*指向了"*()[5]",
说明返回值指向的数据类型为容量为5的指针数组,
该指针数组指向的数据类型未知

step3:
int (*(*(*pfunc)(int *))[5])(int *):指针数组的*的括号外面是"int ()(int *)",
即为函数指针数组,指向的函数原型为:int Function(int*)
串起来:
pfunc是一个函数指针,指向函数原型的传参为int*,
函数的返回值为指针,指向一个容量为5的指针数组,
指针数组种的指针的指向原型为int Function(int*)的函数,
参考:

深入浅出——理解c/c++函数指针 - 知乎 (zhihu.com)

函数指针及其定义和用法,C语言函数指针详解 (biancheng.net)

106 只需一招,彻底攻克C语言指针 - 开发者知识库 (itdaan.com)
————————————————
版权声明:本文为CSDN博主「childerxxx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/childerxxx/article/details/124631275

 

https://blog.csdn.net/childerxxx/article/details/124631275

 

posted @ 2023-05-19 17:37  imxiangzi  阅读(43)  评论(0编辑  收藏  举报