数组
数组是什么?
《C primer plus》上面对数组的定义是:数组由数据类型相同的一系列元素组成。但由于这本书面向C语言入门读者,对于深入学习的我来说,不得不继续深入思考数组到底是什么,下面是我自己对于数组的认识:
- 从数组ADT的逻辑结构来看:数组的逻辑结构是线性的,也就是说,数组元素之间的关系为线性关系。
- 从数组数据元素的存储方面来看:数组指的是从一维的地址空间中开辟一段连续的地址空间,也就是说它的地址空间关系即是线性的又是顺序的。
多维数组
在探讨多维数组之前,我们先来看一些简单的创建数组的例子,我将通过这些简单的例子来说明问题:
一维的创建:
int main()
{
char a[10];
for (int i = 0; i < 10; i++) {
a[i] = i;
printf("%p\n", &a[i]);
}
return 0;
}
二维数组的创建:
int main()
{
char a[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
a[i][j] = 3;
printf("a[%d][%d] address is %p\n", i, j, &a[i][j]);
}
}
return 0;
}
三维数组的创建:
由于在这里的三维数组是动态数组,也就是说是在堆上分配的空间,请读者一定要记得自行释放分配的空间。
#define SPACE 3
#define LINE 3
#define ROW 3
int main()
{
char ***arry = (char ***)malloc(SPACE*sizeof(char **));
for (int i = 0; i < SPACE; i++) {
arry[i] = (char **)malloc(LINE*sizeof(char*));
for (int j = 0; j < ROW; j++) {
arry[i][j] = (char *)malloc(ROW*sizeof(char));
}
}
for (int i = 0; i < SPACE; i++) {
for (int j = 0; j < LINE; j++) {
for (int k = 0; k < ROW; k++) {
printf("arry[%d][%d][%d] addres is %p\n", i, j, k, &arry[i][j][k]);
}
}
}
for (int i = 0; i < SPACE; i++) {
for (int j = 0; j < LINE; j++) {
free(arry[i][j]);
}
}
for (int i = 0; i < SPACE; i++) {
free(arry[i]);
}
free(arry);
return 0;
}
观察以上数组元素的地址我们会发现,不论是几维数组,按照数组下表来看,它们的地址都是在连续的一维地址空间中分配的,这也就是说我们仍然可以将多维数组看成一种特殊的线性表,其特殊性在于表中的数据元素本身也是一个线性表。
以上面的三维数组***arry为例:
由上图,一个n(n>1)维数组可以看成是由n-1维数组的数据元素构成的一维数组,只不过这里的一维数组是指针数组罢了。
数组元素的地址计算
假设j1,j2…jn为数组元素的下标,j1,j2,jn,的下限为c1,c2…cn,上限为d1,d2…dn,每个元素占据size个存储单元那么对于n维数组location(arry[j1][j2]…[j(n-1)][jn]) = location(arry[c1][c2]…[c(n-1)][cn]) + (j1-c1)(d2-c2+1)(d3-c3+1)…(dn-cn+1)+(j2-c2)(d3-c3+1)(d4-c4+1)…(dn-cn+1)+…+(j(n-1)-c(n-1))(dn-cn+1) + (dn-cn);(请参考上图);
如有错漏,敬请指正。