(5)c数组本质
c中的数组是一种聚合类型,把同种类型的元素按顺序存储,即是数组。c中数组类型的特点在于:它是嵌套定义的。
看下一个二维数组int array[2][3]={{1,2,3},{4,5,6}};的内存存储形式:
c中的数组是嵌套定义的:二维数组的元素是一维数组,三维数组的元素是二维数组……
像array[2][3]这样的二维数组,是由两个一维数组组成的:array[0]、array[1],这两个一维数组的规模都是array的第二个下标3。同时,array[0]、array[1]就是两个一维数组名。由于元素都是顺序存储的,故可以通过以下的方式挨个访问array中元素:
int main(void) { int array[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; //让p指向数组首元素 int *p = &array[0][0]; while (p < &array[1][3]) { printf("%4d", *p); p++; } printf("\n\n"); return 0; }运行
这种访问方式能够成功,关键就在于c中的多维数组本质是数组的数组,并且元素顺序存储。
在代码中出现了&array[1][3],是不是越界了呢?理论上array[1][2]是array的最后一个元素,array[1][3]正好是其下一个,这里我们取其地址,而不是访问元素,这是可以的。
下面来探讨一下这三个数组名:array、array[0]和array[1]是何种类型的指针。
首先,在(3)数组和指针中,我们提到过,对于数组int array[N];(N是一常量)。数组名array是一指向数组首元素的常量指针(也就是说,不可再指向别的存储单元),而&array是一指向整个数组的指针。这里以此类推:
int main(void) { int array[2][3] = { {1, 2, 3}, {4, 5, 6} }; int *pa = array[0]; int (*pb)[3] = &array[0]; int (*pc)[3] = array; int (*pd)[2][3] = &array; return 0; }
int main(void) { int array[2][3] = { {1, 2, 3}, {4, 5, 6} }; int *pa = array[0]; int (*pb)[3] = &array[0]; int (*pc)[3] = array; int (*pd)[2][3] = &array; printf("array...%p\n", array); printf(" pa+1...%p\n", pa + 1); printf(" pb+1...%p\n", pb + 1); printf(" pc+1...%p\n", pc + 1); printf(" pd+1...%p\n", pd + 1); return 0; }运行
娓娓道来c指针 (5)c数组本质,布布扣,bubuko.com
原文地址:http://blog.csdn.net/zhangxiangdavaid/article/details/38111983