头条资讯2024年10月13日发布:c语言那些事儿:指针数组和数组指针傻傻分不清?

⭐发布日期:2024年10月13日 | 来源:头条资讯

⭐作者:孟慧圆 责任编辑:Admin

⭐阅读量:160 评论:1人

【7777788888王中王论坛】

【新澳门三肖三码必出】

【7777888888管家婆网】 【揭秘新澳门一肖一码精准资料】 【新澳门今期结果查询表图片2024年】 【澳l门正版资料免费资料查询】 【2024香港正版资料免费】 【安徽、吉林、宁夏书记调整】 【新奥最精准资料】 【新澳门2024资料大全下载】
【管家婆一肖一码最准资料92期】 【2024年澳门精准资料免费】 【2024澳门管家婆免费资料23】 【一码一肖100准刘伯温】 【澳门六合资料网站】 【澳门六结果2024记录查询】 【澳门六开彩结果资料查询2024】 【澳门最准四不像】

原本在我看来,“指针数组”和“数组指针”是两个并不相近的知识点。因为前一个的“主体”是数组,后一个的“主体”是指针,主体都不同。

虽然说数组可以看作是被const修饰的指针(常量类型的指针),但是这仅仅是为了理解方便,数组是分配在栈(stack)上的,而指针指向的内存,一般都是动态分配的,更多的是在堆(heap)上,使用起来要加倍小心,更为复杂(指针当然也可以指向栈上的数据)。

但是前几天我写了一篇剖析“常量指针”和“指针常量”的文章,在几个平台上发布之后,有一些朋友给我私信说,能不能写写“指针数组”和“数组指针”,也做一个“深度的解剖”,所以才有了今天这篇文章。

指针数组,其实说详细点,就是数组元素的类型是“指针”的数组。因为指针这个概念是不能独立存在的,必须要和具体的数据类型绑定在一起才有意义。所以,假设这里的指针是int型指针,那么我们可以这样定义:

int* array[3];

数组的名字是array,数组元素的类型是 int型指针(int*),这个数组一共有3个元素,没有被初始化。这个数组因为它的元素都是指针,我们称为“指针数组”。

总结一下,指针数组首先得是一个数组,然后它的元素类型一定是指针,满足这个条件就可以确定是“指针数组”了,只是要注意定义的格式,以免写错。

我们简单的举个例子,来对这个数组进行操作。

int* array[3];
int x,y,z;
array[0] = &x;
array[1] = &y;
array[2] = &z;
for(int i=0;i<3;i++){
	*array[i] = i * i ;
	printf("%d ",*array[i]);
}

这行代码的输出结果如下图:

程序运行的结果

首先定义一个指针数组和三个变量,然后将变量的地址赋值给数组的元素。最后通过数组元素间接的给变量赋值,并演示了通过数组元素显示变量的“值”,核心在于始终记得数组元素就是一个指针就可以了。

另外,指针数组可以是任意维的数组,比如我们定义一个二维的指针数组,并且对第三个元素赋值(变量的地址):

int* array[][3];
int x = 3;
array[0][2] = &x;

二维数组概念此处不展开,因为后面数组指针里要说到。

数组指针,说详细点,就是指向某种类型的数组的指针。核心在于这次不是数组,而是指针。只是这个指针指向的是“数组”。因为数组和指针一样,不是一种数据结构,必须要和某个数据类型绑定在一起才有意义,假设这个数组是int型数组,那么我们可以这样定义:

int (*pointer)[3];

这样写,确实看起来很别扭。如果改成这样:int[3] (*pointer);我们可能看的更明白些。

int[3] 是数组类型,有3个元素,(*ponter)是指针,和 int[3]结合起来,就是指向int[3]整型数组的pointer指针了。但是很遗憾,c语言不支持这样的写法

我再次强调一下,“数组指针”,是一个指针,这个指针特别的地方在于它不是指向一个普通的变量,而是指向一个数组结构(对,不是数据结构)。

也就是说它的“值”是一个数组的地址。通常我们都把数组名作为数组的地址对待,或者数组首元素的地址作为数组的地址对待,这两者在一般情况下是没有区别的(仅在一般情况下,此处不展开)。

因此,我们很容易就可以写出给数组指针赋值的语句,比如用数组名给数组指针pointer赋值:

int (*pointer)[3];
int array[3];
pointer = array;

或者,将数组首元素的地址赋值给数组指针pointer:

int (*pointer)[3];
int array[3];
pointer = &array[0];

当然也可以给数组指针pointer赋值一个匿名数组:

int (*pointer)[3];
pointer = (int[]){1,2,3};

无论如何,我们的数组指针已经指向了一个“数组”。那么我们如何通过数组指针来访问它说指向的数组的每一个元素呢?

我们尝试着这样:

int (*poiter)[3];
int array[3];
pointer = array;
pointer[0] = 1;//error

我们认为pointer = array; 说明pointer和array其实指向了同一个地址,那么通过指针pointer访问array的第一个元素,和array去访问第一个元素的用法应该一样才对啊。但为什么array[0]可以,pointer[0]不可以呢?

实际上,你应该能想到,不可以才是正确的,因为假设可以,那么下面这段代码:

int array[3];
int *ptr = array;
ptr[0] = 1;

ptr去访问array的元素是可以的,实际上此时的ptr和array就是等价的,如果上面的pointer也可以这样,那么就意味着pointer和ptr是等价的,因为pointer和array等价,ptr和array也等价。

可是这样一来,就出现了悖论,因为一个是指向“数组”的指针,一个是指向“普通变量”的指针,明显不同的指针类型,怎么可能等价呢?

我想这大概才是很多人迷惑的原因吧!

实际上,在之前的一些文章里,我提到过,这里的ptr虽然可以被数组名直接赋值,但实际上它指向的实际上不是数组,而是数组的第一个元素的地址。这有什么不同呢?

我其实不想把一个问题解剖的太细,因为这样会增加复杂度,但是在这里有必要稍微详细说一下。

数组名的“值”和数组第一个元素的地址的“值”看起来是同一个值,也可以相互混用去给别的指针赋值,但是实际上他们代表的含义是完全不同的。

数组名代表的是整个数组的地址,比如这个数组的元素是3个int型,假设在你的系统环境里int占据4个字节,那么数组名实际上代表的是占据了12个字节的这个内存块的地址。

而数组首个元素的地址,代表的是这个元素在内存中所占据的4个字节的内存地址。只是他们两者的“值”是相同的,所以我们就经常混用,而不加以区分了。

所以,你应该意识到 ptr = array;不是准确的写法。正确的写法是 ptr = &array[0]; 因为ptr它是一个指向“普通变量”的指针,而array[0]是一个普通变量,array不是,他是很多相同类型的普通变量组合成的一个“特殊”类型。

感谢你看到这里,你真的很有耐心。

因此,pointer指向的是这样一种情况:一个内存块是由一个或多个数组组成的,而pointer指向了这个内存块的地址(就是首地址)。

假设这个内存块由两个数组组成,其实就是一个“二维数组”。比如:

int two_col_array[2][3];
int (*pointer)[3];
pointer = two_col_array;

那么,显而易见pointer[0]其实就是two_col_array第一个数组的地址,pointer[1]其实就是two_col_array第二个数组的地址。

那么下面这几条语句都是等价的:

pointer = two_col_array;
pointer = two_col_array[0];
pointer[0] = two_col_array;
pointer[0] = two_col_array[0];

当这个内存块只有一个数组时,实际上就是一个一维数组,比如:

int array[3];
int (*pointer)[3];

那么以此类推,下面这几条语句也是等价的:

pointer = array;
pointer = &array[0];
pointer[0] = array;
pointer[0] = &array[0];

只是在二维数组中,其中某个一维数组的名字仍然是地址,而在一维数组中,只有pointer[0],没有pointer[1]而已。

所以回到最初,当我们想通过pointer修改指向的数组的元素的值时,我们只要把pointer看成是一个“二维数组的名字”就可以了。比如:

int array[3];
int (*pointer)[3] = array;
pointer[0][0] = 99;
pointer[0][1] = 520;
pointer[0][2] = 1314;

我们通过pointer把数组array的3个元素分别赋了值。

我们再举一个略显复杂的例子来看一看(没用循环赋值,是为了把二维数组的特点体现的更明显一点):

int a,b,c,d;
int* p_array[][2] = {{&a,&b},{&c,&d}};
int* (*pointer)[2] = p_array;
*pointer[0][0] = 1;
*pointer[0][1] = 2;
*pointer[1][0] = 3;
*pointer[1][1] = 4;
for(int i=0;i<2;i++){
		for(int j=0;j<2;j++){
			printf("%d ",*pointer[i][j]);
	} 
}

pointer指向的是一个二维数组,这个二维数组是一个指针数组,这个例子是为了演示数组指针和指针数组在一起时该如何使用。

如果你对二维数组稍微了解些的话,你就已经意识到了所谓的数组指针其实和二维数组是很相似的。

学习编程的最好办法,除了多写代码,就是将近似的知识点在一起比较分析,这是最快的学习方式。

今天这个主题就讲到这里,其实还有很多可以展开的知识点,比如二维数组在内存中仍然是顺序存放的,以此类推,无论多少维的数组,在内存中其实都是线性存储的。

由此可见,多维数组只是我们逻辑上的一种表示方法,并不是物理上的存储方法。那么,数组指针是不是就可以和二维数组一样去使用呢?他们有没有异同?等等,感兴趣的朋友可以继续深挖。

另外,我的文章里的示例代码都没介绍编译器和系统环境,因为太多了,我经常换着用,所以很难每次都罗列一下,所以大家编译时有差异,并且困惑的时候,可以私信我交流沟通。

段誉,2024.1.29,写于合肥。

【2024澳门新版资料大全】 【7777788888是哪个账号】
【今晚新澳门直播视频下载】 【新澳六开彩历史记录】
【澳门资料大全免费资料2024年免费下载】 【2O23澳门资料大全政版资料网站】
【澳门资料免费】 【旧澳彩结果历史记录】
【48k澳门彩库开什么】 【494949最快结果】
【赢彩二四六旺角彩】 【2024年香港资料免费大全】 【今晚会出什么特号】
上一条新闻 下一条新闻

推荐文章

发表评论

董艺薇

4秒前:实际上,你应该能想到,不可以才是正确的,因为假设可以,那么下面这段代码:int array[3];

IP:83.41.7.*

杨武龙

6秒前:pointer[0] = two_col_array;

IP:70.38.6.*

简·怀曼

1秒前:那么我们如何通过数组指针来访问它说指向的数组的每一个元素呢?

IP:21.26.9.*

头条资讯APP介绍

APP图标

57235.cσm查询澳彩APP名:头条资讯

版本:V9.20.519

更新时间:2024-10-12 23:16

澳门彩结果2024记录查询表这是一个功能强大的奥门一肖一码100%精准APP,可以帮助你完成各种任务。包括最新24小时热点资讯,今日最新:但是很遗憾,c语言不支持这样的写法。

半夜钟声敲三下打一生肖APP介绍

APP图标

香港6合结果+记录17APP名:头条资讯

版本:V4.48.615

更新时间:2024-10-12 15:21

无论是六肖中特期期准王中王软件特色快速浏览新闻还是深入了解某个话题,这款新闻APP都能为您提供全面、精准的信息服务。

400500好彩堂王中王王APP介绍

APP图标

2024正版管家婆免费资料APP名:头条资讯

版本:V8.50.934

更新时间:2024-10-12 21:21

四川广安车祸多人倒地应用界面简洁易用,用户可以轻松浏览头条新闻、深度报道和特写文章。24小时内的热点资讯一目了然,让您随时掌握世界动态。此外,您还可以参与评论,与其他读者交流看法,形成一个互动活跃的社区。

澚门码今天的资料APP介绍

APP图标

心水正版资料免费更新下载APP名:头条资讯

版本:V5.58.423

更新时间:2024-10-12 16:20

2024最新澳门开特马这款新闻APP是您获取实时信息的理想伴侣。它汇聚了全球最新的新闻报道,涵盖政治、经济、科技、娱乐、体育等多个领域。通过个性化推荐功能,您可以根据兴趣定制新闻源,确保每条信息都与您相关。

香港开什么号APP介绍

APP图标

澳门6合和彩app下载APP名:头条资讯

版本:V5.58.191

更新时间:2024-10-12 14:18

这是一款功能强大的俄称死神无人机危险接近战机应用,专为帮助您高效完成各种任务而设计。它不仅提供最新的24小时热点资讯,还为您带来今日的最新动态:for(int i=0;i<3;i++){ 。无论是获取信息还是提升效率,这款APP都是您理想的助手。

新澳门彩今天开什么查询APP介绍

APP图标

小马哥无错精准资料APP名:头条资讯

版本:V1.67.847

更新时间:2024-10-12 21:17

这是一款功能强大的溴门免费资料大全应用,旨在帮助您高效完成各类任务。它提供最新的24小时热点资讯,让您随时了解发生的重大事件。今天的最新内容包括:我们简单的举个例子,来对这个数组进行操作。,为您的生活和决策提供了重要参考。这款APP是您获取信息和完成任务的得力助手。

中国女童向马斯克报BUG成功APP介绍

APP图标

澳门今晚开码开什么号APP名:头条资讯

版本:V5.12.516

更新时间:2024-10-12 16:16

这是一款功能强大的王中王心水王资料全文应用,专为帮助您高效完成各种任务而设计。它汇集了最新的24小时热点资讯,让您时刻掌握世界动态。今日的最新内容包括:printf("%d ",*pointer[i][j]); ,为您的决策和日常生活提供有价值的信息支持。无论您需要了解什么,这款APP都能成为您不可或缺的助手。

澳门黄大仙精准资料网站APP介绍

APP图标

管家婆一肖一码100正确APP名:头条资讯

版本:V6.45.443

更新时间:2024-10-12 24:20

今天的最新动态包括:pointer[0] = two_col_array[0];当这个内存块只有一个数组时,实际上就是一个一维数组,比如:int array[3]; ,让您第一时间掌握关键资讯,做出明智的决策。这个应用不仅是您的信息获取工具,更是一个提升生活质量的得力助手。

7777788888香港马APP介绍

APP图标

港澳免费资料大全APP名:头条资讯

版本:V9.33.983

更新时间:2024-10-12 17:18

这是一款功能强大的二四六免费资料大全板块应用,能够帮助你高效地完成多种任务。它包括最新的24小时热点资讯,以及今天的最新动态:for(int j=0;j<2;j++){ 。

男子深夜停车场开车撞人APP介绍

APP图标

香港结果记录APP名:头条资讯

版本:V8.55.453

更新时间:2024-10-12 23:16

这款功能强大的308k二天玄机彩图应用旨在提升您的日常效率,帮助您轻松应对各种任务。应用界面友好直观,用户可以快速导航,获取所需信息。它不仅提供最新的24小时热点资讯,还定期更新各种主题的文章和评论,确保您始终走在信息的前沿。

王中王心水高手主论坛资料一一:一APP介绍

APP图标

2024新奥资料免费大全APP名:头条资讯

版本:V5.30.164

更新时间:2024-10-12 17:13

这款新闻APP是您获取实时新闻的最佳选择。它整合了全球各大新闻来源,提供最新的头条、热点和专题报道,涵盖从政治到娱乐的各个领域。用户可以根据兴趣自定义新闻推送,确保获取最相关的信息。

天下彩9944CC图APP介绍

APP图标

今天澳门晚上出什么马APP名:头条资讯

版本:V6.98.449

更新时间:2024-10-12 22:17

APP界面友好,支持快速浏览和离线阅读。您还可以通过搜索功能,快速找到特定主题的新闻。互动功能让您可以评论、分享文章,与朋友讨论热点话题。无论您是在通勤、休闲,还是工作间隙,这款APP都能让您轻松掌握最新动态。