多维数组(数组的数组)及指针对其访问

首先,我要说明的,在C语言中,把“多维数组”叫做“数组的数组”更好理解一下。(下面我就统一称之为“数组的数组”
有的教程中喜欢将数组的数组用矩阵表示,不过我更趋向于直线表示,如下图(定义数组的数组int ga[2][3][5]) 
数组的数组 (如果图片太小,建议保存到电脑上对其放大查看)
我对数组的数组的理解(以ga[2][3][5]为例): 即为数组的数组,数组里面包含数组,数组作为另一个数组的元素。
int ga[2][3][5] = {ga_1[1], ga_1[2]}
         = {{ga_2[0], ga_2[1], ga_2[3]},
           {ga_2[0], ga_2[1], ga_2[3]}}
         = {{ga_3[0], ga_3[1], ga_3[2], ga_3[3], ga_3[4]},
            {ga_3[0], ga_3[1], ga_3[2], ga_3[3], ga_3[4]},
           ...(此处省略3个,上下一个6个(ga_3[0]~ga_3[4])的)
            {ga_3[0], ga_3[1], ga_3[2], ga_3[3], ga_3[4]}};  //可能这种表达有点问题!!!欢迎指出 :)

首先,我们看一下指针和一维数组的关系:
int one[5] = {0};
int *p1=one;  //一维数组就是这样子的,没错吧?

然后,再来看看指针与二维数组的关系:
int two[3][5] = {0};
int (*p2)[5] = two;  //注意和上述一维数组的关系和区别噢!

最后我们看看指针与三位数组的关系:
int three[2][3][5] = {0};
int (*p3)[3][5] = three;  //这下你应该总结出来了一点规律了吧?

是的,四维数组、五维数组、...差不多都是这样子的。

下面开始解释其原因:(请始终牢记“多维数组”即是“数组的数组)
1、上述三维数组中的ga[2]可以看作一维数组ga_1[2],其元素是ga_1[0],ga_1[1]。
2、ga_1[0]又是一个数组,其元素是ga_2[0],ga_2[1],ga_2[2],亦即是ga_1[0]可以表示为ga_1[0][3],同理有ga_1[1][3](请注意颜色!);
3、当然ga_2[0] 亦可以表示为ga_2[0][5],同理...;
4、总结的表达式就为上述很长的那个连等式;
5、还有问题需要注意,就是分割出来的子数组的首指针是指向什么位置的;
5、不知道我解释的对不对,您能看懂么? 欢迎指出错误!!!

既然上面有指针p1,p2,p3与数组有关联了,那么现在开始用指针对数组元素访问:
p1:

for ( int i = 0 ; i < 5 ; i ++ )
printf(
" one[%d] = %d\n " , i, * (p + i));

p2:

int i = 0 ,j = 0 ;
for (; i < 3 ; i ++ )
for (j = 0 ; j < 5 ; j ++ )
printf(
" two[%d][%d] = %d\n " , i, j, * ( * (p2 + i) + j));

p3:

int i = 0 ,j = 0 ,k = 0 ;
for (; i < 2 ; i ++ )
for (j = 0 ; j < 3 ; j ++ )
for (k = 0 ; k < 5 ; k ++ )
printf(
" three[%d][%d][%d] = %d\n " , * ( * ( * (p3 + i) + j) + k));

【提示:如果你想愿意可以用指针访问数组的方式,和使用数组下标访问的方式,将数组各个元素的地址打印出来,然后比较一下。打印地址的控制符是"%p"】。

另外需要注意的是:
1、在*(*(*(p3+i)+j)+k)中,当执行“p3+i”的时候数组步长为“4*3*5=60”,当执行“...+j”的时候步长为“4*5=20”,当执行“...+k”的时候步长为“4”,这里的“4”都是指int类型所在字节数。(关于数组步长的概念,请大家查阅其相关资料。)
2、int (*r)[5] = ga[1]中g[1]指的是第二个ga_2[0]地址,亦即是ga[2][3][5]被看作ga_2[2]了;
   int *t = g[1][1]中g[0][0]指的是第二个ga_2[1]地址,亦即是ga[2][3][5]被当作ga_1[2][3]了。
(这点可能有点难理解,建议上机操作一次。) 

ps:貌似用指针和下标访问的多位数组的效率是一样的,到底使用那种方式看自己对其掌握的熟练程度。但是二者所代表的含义不一样,请参考本博博文:http://www.cnblogs.com/ziwuge/archive/2011/10/24/2194813.html 中第三篇模版里提到的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值