浅谈C语言数组指针和函数指针

1、数组指针

A、什么是数组指针

数组指针,顾名思义,是一个指针变量,指向的对象是一个数组

这里有几点需要做出解释:

1、为什么是&arr 。arr是数组名,其本质上是数组首元素的地址,但数组指针要求指向的对象是一个数组,因而我们需要的是一个数组的地址,而&arr得到的就是arr这整个数组的地址。

2、为什么*p要加括号。这涉及到优先级的问题:[ ]这个操作符的优先级高于*。如果不加括号(),变量P会先与[ ]结合,此时p就成为一个数组,一个指向整型指针的数组

3、int (*p)[5]中的5可以省略吗。这个5不可以省略,如果省略,编译器会默认[ ]中的数为0,这样类型就不匹配了:省略5,默认p指向的类型为int[0](实际上,这个也是有问题的,因为数组元素个数必须大于0),而实际上的类型应该是int[5],二者类型不匹配

B、数组指针如何使用

数组指针通常与二维数组结合使用。

a、二维数组的数组名

在讨论数组指针的使用之前,我们需要研究一下二维数组。数组名是数组首元素的地址,对于二维数组而言,它的首元素是什么呢?

二维数组可以看成是由若干一维数组组成的,其中二维数组中的一行元素便相当于一个一维数组。因此,二维数组的首元素实际上就是二维数组第0行元素所构成的这个一维数组,二维数组首元素的地址也就是这个一维数组的地址。

数组的地址又用什么存储呢?用数组指针存储。

b、数组指针的使用

看下面这段代码及其输出结果:

可以看到,我们成功地用数组指针打印了二维数组,而其中最关键的一步在于这里:

这里有两个问题:

1、*(p+i)是什么意思?

p是一个一维数组的地址,因而p+i 进行的是数组地址的移动。p+0,就是不移动,还是该一维数组的地址;p+1,就是跳过一个一维数组,p+1即为下一个一维数组的地址。

对p+i解引用又怎么理解呢?p+i代表的是数组的地址,对其解引用,找到的自然是该地址所对应的数组。而实际上,我们用数组名代表整个数组,因此对 p+i 解引用得到的是一个一维数组的数组名。而数组名又是什么,是数组首元素的地址。

上述二维数组为arr,将其三个元素分别命名为arr1,arr2,arr3

所以,*(p+i)拿到一维数组,实质上是一维数组的数组名后,就正常进行一个一维数组的使用即可。

如果i=0,*(p+i)就是arr1,  *(arr1+j) 也就是遍历了arr1这个一维数组中的元素。

i=1,i=2时以此类推

所以,基于上述理解,我们可以对上述代码作如下改写:

而这一切的变形,归根究底源于下式:

2、函数指针

A、什么是函数指针

函数指针,顾名思义,指向一个函数的指针

这里有三个问题:

1、Add与&Add有什么区别吗?二者没有什么区别,都是Add这个函数的地址

2、(*pf1)这个括号可以去掉吗?不可以,这又设计到优先级的问题。括号()的优先级高于*,如果不加括号,pf1会先与()结合,即进行函数调用,这样是不对的,因此必须加上(), (*pf1),让pf1先与 * 结合,确保pf1是一个指针变量(pf2同理)

3、函数的类型问题。定义变量时,去掉变量名即得变量类型。所以我们可以这么理解,去掉函数名,即得函数的类型,则上述Add函数的类型为 int (int x , int y) ,当然也可以写成int (int ,int)  ,实际上注明函数形参的类型即可。

B、函数指针的使用

函数指针用于调用函数:

如上图所示,得到了我们想要的相加结果。

所以,对pf解引用,可以拿到函数Add,然后便可以如使用函数Add那般,使用*pf:*pf即为函数Add。

我们还可以对上述代码做如下改写,而不改变输出结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值