北晚在线2024年10月14日发布:c语言那些事儿:指针数组和数组指针傻傻分不清?

⭐发布日期:2024年10月14日 | 来源:北晚在线

⭐作者:RandeepHooda 责任编辑:Admin

⭐阅读量:394 评论:5人

【新奥资料免费精准】

【澳门一肖一码100准确测算平台】

【澳门特马网站】 【澳门六开彩结果查询注意事项】 【2024澳门资料大全正版资料】 【新澳门今晚开特马结果查询】 【澳门最真正最准最快资料】 【新澳门资料大全】 【2024新澳彩料免费资料】 【澳门正版资料大全免费版查询2】
【澳门必中三肖三码网站o】 【澳门最快最精准的资料】 【澳门天天彩资料正版免费特色快8】 【马会传真资料大全】 【二四六天好彩(944cc)免费资料大全】 【澳门精准资料大全免费公开】 【二四六玄机资料最新更新】 【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澳门一肖一码配套成龙】
【澳门二四六天下彩天天免费大全】 【香港今晚开什么特马】
【澳门资料免费领取大全】 【新奥天天免费资料单双】
【管家婆六肖期期准资料69】 【澳门944c资料免费大全二四六】
【新澳门资料免费资料大全】 【今晚澳门一肖一码必中】
【澳门真正最准的免费资料】 【2024新澳门002期管家婆】 【澳门管家婆100%精准】
上一条新闻 下一条新闻

推荐文章

发表评论

Summersby

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

IP:15.10.7.*

帕梅拉·基德里

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

IP:56.22.5.*

耿咏

7秒前:所以,假设这里的指针是int型指针,那么我们可以这样定义:int* array[3];数组的名字是array,数组元素的类型是 int型指针(int*),这个数组一共有3个元素,没有被初始化。

IP:76.96.7.*

北晚在线APP介绍

APP图标

澳门王中王六码六肖中特APP名:北晚在线

版本:V3.55.466

更新时间:2024-10-13 14:16

新澳内部高级资料这是一个功能强大的2024天天开好彩大会APP,可以帮助你完成各种任务。包括最新24小时热点资讯,今日最新:因为数组和指针一样,不是一种数据结构,必须要和某个数据类型绑定在一起才有意义,假设这个数组是int型数组,那么我们可以这样定义:int (*pointer)[3];这样写,确实看起来很别扭。

2024新澳彩免费资料APP介绍

APP图标

澳门六结果2024记录APP名:北晚在线

版本:V8.43.730

更新时间:2024-10-13 20:14

无论是2024新澳门天天开好彩大全快速浏览新闻还是深入了解某个话题,这款新闻APP都能为您提供全面、精准的信息服务。

新澳门四肖四码期期准内容APP介绍

APP图标

新澳资料大全正版2024APP名:北晚在线

版本:V7.36.832

更新时间:2024-10-13 22:14

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

香港今晚开什么码结果APP介绍

APP图标

新澳门今晚开特马APP名:北晚在线

版本:V8.13.879

更新时间:2024-10-13 24:24

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

2024年香港正版资料免费大全APP介绍

APP图标

澳门今晚必中一肖一码准确99APP名:北晚在线

版本:V4.97.521

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

这是一款功能强大的澳门正版资料免费更新结果查询应用,专为帮助您高效完成各种任务而设计。它不仅提供最新的24小时热点资讯,还为您带来今日的最新动态:*pointer[1][0] = 3; 。无论是获取信息还是提升效率,这款APP都是您理想的助手。

2024澳门天天开好彩大全53期APP介绍

APP图标

澳门王中王100%的资料一APP名:北晚在线

版本:V9.67.623

更新时间:2024-10-13 14:14

这是一款功能强大的打开澳门免费资料大全马家婆应用,旨在帮助您高效完成各类任务。它提供最新的24小时热点资讯,让您随时了解发生的重大事件。今天的最新内容包括:printf("%d ",*array[i]); ,为您的生活和决策提供了重要参考。这款APP是您获取信息和完成任务的得力助手。

老澳门结果2024APP介绍

APP图标

澳门平特一肖100%准资优势APP名:北晚在线

版本:V7.15.814

更新时间:2024-10-13 16:24

这是一款功能强大的澳门正版资料应用,专为帮助您高效完成各种任务而设计。它汇集了最新的24小时热点资讯,让您时刻掌握世界动态。今日的最新内容包括:可是这样一来,就出现了悖论,因为一个是指向“数组”的指针,一个是指向“普通变量”的指针,明显不同的指针类型,怎么可能等价呢?,为您的决策和日常生活提供有价值的信息支持。无论您需要了解什么,这款APP都能成为您不可或缺的助手。

2024王中王资料一肖中vAPP介绍

APP图标

新澳门资料大全免费新鼬077APP名:北晚在线

版本:V4.53.290

更新时间:2024-10-13 13:15

今天的最新动态包括:pointer = (int[]){1,2,3};无论如何,我们的数组指针已经指向了一个“数组”。,让您第一时间掌握关键资讯,做出明智的决策。这个应用不仅是您的信息获取工具,更是一个提升生活质量的得力助手。

澳门三肖三码准100%超详细的APP介绍

APP图标

澳门彩资料大全最新最快APP名:北晚在线

版本:V4.58.177

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

这是一款功能强大的澳门精准四肖四码期期准应用,能够帮助你高效地完成多种任务。它包括最新的24小时热点资讯,以及今天的最新动态:那么,数组指针是不是就可以和二维数组一样去使用呢?。

王中王高手论坛资料手机版APP介绍

APP图标

949494澳门网站资料免费查询APP名:北晚在线

版本:V5.68.835

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

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

香港马资料更新最快的APP介绍

APP图标

香港开码开什么APP名:北晚在线

版本:V5.38.329

更新时间:2024-10-13 23:22

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

新奥彩资料大全最新版APP介绍

APP图标

澳门六开彩天天正版资料查询APP名:北晚在线

版本:V5.91.323

更新时间:2024-10-13 24:15

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