数组的地址问题
例:
int a[10]={1,2,3,4,5,6,7,8,9,10};
a、a[0]、&a、&a[0]是什么?
a+1、&a+1是什么?
sizeof(a)、sizeof(a[0])、sizeof(&a)、sizeof(&a[0])的值各是什么?
当我们定义一个数组int a[10]时,编译器会分配一块内存,这块内存的名字命名为a,这个a只是一个名字,只是方便编译器和编程者使用,编译器并不为这个名字分配空间来存储它。
我们可以用a[0]、a[1]来访问数组内的元素。a作为右值(位于等号的右边)时,表示的是数组第一个元素的地址(意义与&a[0]一样,但&a[0]是一个指针变量,编译器会为他分配空间,a却不一样,编译器并不为它分配什么空间),而并非数组首地址,&a才表示数组的首地址。
注意:数组的地址和数组第一个元素的地址,虽然它俩地址的值一样,但两个地址指的数据类型不一样,数组的地址指向类型是整个数组,数组第一个元素的地址指向类型是第一个元素。
所以,a是这个数组所在的内存的名字,当它为右值时,表示数组首元素的地址,a[0]是数组的第一个元素,其值等于1,&a是整个数组的首地址,它是一个指针;&a[0]是数组首元素的地址,它的值和a做右值时一样,但意义不同,因为&a[0]是一个指针,编译器要为它分配存储空间,但a却不会被分配存储空间,a也不是指针型变量。
代码测试:
void test(void)
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
printf("%p\n",a);
printf("%p\n",a+1);
printf("%p\n",&a);
printf("%p\n",&a+1);
printf("%p\n",&a[0]);
printf("%p\n",&a[0]+1);
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(&a[0]));
}
输出结果:
- a是数组首元素地址0x200007a4;
- a+1为数组元素地址后移一个int型的偏移量,即0x200007a4+4;
- &a是整个数组的地址0x200007a4;
- &a+1整个数组的地址后移整个数组空间大小的偏移量,即0x200007a4+4*10=0x200007cc;
- &a[0]是数组首元素地址0x200007a4,注意:&a[0]是一个指针,编译器要为它分配存储空间,但a不是指针型变量,不会被分配存储空间;
- &a[0]+1为数组元素地址后移一个int型的偏移量,即0x200007a4+4;
- sizeof(a)是整个数组所占内存大小:4*10;
- sizeof(a[0])是首元素1所占内存大小:4;
- sizeof(&a)是数组的地址所占内存大小:4;
- sizeof(&a[0])是首元素1的地址所占内存大小:4。