C/C++易错知识点(2):二级指针、数组指针、函数指针

指针在C语言中非常关键,除开一些常见的指针用法,还有一些可能会比较生疏,但有时却也必不可少,本文章整理了一些易错知识点,希望能有所帮助!

1.二级指针:

2ab567f99dc74a5fb7c598652e9fe23a.png

parr是一个指针数组,其中每个元素存储字符串首字符的地址

d120d1e5c04f4abb89f9e27ac31d35c2.png

parr在这里表示首元素的地址,首元素是"Hello!"的'H'的地址,所以parr表示的是'H'的地址的地址,用char**来存储,如果解引用p就得到'H'的地址,相当于parr[0]。

如果使用p + 1,就会跳过一个char*的大小,在这里是8个字节(64位平台)。要理解p的加法含义,我们需要知道内存中的每一个字节都有一个地址,这个地址相当于内存的标签,它指向我们存储的内存空间,存储该数据需要k个字节,那么这些地址的数值差也是k。

83d0070198314e248fdfc435a742380e.png

以上面的例子讲解:p对应的是首元素地址,相当于一块内存空间的标签,在p这个地址下存储char*的具体值,占了8个字节。p + 1就会找到紧接着第一个char*的下一个char*存储的内存空间的地址。p + 2同理。

0ea1c3841d1048c09ac906b4f6733734.png

139c85e5aa354b77b3e3a2e33c152b3f.png

我们可以通过这两张图看到,地址是内存空间的标签,在内存里存储数据,地址则是负责找到这块空间。理解了这里,那么指针的大部分问题都会解决。

2.一维数组指针:

注意数组指针的本质是指针,它存储的值是数组的首元素地址,象征着它指向的对象是一个数组。但是,很多人会注意到,既然存储的值和单独取首元素地址的指针存储的值相同,那么怎么区分它们?

区分它们的主要方式有以下几点:首先,指针+1跳过的大小不同,数组指针+1会跳过数组的大小,而单独取首元素地址对应的指针+1只会跳过该元素的大小。

8c52e215b4624fd294502abea2e4ab79.png

这里可以轻松算出两者之间相差32,即一个数组的大小。

4a8894914f814dfea961cb2c3adb03ad.png

注意:arr单独表示整个数组,而arr + 0 表示第一个元素地址,两者有本质区别

那么,既然两者存储的值相同,那么它们之间在除强制转换这种方法以外是否有其它转换方法?

我们知道,数组指针是对整个数组取地址,即&arr,假设这个指针表示为int (*parr) [10] = &arr,那么*parr得到的就是*(&arr)即arr,相当于首元素地址,也就是int*,所以首元素的地址也可表示为int* p = *parr。

0e73932029b74d9db407556b8bede88a.png

我们要尝试理解它的本质,不要死记硬背,学会分析会帮助我们更好的运用指针。

下面四种写法均等效:

949540125c69469b86e97d25bb34fe20.png

3.二维数组指针:

二维数组指针是一维数组指针的变形,理解了一维数组的指针,二维数组指针就可以轻松应对了。

首先熟悉一下二维数组的初始化过程:

9b0597c523454b3faf88812f898c28bd.png

其中arr[2][2]中第一个2代表2行,第二个2代表2列。

下面是有关二维数组指针易混的代码,可以尝试解释:

3a28f0ca98a045888e8938b642094d3f.png

对数组的解释具体如下图:

c068952634884c6c8526baeec6c8b07a.png

理解了这里,那么二维数组就基本掌握了,下面看看整型数组指针和整型指针的转换,加深理解:

0c57b28c28cb4c2aa6541613543df0cb.png

说到底,二维数组就是将一维数组作为元素存储在数组中,刚开始会觉得有点绕,不过多看几遍就能很好理解运用了。

注意二维数组传参:

490e53c332fa4f7ea7e8bd0ed5a19ece.png

这里arr传的是首元素(数组)地址,要用数组指针来接收,数组指针传参不能省略元素个数

57af2f1f9eb64a1ebc7c24a8aabd0a07.png

667a356193724d4d8445b19fc9a681da.png

二维数组在函数内取值要注意层级:

a10cd18a5d4f49809fc5f6599a69fc63.png

&arr是对整个arr取地址,是二维数组的指针,第一次解引用得到arr,首元素(数组)的地址,即一维数组指针,第二次解引用是对元素数组解引用,得到首元素(整型)的地址(注意理解)即int*,第三次解引用就能得到值。

4.函数指针:

函数指针一般用的不多,但是我们要清楚它的用法。对于int Fun (int a, int b),其对应的函数指针应表示为int (*pFun) (int a, int b) = Fun,当然也可写作&Fun。使用过程中,可以直接将pFun当作函数名一样使用,如pFun (1, 2)。多个函数指针也可以组成一个数组,成为函数指针数组,如int (*pFunarr[2]) (int a, int b) = { pFun1, pFun2 };它可以用于传递参数相同,且实现的功能有相似度的几种函数的集合,如加减乘除的函数的集合。


#include <stdio.h>

int add(int x, int y)
{
	return x + y;
}

int sub(int x, int y)
{
	return x - y;
}

int mul(int x, int y)
{
	return x * y;
}

int div(int x, int y)
{
	return x / y;
}

int main()
{
	int (*pFun[4]) (int x, int y) = { add, sub, mul, div };

	printf("%d\n%d\n%d\n%d", pFun[0](1, 1), pFun[1](1, 1), pFun[2](2, 3), pFun[3](8, 2));

	return 0;
}

36ce2c7dcc2d4cbcb9dc82b5376469ac.png

注意函数指针和函数指针数组传参:

b3980b27ea2a440e94dc322a41921936.png

 注意因为函数指针创建可以&fun也可直接fun,在解引用时也可选择加*或不加*

556582ccbe8d48edb81e9413dc025be6.png

但是要注意层级不要弄错:

912358fb88614f0b934b8748fad7e08f.png

这里是函数指针的指针,pFun + 1相当于找到了存储减法函数地址的地址,但是只有在减法函数地址这个层级才能使用。

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值