1.一维数组
创建一个数组a,输出数组a的起始地址、数组a首元素的地址,直接输出数组名a的地址,将上面的变量都偏移一个单位后再输出一遍,对比偏移前后的区别。
int a[4] = {
1,2,3,4};
//起始地址
//数组的地址
printf("&a = %p\n",&a);
//数组首元素的地址
printf("&a[0] = %p\n",&a[0]);
//直接打印数组名
printf("a=%p\n",a);
printf("====================\n");
//偏移一个单位
printf("&a+1=%p\n",&a+1);
printf("&a[0]+1=%p\n",&a[0]+1);
printf("a+1=%p\n",a+1);
输出结果:
&a = 0xffffcc00
&a[0] = 0xffffcc00
a=0xffffcc00
====================
&a+1=0xffffcc10
&a[0]+1=0xffffcc04
a+1=0xffffcc04
由输出结果可知,偏移一个单位后,&a偏移了16个字节,&a[0]偏移了4个字节,数组名a的地址也偏移了4个字节,所以我们可以理解为,&a代表了整个数组,&a[]代表了数组的一个元素,a代表了数组的第一个元素。
如下图所示:
2.二维数组
同理,创建一个二维数组a[2][3],输出各个地址后,将上面的变量都偏移一个单位后再输出一遍,对比偏移前后的区别。
int a[2][3] = {
{
1,2,3},{
4,5,6}};
printf("&a=%p\n",&a); // &a是整个数组的地址
printf("a=%p\n",a); // a是小数组的地址
printf("&a[0]=%p\n",&a[0]); // &a[0]是小数组的地址
printf("&a[0][0]=%p\n",&a[0][0]); // &a[0][0]是首元素的地址
printf("a[0]=%p\n",a[0]); // a[0]是首元素的地址
printf("=======================\n");
printf("&a+1=%p\n",&a+1);
printf("a+1=%p\n",a+1);
printf("&a[0]+1=%p\n",&a[0]+1);
printf("&a[0][0]+1=%p\n",&a[0][0]+1);
printf("a[0]+1=%p\n",a[0]+1);
输出结果:
&a=0xffffcbf0
a=0xffffcbf0
&a[0]=0xffffcbf0
&a[0][0]=0xffffcbf0
a[0]=0xffffcbf0
=======================
&a+1=0xffffcc08
a+1=0xffffcbfc
&a[0]+1=0xffffcbfc
&a[0][0]+1=0xffffcbf4
a[0]+1=0xffffcbf4
由输出结果可知,偏移一个单位后,&a 偏移了24个字节,正是该二维数组的长度,a 和 &a[0] 偏移了12个字节,是数组中一个小数组的长度;&a[0][0] 和 a[0]偏移了4个字节,是数组中一个元素的大小,所以可以得出结论:
二维数组中:
符号 | 意义 |
---|---|
&a | 整个数组的地址 |
a | 小数组的地址 |
&a[0] | 小数组的地址 |
&a[0][0] | 首元素的地址 |
a[0] | 首元素的地址 |
如下图所示: