一、问题
常听说数组实质就是指针,是这样的吗?
二、解答
数组是⼀组数,这组数⽤下标相区分,例如:
int a[5] = {1, 3, 5, 4, 8};
产⽣5个数,这5个数是 a[0]、a[1]、…、a[4]。
指针是⼀个变量的地址。例如:
int *p;
int a = 5;
p = &a;
p是另⼀指针变量,⽤于保存另⼀变量的地址。 这样说来,指针与数组间没有任何联系。 按上⾯的定义p和a,如果再有如下语句:
p = &a[0];
这样,由于数组在内存中连续分配内存,(假设 a[0]地址为 2000,整型占两个字节),p的值是2000,*p为1,即 a[0]。
2000 1 a[0]2002 3 a[1] 2004 5 a[2]2006 4 a[3]2008 8 a[4]
注意,p+1 的值不是 2001。C语⾔中 p+1的值是由P的定义来决定的,定义时指向⼏个字节的变量,指针加1就加⼏个字节。由于p的定义是 int*p: int 占两个字节,因此p+1 就是两个字节,是2002,正好就是 a[1]的地址。
因此:
p+1 值为2002,*(p+1)为5即 a[l]
p+i 即是&a[i],⽽*(p+i)即为a[i]
以上int占两个字节只是⼀种假设,因为 int 所占字节数实际在不同系统中是不⼀样的, 但⽆论是两个字节还是四个字节,得到的结论是⼀样的。
C语⾔中规定,数组名表⽰数组⾸地址,即: a 即为&a[0]
因此:
a+1 即 *a[1];
*(a+1)即 a[l]
*(a+i)即 a[i]
C语⾔规定指针变量也可以表⽰成下标写法,即:
*(p+1)可以写成p[1]
到此为⽌,数组的所有表示法 a[i],a+i,*(a+i) 都可以有对应的指针表⽰法 p[i],p+i,*(p+i),于是结论“数组即指针,指针即数组〞好像就成⽴了。
其实这两种说法都是错的,只能说明在表示法上,⼆者可以有相同的⽅法。下⾯再对⼆者做⼀区分。
数组名表示数组⾸地址,可以说数组名是数组的指针,但它不是变量,只是⼀个常量, 即不能对数组名a进⾏重新赋值。⽽指针变量是变量,可以重新赋值。
程序中可以这样写:
p = &a[l];
p = p+1;
p++;
以上写法都是正确的。
a = p;
a = a+1;
a++;
以上三种写法试图对a的重新赋值都是错误的。
三、总结
指针与数组是两个完全不同的概念,当⽤指针表示数组时,⼆者都有下标表示法和*号表示法,数组名是⼀数组的⾸地址,是常量,指针变量可以指向数组,是变量。