数组指针,即指向一个数组的指针。可以指向一维数组,也可以指向二维数组(三维及以上数组一般不用)。
解析:
类型说明符 (*指针变量名)[长度]。
其中“类型说明符”为所指数组的数据类型。* 表示其后的变量p是指针类型,它指向的对象是一个整体,即一维数组(不能拆开此数组)。
【注1】
首先 运算符[ ] 的优先级比 * 高,虽然在优先级表中 [ ] 的优先级最高,其次是 ( ) 。但是 ( ) 有强制结合的功能,所以这里p是和*结合的,而不是[]。
【注2】
当数值指针指向一维数组时,n是一维数组元素的个数。 当数值指针指向二维数组时,n是二维数组的列数,即按行拆分成一维数组后,一维数组的个数。
【注3】
数组指针也叫“行指针”,原因是数组指针指向的数组不管是一维数组,还是二维数组,指针变量p指向的都是行。
【例】用“数组指针”分别指向并遍历一维数组和二维数组的所有元素。
#include <stdio.h> int main(void){ int i,j; int a[5]={1,2,3,4,5}; int b[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int (*p1)[5]=NULL; int (*p2)[4]=NULL; p1=a; //会警告提示指针类型不匹配,但是可以运行正常,应该是C隐式进行类型转换。写成 p1=&a;无警告无错误 p2=b; printf("遍历输出一维数组元素\n"); //通过数组指针来遍历输出一维数组a的元素 for(i=0;i<5;i++){ printf("%2d", *((*p1+0)+i) ); } printf("\n"); printf("遍历输出二维数组元素\n"); for(i=0;i<3;i++){ for(j=0;j<4;j++){ printf("%3d", *(*(p2+i)+j) ); } printf("\n"); } return 0; }运行结果:
在上例中,数组指针p2指向二维数组b。
下面探索一下如何使用数组指针 p2 来访问二维数组b中的每个元素。
数组指针p2指向二维数组 b 的开头,也即第 0 行;p2+1前进一行,指向第 1 行。
*(p2+1)表示取地址上的数据,也就是整个第 1 行数据。注意是一行数据,是多个数据,不是第1 行中的第0个元素。
*(p2+1)+1表示第 1 行第 1 个元素的地址。怎么理解?
*(p2+1)单独使用时表示的是第1行整体数据,放在表达式中会被转换为第 1 行数据的首地址,也就是第 1 行第 0 个元素的地址,因为使用整行数据没有实际的含义,编译器遇到这种情况都会转换为指向该行第 0 个元素的指针;就像一维数组的名字,在定义时或者和 sizeof、& 一起使用时才表示整个数组,出现在表达式中就会被转换为指向数组第 0 个元素的指针。
*(*(p2+1)+1)表示第 1 行第 1 个元素的值。很明显,增加一个 * 表示取地址上的数据。
具有指针类型元素的数组称为指针数组,实质上就是一个数组。
类型说明符 *指针变量名[长度];
【注】
如:int *p[n]; //int *(p[n])也是一个指针数组,这里小括号可有可无。 []优先级比 * 高,所以先与p结合成为一个数组,然后int *说明该数组中每个元素的数据类型都是“整形指针类型”。