【C语言进阶】指针进阶(函数指针)

目录

1.函数指针

2.函数类型

3. 看几个代码

练习

代码分析1

代码分析2

4.函数的解引用

5.函数指针数组

6.练习


1.函数指针

  • 数组指针:指向数组的指针
  • 函数指针:指向函数的指针(存放函数地址的指针
  • 数组arr:arr是首元素地址,&arr是整个数组地址
  • 函数没有首元素的概念,所以函数名和&函数名都是函数的地址

2.函数类型

 首先看一下数组指针:int arr[10];

  • 怎么存储&arr,整个数组的地址呢
  • 首先&arr说明是个地址,地址就需要指针存储,所以是*p
  • 然后,arr是个数组,说明p指向的是个数组,数组arr10个元素,所以(*p)[10],[]比*的优先级别高
  • 最后,arr里面每个元素int类型,所以数组指针的写法是int (*p)[10]
  • 数组指针类型就是去掉变量名p,int (*)[10]

所以函数存储:int (*p)(int,int) = ADD;

  • 因为函数地址,需要指针接收 *p
  • 看到(),代表是个函数,p指向一个函数
  • 函数参数类型是int,int(int x ,int y也可以,但是这里只要说明函数形参参数的类型就行,没必要写形参)
  • 最后看函数的返回类型是int
  • 函数指针类型:int (*)(int,int)

  • 程序也可以说明,&函数名和函数名没区别,都是函数的地址
  • *p1 找到ADD函数

3. 看几个代码

练习

  • fun1 ✔
  • fun2 ❌
  • 因为()比 * 的优先级高

代码分析1

  • (*): 说明是个指针
  • void (*)():说明是个函数指针,没有参数,且返回值为void,没有返回值
  • (类型)------> 强制类型转换
  • void (*)() ) 0:  将一个整数0强制转换成函数指针类型,意味着把0当作一个函数地址。没有参数,且返回值为void,没有返回值
  • (* ( void (*)() ) 0 )(): * 找到这个函数,没有参数,返回值void的函数

代码分析2

  • signal() :说明signal一个函数
  • signal( int,void(*)(int) ):第一个参数为int类型,第二个参数是函数指针类型(没有参数,且返回值为void)
  • 将整个代码去掉上面一行后为 void (*)(int) :说明整个signal函数的返回类型是一个函数指针,参数是int,返回值值void

  •  类似于这种形式

  •  但上面图片这种写法是错误的,signal返回类型是一个函数指针,那么*就要靠着signal

 利用typedef优化一下:

  • 将函数指针类型重新定义不能按照传统的写法

  •  要写成这种形式

  •  所以将之前的代码优化为

4.函数的解引用

  • 这里我们第一个*p找到函数ADD
  • 那为什么**p和***p都能找到ADD呢?
  • 答案:* 在这里不起作用 


 

简单分析:

int (*p)(int,int)  = ADD或者&ADD;

当&ADD的时候,*p就找到ADD这个函数。所以*p是等价于ADD的。所以(*p)(2,3) == ADD(2,3)

而之前说了&ADD和ADD没有区别,那么说明p和ADD也就没区别,类似于一维数组,见下图。所以p(2,3) == ADD(2,3)

 总之就是:

&地址,就要*找到它        int (*p)(int,int)  = &ADD------>(*p)==ADD

如果直接 地址,那么就不需要*去找它        int (*p)(int,int)  = ADD------>p==ADD

5.函数指针数组

  • parr[4] :说明是个数组,有四个元素
  • int (*)(int,int):函数指针类型,说明parr是个函数指针数组

正确使用:

 

6.练习

 

  • 第一个是函数指针数组:parr1先和[]结合是数组,有10个元素。每个元素都是函数指针,无参数,返回值int类型
  • 第二个瞎写的(❌)
  • 第三个和第一个一样,但是我们说,不能这样写,parr3[10]要放到*的后面(❌)

练习一下:

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听风吹等浪起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值