二维数组的指针变量
------指向二维数组元素的指针变量
int main()
{ static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p;
for(p=a[0];p<a[0]+12;p++)
{ if((p-a[0])%4==0) printf("\n");
printf("%4d ",*p);
}
return 0;
}
debug看看。
看看图上几个地址都是一样。
当p = a时为什么会报错呢?
error C2440: '=' : cannot convert from 'int [3][4]' to 'int *'
分析一下:
二维数组,可以理解为一维数组的嵌套。
a是一个一维数组,包括a[0],a[1],a[2],3个元素
而元素a[0]又是一个一维数组,包括a[0][0],a[0][1],a[0][2],a[0][3]
同理,a[1],a[2]也是一维数组
a[0]是a[0][0],a[0][1],a[0][2],a[0][3]的数组名,数组名是数组首元素的地址
所以a[0]是a[0][0]的地址,同理a[1]是a[1][0]的地址,a[2]是a[2][0]的地址。
再同理,a是a[0],a[1],a[2]的数组名,所以数组名a是首元素a[0]的地址。
所以,a的地址和a[0],a[0][0]的地址都是一样的。
但是a是一个有三个元素的数组,它这三个单元里存放着一个有四个元素的一维数组,p=a就是让一个指向int型的指针变量指向int[4]这个数组了(且把int[4]看成一种类型)。错在这里。
改一下。int (*pi)[4] = a;
也可以把a地址的变量类型转换成int的
p=(int *)a;
就不会报错了。
所以:
p=*a; //对
p=&a[0][0]; //对
p=(int *)a; //对
p=a; //错
-------指向一维数组的指针变量
定义形式: 数据类型 (*指针名)[一维数组维数];
例 int (*p)[4]; //p的值是一维数组的首地址,p是行指针
可让p指向二维数组某一行
如 int a[3][4], (*p)[4]=a; //注意一维数组指针变量维数和二维数组列数必须相同 //( )不能少,[]优先级比*高
//int (*p)[4]与int *p[4]不同
int main()
{ static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int i,j,(*p)[4];
for(p=a,i=0;i<3;i++,p++)
for(j=0;j<4;j++)
printf("%d ",*(*p+j));
printf("\n");
return 0;
}
分析:p是指向一个有4个元素的一维数组的指针变量
p=a[0]; //错 a[0]是a[0][0]的地址,a[0][0]是int型的
p=*a; //错 *a是第0行第0列元素的地址,这元素是int型的
p=&a[0][0]; //错 &a[0][0] 地址的变量类型是int
p=&a[0]; //对 a[0]是a的首元素,它的地址就和a是一样的,a[0]里存放的就是int[4]
表示形式 | 含义 | 地址 |
a | 二维数组名,数组首地址 | 2000 |
a[0],*(a+0),*a | 第0行第0列元素地址 | 2000 |
a+1,&a[i] | 第1行首地址 | 2008 |
a[1],*(a+1) | 第1行第0列元素地址 | 2008 |
*(a[1]+0),*(*(a+1)+0),a[1][0] | 第1行第0列元素值 | 11 |
a[1]+2,*(a+1)+2,&a[1][2] | 第1行第2列元素地址 | 2012 |
*(a[1]+2),*(*(a+1)+2),a[1][2] | 第1行第2列元素值 | 14 |
定义array[i][j]
则有
访问二维数组元素
第一种方式:*(array[i] + j)
第二种方式:*(*(array+i) + j)
访问第i行首地址:array+i
访问第i行第j列元素地址:*(array + i) + j