C语言之指针的奥秘(二)
创始人
2024-12-27 12:38:41
0

一、数组名的理解

int arr[10]={1,2,3,4,5,6,7,8,9,10}; int *p=&arr[0];
这里使用 &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,而且是数组首元素的地址。如下:

 我们发现数组名和数组⾸元素的地址打印出的结果⼀模⼀样,数组名就是数组⾸元素(第⼀个元素)的地址

数组名如果是数组首元素的地址,那下⾯的代码怎么理解呢?

#include  int main() { 	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; 	printf("%d\n", sizeof(arr)); 	return 0; }

输出的结果是:40。 如果arr是数组⾸元素的地址,那输出应该的应该是4/8才对。

其实数组名就是数组首元素(第⼀个元素)的地址是对的,但是有两个例外:

①sizeof(数组名),sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节

②&数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)

除此之外,任何地方使用数组名,数组名都表示首元素的地址。

这里我们发现&arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,是因为&arr[0] 和 arr 都是首元素的地址,+1就是跳过一个元素。但是&arr 和 &arr+1相差40个字节,这就是因为&arr是数组的地址,+1 操作是跳过整个数组的。

二、使用指针访问数组

数组在内存中是连续存放的

指针的加减运算,方便我们获得每一个元素的地址

#include int main() { 	int arr[10] = { 0 }; 	//使用指针来访问数组 	int sz = sizeof(arr) / sizeof(arr[0]); 	//输入10个值 	int* p = arr; 	int i = 0; 	for (i = 0; i < sz; i++) 	{ 		//输入 		scanf("%d", p + i);//p+i == &arr[i] 	} 	//输出10个值 	for (i = 0; i < sz; i++) 	{ 		printf("%d ", *(p + i)); 	} 	return 0; }

数组名arr是数组首元素的地址,可以赋值给p,数组名arr和p这里是等价的。

p[i]等价于*(p+i),arr[i]等价于*(arr+i),数组元素在访问编译器处理的时候,也是转换成首元素的地址 +偏移量求出元素的地址,然后解引用来访问。

1.数组就是数组,是一块连续的空间(数组的大小和数组元素类型都有关系)

2.指针(变量)就是指针(变量),是一个变量(4/8个字节)

3.数组名是地址,是首元素的地址

4.可以使用指针来访问数组

拓展: 

三、一维数组传参的本质

我们之前都是在函数外部计算数组的元素个数,那我们可以把函数传给一个函数后,函数内部求元素个数吗?

我们发现在函数内部没有正确获得数组的元素个数。 

这就要学习数组传参的本质了,上篇文章写道:数组名是数组⾸元素的地址;那么在数组传参的时候,传递的是数组名,也就是说本质上数组传参本质上传递的是数组首元素的地址。

所以函数形参的部分理论上应该使用指针变量来接收首元素的地址。那么在函数内部我们写 sizeof(arr) 计算的是⼀个地址的大小(单位字节)而不是数组的大小(单位字节)。正是因为函数的参数部分是本质是指针,所以在函数内部是没办法求的数组元素个数的。

1. 数组传参的本质是传递了数组首元素的地址,所以形参访问的数组和实参的数组是同一个数组。

2.形参的数组是不会单独再创建数组空间的,所以形参的数组是可以省略数组大小的。

结论:一维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。本质上是指针变量 。

四、二级指针 

指针变量是变量,是变量就有地址,那指针变量的地址存放在哪里呢?这就是二级指针

int**就是二级指针:

*pp通过对pp中的地址解引用,这样找到的是p,*pp其实访问的就是p;

**pp先通过*pp找到p,然后对p进行解引用操作,找到的就是a。

 

五、指针数组

整型数组是存放整型的数组,字符数组是存放字符的数组,那么,指针数组是存放指针的数组

 

指针数组的每个元素是地址,又可以指向一块区域。

六、指针数组模拟二维数组

#include int main() { 	int arr1[] = { 1,2,3,4,5 }; 	int arr2[] = { 2,3,4,5,6 }; 	int arr3[] = { 3,4,5,6,7 }; 	int* parr[3] = { arr1,arr2,arr3 }; 	//打印数组 	int i = 1; 	for (i = 0; i < 3; i++) 	{ 		int j = 0; 		for (j = 0; j < 5; j++) 		{ 			printf("%d ", parr[i][j]); 		} 		printf("\n"); 	} 	return 0; }

 画图演示:

*(arr1+j)==arr1[j]

*(*(arr+i)+j)==arr[i][j]

parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型⼀维数组,parr[i][j]就是整型⼀维数组中的元素。上述的代码模拟出二维数组的效果,实际上并非完全是二维数组,因为每一行并非是连续的。

相关内容

热门资讯

终于知道”新荣耀房卡领取码“牛... 终于知道”新荣耀房卡领取码“牛牛房卡哪里有卖微信房卡充值 添加房卡批售商:微【113857776】复...
终于知道”新久情房卡怎么得“牛... 终于知道”新久情房卡怎么得“牛牛房卡最低价格 微信牛牛房卡客服微信号微信游戏中心打开微信,添加客服【...
终于知道”新天道房卡获取“新道... 终于知道”新天道房卡获取“新道游房间卡怎么购买 微信牛牛房卡客服微信号微信游戏中心打开微信,添加客服...
终于知道”人海大厅房卡充值“炸... 终于知道”人海大厅房卡充值“炸金花房间卡怎么购买 微信牛牛房卡客服微信号微信游戏中心打开微信,添加客...
终于知道”财神在哪里买房卡“新... 来教大家如何使用在哪里买房卡房卡充值 添加房卡批售商:微【113857775】复制到微信搜索、直接添...
终于知道”新长虹如何买房卡“新... 终于知道”新长虹如何买房卡“新猴王大厅房间卡怎么购买 微信牛牛房卡客服微信号微信游戏中心打开微信,添...
终于知道”新金龙房卡领取码“人... 房卡领取码是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:113857776许多玩家在游戏中会购买房...
终于知道”新九哥房卡在哪里买“... 房卡在哪里买是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:113857776许多玩家在游戏中会购买...
终于知道”新八戒房卡怎么得“人... 终于知道”新八戒房卡怎么得“人海大厅房卡充值 微信牛牛房卡客服微信号微信游戏中心打开微信,添加客服【...
终于知道”新卡农房卡到哪里买“... 终于知道”新卡农房卡到哪里买“先锋大厅房间卡怎么购买微信房卡充值 添加房卡批售商:微【1138577...
终于知道”新财神哪里买低价获取... 来教大家如何使用哪里买低价获取房卡充值 添加房卡批售商:微【113857775】复制到微信搜索、直接...
终于知道”新天道在哪里买房卡“... 终于知道”新天道在哪里买房卡“王者大厅房间卡怎么购买 微信牛牛房卡客服微信号微信游戏中心打开微信,添...
终于知道”新详心房卡购买“拼十... 终于知道”新详心房卡购买“拼十房卡充值游戏中心打开微信,添加客服【113857776】,进入游戏中心...
终于知道”新老夫子房卡购买“王... 来教大家如何使用房卡充值房卡充值 添加房卡批售商:微【113857775】复制到微信搜索、直接添加房...
终于知道”新九游是如何购买的“... 第二也可以在游戏内商城:在游戏界面中找到 “微信金花,斗牛链接房卡”“商城”选项,选择房卡的购买选项...
终于知道”新上游房卡哪里充“先... 终于知道”新上游房卡哪里充“先锋大厅房间卡怎么购买微信房卡充值 添加房卡批售商:微【11385777...
终于知道”新九天获得房卡链接渠... 来教大家如何使用获得房卡链接渠道房卡充值 添加房卡批售商:微【113857775】复制到微信搜索、直...
终于知道”大众互娱在哪里买房卡... 终于知道”大众互娱在哪里买房卡“牛牛房卡哪里有卖 微信牛牛房卡客服微信号微信游戏中心打开微信,添加客...
终于知道”九九房卡获取方式“先... 终于知道”九九房卡获取方式“先锋大厅房间卡怎么购买微信房卡充值 添加房卡批售商:微【11385777...
终于知道”新荣耀获得房卡链接渠... 终于知道”新荣耀获得房卡链接渠道“新道游房卡充值微信房卡充值 添加房卡批售商:微【113857776...