数组与指针声明有如此多的共同点,以至于我们通常觉得它们之间没有区别。其实不然。
首先,我们有必要重申一下一些常见形式的代码:
int a[3] = {0, 0, 0};
int *pa = a;
pa[1] = 1; //语句1
a[1] = 2; //语句2
从功效上看,语句1跟语句2一样设置数组中第2个元素的值。
但是其所产生的汇编代码却不一样,如下所示。
mov eax, dword ptr[pa]
mov dword ptr [eax + 4], 1 // 语句1
mov dword ptr [ebp-18h], 2 // 语句2
 
由此,我们可以看出变量名a实际上是一个常量,并且只能作为右值(rvalue)。
显然,
pa++; // 编译通过
a++; // 编译错误
 
另外,在使用sizeof时,它们的区别也是一目了然的。
sizeof(pa)只与编译器相关,受逻辑地址空间大小的影响;而sizeof(a)与数组长度成正比。
比如,在32位编译器中,
sizeof(pa)=4
sizeof(a)=3*sizeof(int)
 
有一个情况需要特别注意,就是当数组名作形参时。例如一下代码
void func(int a[])
{
int i = sizeof(a);
}
在这里,形参a仅仅是一个指针。