在一般上下文中,对数组的引用会退化为指针,例如:
int a[5];
int *p = a + 1;
在这代码中,第二行对a的引用退化为一个指针,指针类型为int。
在&a这样的表达式中数组退化为指针的规则则不再使用。作为一个整体,&a也表示一个指针,它与a不同的就是:a的指针类型为int,而&a的指针类型为int[5]。
用这段理解来解释楼主的问题就不难了
-------------------------------------------------
补充知识:
1)在c语言中,并没有真正的数组类型,大部分对数组的引用会退化为指针
2)多位数组的情况:
例如int a[x][y];
则a退化为指针类型是int[y],&a的类型则是int[x][y]
3)数组退化为指针的规则不能递归应用。数组的数组退化为数组的指针,而不是指针的指针。
如果你向函数传递一个二维数组,例:
int a[x][y];
f(a);
则f必须声明成
int f(int a[][y]);
或
int f(int (*a)[y]);
而不能是
int f(int **a);
-----------------------------------
a称作常量指针,要想真正理解数组,必须明白在表达式中出现a,a退化为指针
“数组名“之所以为常量是因为它不能被赋值,但!!数组不是指针!!。数组只是在表达式中出现时退化为指针,而指针&p与数组&a则是截然不同的行为,这正说明数组不是指针。
例如 int *p = (int *) 111;
那么p是111,而&p则是p的地址(可能为0x00122222),
但对于数组 int a[6];
若a是0x00123333,则&a也是0x00123333,只是这两者的指针类型不同
-----------------------------------------------
另外,在参数传递时数组也经常令人困惑
例如int f(char a[]);这种类型的声明,编译器内部将它当作int f(char *a);
所以可以对它传入指针。若对它传入数组,则数组退化为指针所以参数类型检验才能通过。
所以你即使声明int f(char a[4]);看上去a是个数组,在函数体内写a = 1;则违反了数组名是常量的规则,其实a = 1;是允许的因为int f(char a[4]);在编译器看来是int f(char *a);其中的4被忽略了
最后一点要注意的是在一个源文件中定义int a[5];
而在另一个源文件1中写下extern char *a是不合法的
因为数组与指针是两个类型
-----------------------------------------------
&a[0]倒是和一般上下文中a等价都是int型指针。而&a则是int[5]型指针
------------------------------------------------