观察下面的程序:
#include <stdio.h>int main(void)
{
int i, a[2]={1,2};
int *p;
int (*pa)[2];
printf("1. a = %d\n",a);
printf("2. a+1 = %d\n",a+1);
printf("3. &a = %d\n",&a);
printf("4. &a+1 = %d\n",&a+1);
printf("5. sizeof(p) = %d\n",sizeof(p));
printf("6. sizeof(a) = %d\n",sizeof(a));
p = a;
printf("7. p = %d\n",p);
printf("8. p+1 = %d\n",p+1);
pa = a; //也可以是pa = &a;
printf("9. pa = %d\n",pa);
printf("10. pa+1 = %d\n",pa+1);
return 0;
}
运行结果:
1. a = 1245008
2. a+1 = 1245012
3. &a = 1245008
4. &a+1 = 1245016
5. sizeof(p) = 4
6. sizeof(a) = 8
7. p = 1245008
8. p+1 = 1245012
9. pa = 1245008
10. pa+1 = 1245016
1、3、7中打印出来的地址是一样的,
但是4、10要比2、7大4个字节的地址空间。
解释:
一. 1、3、7、9中打印出来的地址是一样的,
在C语言中, 在多数情况下,数组名的值是个指针常量,也就是数组第一个元素的地址。
它的类型取决于数组元素的类型: 如果它们是int类型,那么数组名的类型就是指向int的常量指针。
1. a = 1245008中,a指向a[0],a的值就是a[0]的地址;
3. &a = 1245008中,a指向整个数组,a代表整个数组,相当于int (*a)[2],整个数组的地址也是用第一个元素的地址来表示的,就是a[0]的地址;
7. p = 1245008中,p指向a[0],p的值就是a[0]的地址;此处与1情况相同;
9. pa = 1245008中,pa是指向数组的指针,数组大小是2,而p指向a数组,可以用pa = a;也可以用pa = &a;此处与3情况相同。
因此 1、3、7、9中打印出来的地址是一样的,都是a[0]的地址
二. 4、10要比2、7大4个字节的地址空间。
数组名并不是用指针常量来表示,就是当数组名作为sizeof()操作符和单目操作符&的操作数时。
A.sizeof()返回整个数组的长度,而不是指向数组的指针的长度。
B.取一个数组名的地址所产生的是一个指向数组的指针,即&a就是相当于pa,而不是一个指向某个指针常量(上面的p,也就是a,代表指向a[0])的指针。
所以&a后返回的指针便是指向数组的指针,跟a(一个指向a[0]的指针)在指针的类型上是有区别的。
可以认为sizeof(a)和&a中,此时a都是指向数组的指针,代表整个数组。