【发布时间】:2017-03-07 21:53:20
【问题描述】:
我一直相信在 C 中:
int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
指的是一个数组数组,在内存中存储了十五个连续的块,但a[0]是指向a[0][0]的指针,a[1]是指向a[1][0]的指针,依此类推。所以我认为它类似于一个指针数组。它们有什么区别?
【问题讨论】:
我一直相信在 C 中:
int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
指的是一个数组数组,在内存中存储了十五个连续的块,但a[0]是指向a[0][0]的指针,a[1]是指向a[1][0]的指针,依此类推。所以我认为它类似于一个指针数组。它们有什么区别?
【问题讨论】:
数组和指针在 C(和 C++)中有着非常奇妙而亲密的关系。在大多数情况下,如果您有一个“X 数组”,那么它将被静默转换为指向该数组第一个元素的“指向 X 的指针”。
你的信念
int a[5][3];
创建一个数组数组是完全正确的。根据声明,它是一个array of 5 arrays of 3 ints,它在内存中占用了15个连续整数。
你出错的地方在于相信a[0] 是一个指针。事实上,a[0] 是a 的第一个子数组,它本身就是一个array of 3 ints。但是,由于指针和数组之间奇怪的关系,表达式a[0] 几乎总是被转换为指针。
数组数组和指针数组之间的主要区别之一在于数组元素所在的位置。数组数组将始终占用一个连续的内存块,但指针数组中的指针将各自引用它们自己的(通常是不相交的)内存块。
【讨论】:
数组和指针大致等同于同一事物。当您声明一个数组 N long 时,您正在分配一块内存 N long(乘以值类型的大小)并返回指向第一个元素的指针。然后像arr[2] 这样的表达式通过从第一个指针向前计数来从该内存中检索一个值。如果您有一个数组数组,那么您在第一个数组(在您的a 数组中)中存储的所有内容都是指向其他数组存储位置的指针。 (也就是说,我相信它们应该像你说的那样在一个连续的块中)
这对解释有帮助吗?
【讨论】:
sizeof 暴露出来
int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
这是一个真正的二维数组:已预留 15 个int 大小的位置,并使用常规矩形下标来查找元素a[row][col]
int *b[5];
这是一个指针数组,它分配了 5 个指针并且未初始化,但 a[3][2] 和 b[3][2] 在语法上都是对单个 int 的合法引用。
假设b 的每个元素都
指向一个三元素数组,那么会有15 ints留出,再加上五个单元格
指针。
指针数组的重要优点是数组的行可以是
不同的长度。即b的每个元素不需要指向一个三元素向量,有些
可能指向两个元素,有的指向 9,有的根本没有。
【讨论】: