我一直相信在 C 中:
int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
指的是数组的数组,并且在内存中存储了 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]
then 这样的表达式通过从第一个指针向前计数来从该内存中检索一个值。如果您有一个数组数组,那么您在第一个数组(在您的a
数组中)中存储的所有内容都是指向其他数组存储位置的指针。(也就是说,我相信他们应该像你说的那样在一个连续的街区)
这对解释有帮助吗?
int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
这是一个真正的二维数组:int
已预留 15 个大小的位置,并使用传统的矩形下标来查找元素a[row][col]
int *b[5];
这是一个指针数组,它分配了 5 个指针并且没有被初始化,但是在语法a[3][2]
上b[3][2]
都是对单个 int 的合法引用。
假设 的每个元素b
确实指向一个三元素数组,那么就会有15 ints
预留,再加上五个单元格作为指针。
指针数组的重要优点是数组的行可以有不同的长度。也就是说, 的每个元素b
不必指向一个三元素向量,有的可能指向两个元素,有的指向 9,有的根本没有。