函数指针和指针函数

目录

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)

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值