1、数组内存大小
int a[5];
sizeof(a)的值为sizeof(int)*5,32位系统下为20。
sizeof(a[0])的值为sizeof(int),32位系统下为4。
sizeof(a[5])的值为sizeof(int),32位系统下为4。虽然并不存在a[5]这个元素,但是这里也并没有去真正访问 a[5],而是仅仅根据数组元素的类型来确定其值。所以这里使用 a[5]并不会出错。
sizeof(&a[0])的值在 32 位系下为 4,这很好理解。取元素 a[0]的首地址。
sizeof(&a)的值在 32 位系统下也为 4,这也很好理解。取数组 a 的首地址。
2、数组名作为左值和右值的区别
出现在赋值符号“=”右边的值就是右值,出现在左边的就是左值。
x=y,左值即为地址,x的含义是x所代表的地址。右值即为内容,y的含义是y所代表的地址里面的内容。这里就是把y地址里面的内容放到x所指的地址里面。左边的值一定是可以被修改的。
int a[5];当a为右值时其意义与&a[0]一样,代表的数组首元素的首地址。编译器并没有为数组a来分配一块内存存放其地址。a不能作为左值。
3、a和&a的区别
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
对指针进行加 1 操作,得到的是下一个元素的地址,而不是原有地址值直接加 1。一个类型为 T 的指针的移动,以 sizeof(T) 为移动单位。
&a + 1: 取数组 a 的首地址,该地址的值加上 sizeof(a) 的值,即 &a + 5*sizeof(int),也就是下一个数组的首地址,(int *)(&a+1): 则是把上一步计算出来的地址,强制转换为 int * 类型,赋值给 ptr。*(ptr-1): 因为 ptr 是指向 a[5],并且 ptr 是 int * 类型,所以 *(ptr-1) 是指向 a[4] ,输出 5。
*(a+1): a,&a 的值是一样的,但意思不一样,a 是数组首元素的首地址,也就是 a[0]的首地址,&a 是数组的首地址,a+1 是数组下一元素的首地址,即 a[1]的首地址,&a+1 是下一个数组的首地址。输出为2。
4、指针数组和数组指针
指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。int *p1[10];
数组指针:数组指针:首先它是一个指针,它指向一个数组。在 32 位系统下永远是占 4 个字节。int (*p2)[10];