数组名+1和&数组名+1的区别

数组名+1和&数组名+1的区别

一、数组名的含义

首先理解 首元素地址数组的首地址 两个概念。

首元素地址,即数组第一个元素的地址;数组的首地址,即整个数组的首地址。二者在值上是相等的(因为数组的首地址也是从第一个元素开始的),但是二者的含义是不同的。

比如首元素地址加 1 ,即表示第二个元素的地址,期跨度为一个元素所占的字节;而数组的首地址加 1 ,其跨度为整个数组,如果 int a[5] ,那么跨度就是 4*5 = 20 ,即地址会加 20 个字节。

1、一维数组
int array_1[6] = {0};//数组名array_1 含义为指向这个一维数组的 首元素的地址 

一维数组的数组名表示数组首元素的地址(区别于数组的首地址)。它是一个指向第一个元素的指针常量。正因为是常量,所以array_1 ++ 就是一个错误的表达,常量不存在 + + 操作,所以要想访问第二个元素,需要 array_1+1 来实现。

2、二维数组

二维数组常规理解为行和列,这里换个角度看待二维数组。

二维数组看成是一个一维数组,然后这个一维数组的每个元素都是由另一个一维数组组成。

int array_2[2][4] = {0};
/* 
(1)二维数组实际上就是元素为一维数组的数组
(2)二维数组名可以看做指向其第一个元素(一维数组)的指针
*/

把array_2看成是一个有两个元素组成的一维数组,然后这个一维数组的两个元素都是由四个元素的一维数组组成。这边把第一个一维数组称为第一维数组,第二个一维数组称为第二维数组

array_2表示第一维数组的数组名,所以其是指向第一维数组的首元素的。

array_2[0]、array_2[1] 分别表示两个第二维数组的数组名,它们的长度都是4。将array_2[0]、array_2[1] 当做整体来看待,例如a[4]、b[4] 为两个一维数组,这里将 a 当成 array_2[0],将 b当成 array_2[1]。

综上,二维数组的数组名,实际上是指向第一维数组的首元素的指针,而这个首元素的内容为第二维数组的首元素地址,即,*array_2 与 array_2[0] 是等价的( * 表示解引用,所以此处 *array_2 表示的是第一维数组的首元素的内容,这个内容是指向第二维数组的首元素;array_2[0] 为第二维数组的数组名,所以 array_2[0] 也是指向第二维数组的首元素)( *array_ 2 + 1 等价于 array_2[0] + 1,可自行验证)。
所以二维数组的数组名是指向指针的指针常量,类似于二重指针。

3、三维数组及多维数组

三维及以上数组,和二维数组类似的分析,不再赘述。

二、&数组名的含义

对数组名取地址所产生的值的类型是一个指向整个数组的指针,而不是一个指向指针常量的指针。所以&array的类型是指向整个数组的指针,而array是指向array[0]的指针,虽然在数值上相同,但是在类型上不同。

正因为它们的类型不同,所以在加1或减1的时候,颗粒度不同。array以一个数组元素为颗粒度,以 int array[5] = {0} 为例,例子中的数组元素为整型,所以array加1时地址加4;而&array以整个数组为颗粒度,例子中的数组为有5个元素的整型数组,所以&array加1时,地址加20。&a 是整个数组的首地址,a是数组首元素的首地址,其值相同但意义不同。

三、具体运行结果

/******一维数组******/ 
short int array_1[6] = {0};
printf("///******一维数组******///\t"); 				
printf("short int array_1[6] = {0};\t");			
printf("(1)          array_1 = %d\t", array_1); 		
printf("(2)      array_1 + 1 = %d\t", array_1 + 1);		
printf("(3)         &array_1 = %d\t", &array_1); 		
printf("(4)     &array_1 + 1 = %d\t", &array_1 + 1);	
putchar('\n');
printf("(5)       array_1[0] = %d\t", array_1[0]); 		
printf("(6)   array_1[0] + 1 = %d\t", array_1[0] + 1);	
printf("(7)      &array_1[0] = %d\t", &array_1[0]); 	
printf("(8)  &array_1[0] + 1 = %d\t", &array_1[0] + 1);	
putchar('\n');	
/******二维数组******/ 
short int array_2[2][4] = {0};
printf("///******二维数组******///\n");
printf("short int array_2[2][4] = {0};\n");
printf("(1)          array_2 = %d\n", array_2);
printf("(2)      array_2 + 1 = %d\n", array_2 + 1);
printf("(3)         &array_2 = %d\n", &array_2);
printf("(4)     &array_2 + 1 = %d\n", &array_2 + 1);
printf("(5)       array_2[0] = %d\n", array_2[0]);
printf("(6)   array_2[0] + 1 = %d\n", array_2[0] + 1);
printf("(7)      &array_2[0] = %d\n", &array_2[0]);
printf("(8)  &array_2[0] + 1 = %d\n", &array_2[0] + 1);
printf("(9)       array_2[0][0] = %d\n", array_2[0][0]);
printf("(10)  array_2[0][0] + 1 = %d\n", array_2[0][0] + 1);
printf("(11)     &array_2[0][0] = %d\n", &array_2[0][0]);
printf("(12) &array_2[0][0] + 1 = %d\n", &array_2[0][0] + 1);
/******三维数组******/
short int array_3[2][3][4] = {0};
printf("\n///******三维数组******///\n"); 
printf("short int array_3[2][3][4] = {0};\n");
printf("(1)          array_3 = %d\n", array_3);
printf("(2)      array_3 + 1 = %d\n", array_3 + 1);
printf("(3)         &array_3 = %d\n", &array_3);
printf("(4)     &array_3 + 1 = %d\n", &array_3 + 1);
putchar('\n');
	
printf("(5)       array_3[0] = %d\n", array_3[0]);
printf("(6)   array_3[0] + 1 = %d\n", array_3[0] + 1);
printf("(7)      &array_3[0] = %d\n", &array_3[0]);
printf("(8)  &array_3[0] + 1 = %d\n", &array_3[0] + 1);
putchar('\n');

printf("(9)      array_3[0][0] = %d\n", array_3[0][0]);
printf("(10) array_3[0][0] + 1 = %d\n", array_3[0][0] + 1);
printf("(11)    &array_3[0][0] = %d\n", &array_3[0][0]);
printf("(12)&array_3[0][0] + 1 = %d\n", &array_3[0][0] + 1);
putchar('\n');
	
printf("(13)	    array_3[0][0][0] = %d\n", array_3[0][0][0]);
printf("(14)  	array_3[0][0][0] + 1 = %d\n", array_3[0][0][0] + 1);
printf("(15)	   &array_3[0][0][0] = %d\n", &array_3[0][0][0]);
printf("(16)   &array_3[0][0][0] + 1 = %d\n", &array_3[0][0][0] + 1);

注:以上均用的 short int 类型,即一个元素占 2 个字节。
结果如下:
在这里插入图片描述

  • 15
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值