数组指针应该结合二维数组多维数组来理解
本质与区别
指针数组是数组元素为指针的数组(例如 int *p[3],定义了p[0],p[1],p[2]三个指针),其本质为数组。
数组指针的使用在某些情况下与指针数组很相似,要注意区别。
二维数组指针
编辑为了能更好地理解数组指针,与普通指针及二级指针的区别,下面举例说明一下。
例如:
1
2
3
4
|
{ 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]的作用就是帮助你记忆说你所指向的一维数组的长度。(不过除了与定义的二维数组的长度一致的不会警告之外 )其他的数会警告但是不影响结果。
相关区别
编辑一、指向一维数组的指针变量设一维数组为a[n]
定义方法:*指针变量名即*P
这个p一般指向的一维数组的首地址,即p=a,或者p=&a[0];p,a,&a[0]均指向同一单元,它们是数组a的首地址,也是0号元素a[0]的首地址。p+1,a+1,&a[1]均指向1号元素a[1]。类推可知p+i,a+i,&a[i]。
例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
main() { int a[5],i,*pa; pa=a; for (i=0;i<5;i++) { *pa=i; pa++; } pa=a; for (i=0;i<5;i++) { printf ( "a[%d]=%d\n" ,i,*pa); pa++; } } |
二、指向二维数组的指针变量设二维数组为a[m][n]
定义方法:(*指针变量名)[长度]即(*P)[n]
“长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。
1、多维数组有关概念
注意a[0],a[1],a[2]表示的都是对应那行的数组首地址,和数组名,而不是一个元素
多维数组地址的表示方法
设有整型二维数组a[3][4]如下:
设有整型二维数组a[3][4]如下:
1
2
3
|
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 |
设数组a的首地址为1000,各下标变量的首地址及其值如图所示。在第四章中介绍过,C语言允许把一个二维数组分解为多个一维数组来处理。因此数组a可分解为三个一维数组,即a[0],a[1],a[2]。每一个一维数组又含有四个元素。例如a[0]数组,含有a[0][0],a[0][1],a[0][2],a[0][3]四个元素。数组及数组元素的地址表示如下:a是二维数组名,也是二维数组0行的首地址,等于1000。a[0]是第一个一维数组的数组名和首地址,因此也为1000。*(a+0)或*a是与a[0]等效的,它表示一维数组a[0]0号元素的首地址。也为1000。&a[0][0]是二维数组a的0行0列元素首地址,同样是1000。因此,a,a[0],*(a+0),*a,&a[0][0]是相等的。同理,a+1是二维数组1行的首地址,等于1004。a[1]是第二个一维数组的数组名和首地址,因此也为1004。&a[1][0]是二维数组a的1行0列元素地址,也是1004。因此a+1,a[1],*(a+1),&a[1][0]是等同的。由此可得出:a+i,a[i],*(a+i),&a[i][0]是等同的。此外,&a[i]和a[i]也是等同的。因为在二维数组中不能把&a[i]理解为元素a[i]的地址,不存在元素a[i]。
C语言规定,它是一种地址计算方法,表示数组a第i行首地址。由此,我们得出:a[i],&a[i],*(a+i)和a+i也都是等同的。另外,a[0]也可以看成是a[0]+0是一维数组a[0]的0号元素的首地址,而a[0]+1则是a[0]的1号元素首地址,由此可得出a[i]+j则是一维数组a[i]的j号元素首地址,它等于&a[i][j]。由a[i]=*(a+i)得a[i]+j=*(a+i)+j,由于*(a+i)+j是二维数组a的i行j列元素的首地址。该元素的值等于*(*(a+i)+j)。
C语言规定,它是一种地址计算方法,表示数组a第i行首地址。由此,我们得出:a[i],&a[i],*(a+i)和a+i也都是等同的。另外,a[0]也可以看成是a[0]+0是一维数组a[0]的0号元素的首地址,而a[0]+1则是a[0]的1号元素首地址,由此可得出a[i]+j则是一维数组a[i]的j号元素首地址,它等于&a[i][j]。由a[i]=*(a+i)得a[i]+j=*(a+i)+j,由于*(a+i)+j是二维数组a的i行j列元素的首地址。该元素的值等于*(*(a+i)+j)。
举例
编辑数组指针:
1
2
3
4
5
6
7
8
|
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int (*p)[4]; p=( int (*)[4])a; for ( int i=0;i<3;i++) { for ( int j=0;j<4;j++) printf ( "%d" ,p[i][j]); //或者 *(*(p+i)+j) 或者 *(p[i]+j) printf ( "\n" ); } |
指针数组:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int ix=0; int i=0,j=0; int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int *p[3]; for (ix;ix<3;ix++) p[ix]=a[ix]; for (i;i<3;i++) { for (j=0;j<4;j++) //注意这里的j要赋值等于0,要不然只能输出第一行1234,达不到预期的效果 { printf ( "%d" ,p[i][j]); //或者 *(*(p+i)+j) 或者 *(p[i]+j) } printf ( "\n" ); } |