二维数组
int buf[2][3] = {{1,2,3},{4,5,6}};
int (*p)[3] = buf;
//定义了一个数组指针,指向int[3]这个数组类型,指向二维数组的指针
//int *p[3]; 指针数组
//p++ 指向第二行
printf("%d\n",sizeof(buf));//24
printf("%d\n",sizeof(buf[0]));//12
printf("%d\n",sizeof(p));//4
printf("%d,%d\n",p,p+1);//3996804,3996816 一行12个字节
for(int i = 0; i < (sizeof(buf)/sizeof(buf[0]));i++)
{
for(int j = 0; j < (sizeof(buf[0])/sizeof(int)); j++)
{
printf("%d\n",p[i][j]);
}
}
以上代码中出现了 两个概念,指针数组,数组指针,
指针数组
int *p1[3];
上面的这种形式构成了一个指针数组,是一个数组,数组名为p1,这个数组中的每个元素的类型都是int *,也就是说该数组包含了3个指向int类型数据的指针
数组指针
nt (*p2)[3];
上面这种形式构成了一个数组指针,是一个指向数组的指针变量,指针变量名为p2,指向的数组元素类型为int,也就是说定义了一个指向包含3个int类型数据数组的首地址,这个数组在这里没有名字,是个匿名数组。
int arr[3] = { 1,2,3};
int(*p1)[3] = &arr;
/*下面是错误的*/
int(*p2)[3] = arr;
"int *" 类型的值不能用于初始化 "int (*)[5]" 类型的实体
为什么会报错,在上一篇指针与数组中讲过,可以回头在看看。这里正好反过来了。
这里的p1,p2都指向的是整个数组,而不是数组的首元素。
指向二维数组的指针
int buf[3][5] |
二维数组名称,buf代表数组首地址 |
int (*a)[5] |
定义一个指向int [5]类型的数组指针变量a |
a[0], *(a + 0), *a |
0行,0列元素地址 |
a + 1 |
第1行首地址 |
a[1], *(a + 1) |
第1行,0列元素地址 |
a[1] + 2, *(a + 1) + 2, &a[1][2] |
第1行,2列元素地址 |
*(a[1] + 2), *(*(a + 1) + 2), a[1][2] |
第1行,2列元素的值 |
练习
不允许使用数组下标,只能通过二维数组的指针求出数组中每行和每列的平均值
int buf[3][5] = {{23,33,21,37,56},{23,23,33,88,56},{14,21,64,21,44}};
int *p[5] = buf;
//行平均值
for(int i = 0; i < (sizeof(buf)/sizeof(buf[0])); i++ )
{
int sum = 0;
for(int j = 0; j < (sizeof(buf[0])/ sizeof(int));j++)
{
sum += *(*(p +i) + j)
}
printf("%d\n",sum/(sizeof(buf[0])/ sizeof(int)));
}
//列平均值
for(int i = 0; i < (sizeof(buf[0])/ sizeof(int)); i++ )
{
int sum = 0;
for(int j = 0; j < (sizeof(buf)/sizeof(buf[0]));j++)
{
sum += *(*(p + j) + i)
}
printf("%d\n",sum/(sizeof(buf)/sizeof(buf[0])));
}