如何声明数组指针?
数组指针:形如 char (*c)[10];这样的声明,c是一个指向包含10个字符型元素的数组的指针,即指向数组首元素地址的指针;
{
int a[4][5];
int (*p)[5]=a;
}
这里a是个二维数组的数组名,相当于一个二级指针常量;//二维数组名与二级指针毫无关系(初学者常常混淆)。
p是一个指针变量,它指向包含5个int元素的一维数组,此时p的增量以它所指向的一维数组长度为单位;
*(p+i)是一维数组a[i][0]的地址;
*(p+2)+3表示a[2][3]地址(第一行为0行,第一列为0列),*(*(p+2)+3)表示a[2][3]的值。
//(*p)[5]其中的5换成其他的数字在vc++6.0环境中都无法通过编译
(*p)[5]其中的5在上述例子中没有表示任何意思你可以换成除0以外的整数,[5]的作用就是帮助你记忆说你所指向的一维数组的长度。(不过除了与定义的二维数组的长度一致的不会警告之外 )其他的数会警告但是不影响结果。(百度百科)
“二维数组、数组指针、指针数组(Iliffe向量)”相关概念见https://blog.csdn.net/qq_39478139/article/details/107615646
此处不再赘述。
首先看一个例子,预测并对比p++,r++,t++每次增加的步长是多少字节。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
int a[2][3][4];
int (*p)[3][4] = a;
int (*r)[4] = a[0];
int *t = a[0][0];
printf("p=%d r=%d t=%d\n",p,r,t);
printf("p=%d r=%d t=%d\n",++p,++r,++t);
return 0;
}
打印结果:(其中int类型占4bytes)
p=6421920 r=6421920 t=6421920
p=6421968 r=6421936 t=6421924
步长(t) =1 *4bytes = 4bytes;
步长(r) =4 *4bytes = 16bytes;
步长(p)=4*3*4bytes = 48bytes;
那么上例中p、r、t 各代表什么意思呢?
int (*p)[3][4] = a; 声明了*p是一个“拥有着3个数组,而这每一个数组拥有4个整型元素”的数组,因此,p就是一个指向这样的数组的指针;
类似的,*r是一个拥有“4个整型元素”的数组,r是一个指向该数组的指针;
由于在某种场合下(数组作为函数定义的形式参数),数组名代表数组首元素的地址,那么a[0][0]代表元素a[0][0][0]的地址,所以t是一个指向a[0][0][0]的指针;
因此,p的步长为12*4bytes;r的步长为4*4bytes;t的步长为1*4bytes;
不妨再看一个例子,
#include <stdio.h>
#include <stdlib.h>
void test(char **ptr){
int i = 3;
while(i--){
printf("%s\n",*ptr++);
}
}
int main(int argc, char** argv)
{
char *p[3] = {"abc", "defg", "hijkl"};//指针数组
char c[3][5];
char (*q)[5] = c;//数组指针
test(p);
printf("%d\n",q);
q++;
printf("%d\n",q);//+5bytes
char (*r)[3][5] = &c;
r++;
printf("%d\n",r);//+15bytes
return 0;
}
通过第一个例子,可以很轻松的计算出q的步长;这里的r代表了整个数组的步长。
char (*r)[3][5] = &c; 声明了*r是一个“拥有3个数组,每个数组有5个整型元素”的数组,而r是一个指向这样的数组的指针;char类型大小为1byte,所以r的步长为3*5*1byte。
思考:对于数组a[3],a,&a,a+1,&a+1有什么区别?&a占内存吗?
关于这个问题的解释请看:https://blog.csdn.net/qq_39478139/article/details/107807421 数组名a和数组名取地址&a的区别