这个问题很有趣,要理解有个前提,你至少要思考过数组怎样在内存中存储,并且一个字节一个字节地画过。
无论数组指针,还是指针数组,这样的名词性短语重心都在后面,所以数组指针是个指针,指针数组是个数组。
数组指针的实例:int(*p)[5]; 可以这样解释其定义:p是个指针,指向一个数组,数组有5个元素,每个元素是一个int型整数。在内存中,p就是一个占4字节的变量,变量的值是个地址,在内存的那个地址处,有4*5=20个连续字节被认为是一个int[5]数组。做一次p++,p的值增加20。这种特性和二维数组是有相似之处的,比如int k[3][5],事实上,可以这样赋值: p=k。 如果要在形参里使用,可以将变量名去除,就抽象出数据类型。典型的函数声明可以这样写:void f( int(*)[5] ); 典型的实参调用可以这样写:f(k); 这里的k是int k[3][5]二维数组。我印象里要把二维数组名作实参使用,形参只能写成数组指针,形参直接写成二维数组是不行的,void f( int [3][5]);这样声明会报错。也不能写void f( int** ); 因为int**和intint(*)[5]是不同的,前者做++只增4,后者增20。
指针数组的实例:int*p[5]; 这样解释:p是个数组,数组有5个元素,每个元素是一个指针,指向一个int型整数。这里p是数组名,是指针常量而不是变量,不可以对p赋值,这和上面比,是本质区别。从内存占用情况来看,他和int p[5]没啥区别,每个元素都占4字节。所以使用时可以参考整型数组,只要把int替换成int*就行了。比如声明时可用void f( int*[5] );,也可用void f( int** );。调用实参时,就把实际的指针数组名传入即可,比如f(t);,这里t是 int*t[5]。
这点篇幅其实是说不完的,书里都用一整章来讲呢。还是开头说的,研究一下数组及指针在内存里怎样存储,一个字节一个字节画一画,有好处。
温馨提示:内容为网友见解,仅供参考