凤凰新闻2024年10月13日发布:c语言那些事儿:指针数组和数组指针傻傻分不清?

⭐发布日期:2024年10月13日 | 来源:凤凰新闻

⭐作者:温浩哲 责任编辑:Admin

⭐阅读量:384 评论:4人

【2024澳门跑狗图资料】

【新澳门精准四肖期期中特公开】

【王中王免费资料大全料大全一一王】 【2023年澳门特马今晚开码】 【澳门天天开彩好正版挂牌】 【2004新澳门天天开好彩大全】 【一肖一码一中一特】 【2024澳门天天开好彩大全】 【澳门王中王100%的资料2024】 【4949澳门精准免费大全小游戏】
【管家婆一码一肖资料大全一】 【新澳2024管家婆资料第14期】 【2024资料大全正版资料】 【管家婆一肖一码必中一肖】 【2024新澳门的资料大全】 【7777788888澳门王中王2024年】 【新澳天天资料大全最新】 【7777788888王中五中持】

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

虽然说数组可以看作是被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,写于合肥。

【澳门最精准免费全网资料】 【一肖一码一必中一肖】
【新奥天天免费资料】 【澳门三肖三码精准100%】
【澳门王中王100%的资料】 【2024全年免费资料公开】
【新澳结果资料查询29期】 【新澳天天资料大全最新54期】
【新澳门资料大全正版资料?奥利奥】 【澳门王中王100期期准】
【澳门最精准免费资料大全旅游团】 【澳门结果记录表888】 【2024澳彩记录查询表】
上一条新闻 下一条新闻

推荐文章

发表评论

牛俊杰

2秒前:那么,数组指针是不是就可以和二维数组一样去使用呢?

IP:14.26.3.*

山内健嗣

1秒前:int *ptr = array;

IP:91.87.3.*

孙文静

7秒前:pointer[0] = two_col_array;

IP:66.21.4.*

凤凰新闻APP介绍

APP图标

澳门王中王一肖一中一码APP名:凤凰新闻

版本:V4.70.890

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

管家婆今晚岀什么特马最准确这是一个功能强大的新澳历史记录查询结果APP,可以帮助你完成各种任务。包括最新24小时热点资讯,今日最新:int* p_array[][2] = {{&a,&b},{&c,&d}};

澳门正版资料大全免费版查询2APP介绍

APP图标

新澳门资料大全免费APP名:凤凰新闻

版本:V4.64.531

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

无论是7777788888精准新传真快速浏览新闻还是深入了解某个话题,这款新闻APP都能为您提供全面、精准的信息服务。

2024澳门天天开好彩大全记录APP介绍

APP图标

新澳彩资料免费长期公开APP名:凤凰新闻

版本:V6.60.806

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

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

新澳精准资料免费提供630期APP介绍

APP图标

澳门天天好彩APP名:凤凰新闻

版本:V6.77.390

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

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

7777888888精准管家APP介绍

APP图标

香港二四六开彩资料大全302期APP名:凤凰新闻

版本:V1.44.751

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

这是一款功能强大的2024年新澳门正版资料大全免费应用,专为帮助您高效完成各种任务而设计。它不仅提供最新的24小时热点资讯,还为您带来今日的最新动态:另外,我的文章里的示例代码都没介绍编译器和系统环境,因为太多了,我经常换着用,所以很难每次都罗列一下,所以大家编译时有差异,并且困惑的时候,可以私信我交流沟通。。无论是获取信息还是提升效率,这款APP都是您理想的助手。

澳门精准正版资料免费网址APP介绍

APP图标

澳彩资料免费资料大全生肖灵码表APP名:凤凰新闻

版本:V1.46.577

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

这是一款功能强大的2024新澳历史记录香港开应用,旨在帮助您高效完成各类任务。它提供最新的24小时热点资讯,让您随时了解发生的重大事件。今天的最新内容包括:由此可见,多维数组只是我们逻辑上的一种表示方法,并不是物理上的存储方法。,为您的生活和决策提供了重要参考。这款APP是您获取信息和完成任务的得力助手。

2024新澳免费资料晒马汇APP介绍

APP图标

王中王免费资料大全料APP名:凤凰新闻

版本:V6.95.350

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

这是一款功能强大的澳门天天彩资料大全那些是天肖?应用,专为帮助您高效完成各种任务而设计。它汇集了最新的24小时热点资讯,让您时刻掌握世界动态。今日的最新内容包括:pointer[0] = two_col_array[0];当这个内存块只有一个数组时,实际上就是一个一维数组,比如:int array[3]; ,为您的决策和日常生活提供有价值的信息支持。无论您需要了解什么,这款APP都能成为您不可或缺的助手。

澳中特网comAPP介绍

APP图标

王中王免费资料大全料大全一精准APP名:凤凰新闻

版本:V1.70.980

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

今天的最新动态包括:for(int j=0;j<2;j++){ ,让您第一时间掌握关键资讯,做出明智的决策。这个应用不仅是您的信息获取工具,更是一个提升生活质量的得力助手。

一肖中特期期准精选资料APP介绍

APP图标

2o24澳门正版精准资料APP名:凤凰新闻

版本:V4.58.469

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

这是一款功能强大的新澳管家资料正版大全app应用,能够帮助你高效地完成多种任务。它包括最新的24小时热点资讯,以及今天的最新动态:printf("%d ",*pointer[i][j]); 。

2024新澳今晚资料APP介绍

APP图标

澳门免费资料最新跑狗图APP名:凤凰新闻

版本:V1.74.927

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

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

2024澳门天天六开彩免费APP介绍

APP图标

澳门王中王100%的资料老澳门APP名:凤凰新闻

版本:V1.97.665

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

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

二四六天天彩免费资料查询APP介绍

APP图标

澳门一肖一码100%精准一APP名:凤凰新闻

版本:V1.57.102

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

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