您的位置:首页 > 其它

关于二维数组的指针理解

2018-04-11 00:20 239 查看
#include  <stdio.h>
int main()
{
int s[3][3]={{1,2,3},{4,5,6},{7,8,9}};
int (*ps)[3][3] ={&s};
printf("value:%x\n",ps[0][0]);  /*0x22fe20存着s的地址*/
printf("value:%d\n",*ps[0][0]);  /*1 首元素的内容*/

printf("value:%d\n",s[0][0]); /*1 首元素的内容*/
printf("addr:%p\n",s);  /*0x22fe20 s的地址*/
}


printf("value:%x\n",ps[0][1]);  /*0x22fe2c,即首地址+12*/
printf("value:%d\n",*ps[0][1]);  /*4*/


printf("value:%x\n",ps[1][0]);  /*0x22fe44,即首地址+36*/
printf("value:%d\n",*ps[1][0]);  /*0*/


int (*ps)[3][3]
定义的是一个指针,指针指向一个3*3的数组,实际上,只能通过它读取到s[1],s[2]和s[3],即第1、2、3行内容的首元素。

这是由于s[3][3]本身就是等同于一个s[3],而这三个数组元素中存的内容是int *,也就是各行的首地址。

也就是说,int(*x)[]这种格式,对于二维数组来说,并不适用,只能取到每行的无法直接调用x[][]。

而实际上,若定义
int (*ps)[3][3]
格式的形参,对于C来说,实际上是把它当做
int *(*ps)[3]
,也就是退化成一个指针,该指针是一个指向指针数组(包含3个元素)的指针。同理,

int *ps[3][3]
类型当做形参,也是一样。但由于
int *ps[3][3]
是3*3的指针数组,在赋值时,如果直接让它等于{&s},只能给ps[0][0]赋值,其他均是初值,只能直接读到整个数组的第一个元素。

若到在C中直接使用二维数组的指针传参,最多只能直接得到各行的首地址,其后的元素地址,需要通过指针操作来获得。

若需要把二维数组传入函数,最简便的方法,是直接传数组本身即可。

此时对于函数来说,传入的二维数组的类型为
int (*)[3]
,即为一个指向3个元素的数组指针(可直接利用下标得到元素,其实本质都是指针,但与直接传递指针不同,起到声明的效果)

#include  <stdio.h>
void test(int tmp[3][3])
{
printf("%x\t",tmp); /*22fe20*/
printf("%d\t",(tmp[1][2]));/*6*/
(tmp[1][2]) = 2;
printf("%d\t",(tmp[1][2]));/*2*/
}
int main()
{
int s[3][3]={{1,2,3},{4,5,6},{7,8,9}};
printf("%x\t",s);/*22fe20*/
test(s);
printf("%d\t",(s[1][2]));/*2*/
}


结论:在函数中传入数组,等同于传入指针,对形参的改变,会同时改变实参
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二维数组 指针 c