首先,我要说明的,在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:
printf("one[%d] = %d\n", i, *(p+i));
p2:
for(; i<3; i++)
for(j=0; j<5; j++)
printf("two[%d][%d] = %d\n", i, j, *(*(p2+i)+j));
p3:
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 中第三篇模版里提到的内容。
快捷操作:
坚其志,苦其心,劳其力,事无大小,必有所成。
@如有侵权,请作者本人尽快与我(chrayo#163.com)联系,我将及时删除侵权内容。