二维数组是双指针吗? [复制]
Posted
技术标签:
【中文标题】二维数组是双指针吗? [复制]【英文标题】:Is 2d array a double pointer? [duplicate] 【发布时间】:2011-09-28 16:48:37 【问题描述】:int main()
matrix[2][4] = 11,22,33,99,44,55,66,110;
int **ptr = (int**)matrix;
printf("%d%d",**matrix,*ptr);
但是当二维数组作为参数传递时,它会被类型转换为 (*matrix)[2] .. 编译器将此数组存储为什么类型......它是存储为二维数组还是双指针或指向数组的指针..如果它存储为数组,它在上述不同情况下如何以不同方式解释.请帮我理解。
【问题讨论】:
指针不是数组,数组也不是指针。数组(无论它们有什么维度)在传递给函数时衰减为(单个)指针。(int) matrix
有点毫无意义。它强制matrix
两次衰减为指向整数的指针,但将指针转换为整数的结果是未定义的。
@David Schwartz:(int)matrix
会衰减一次(不是两次)matrix
,结果不是未定义,而是实现定义。
@jpalecek:实现定义意味着实现可以随意做任何事情。所以如果你不知道实现,你就没有定义。在实现未知的上下文中,它是未定义的。 (不是正式意义上的“未定义”,在正常意义上。)
在 C 语言中,不要将调用结果转换为 malloc()
、realloc()
或 calloc()
- 这是不必要的,并且可能掩盖了缺少原型的严重错误。
【参考方案1】:
二维数组是双指针吗?
没有。你程序的这一行不正确:
int **ptr = (int**)matrix;
This answer deals with the same topic
如果你想具体了解多维数组是如何实现的:
多维数组的规则与普通数组的规则没有区别,只是将“内部”数组类型替换为元素类型。数组项直接一个接一个地存储在内存中:
matrix: 11 22 33 99 44 55 66 110
----------- the first element of matrix
------------ the second element of matrix
因此,要寻址元素matrix[x][y]
,您需要使用the base address of matrix + x*4 + y
(4 是内部数组大小)。
当数组传递给函数时,它们会衰减为指向其第一个元素的指针。如您所见,这将是int (*)[4]
。然后类型中的4
会告诉编译器内部类型的大小,这就是它起作用的原因。在对类似指针进行指针运算时,编译器会添加元素大小的倍数,因此对于matrix_ptr[x][y]
,您会得到matrix_ptr + x*4 + y
,与上面完全相同。
因此,演员 ptr=(int**)matrix
是不正确的。这一次,*ptr
表示存储在矩阵地址处的指针值,但没有。其次,程序内存中的任何地方都没有指向matrix[1]
的指针。
注意:本文中的计算假设sizeof(int)==1
,以避免不必要的复杂性。
【讨论】:
【参考方案2】:没有。多维数组是单个内存块。块的大小是维度乘以元素类型大小的乘积,并且在每对括号中的索引偏移到数组中的是其余维度的维度乘积。所以..
int arr[5][3][2];
是一个包含 30 个int
s 的数组。 arr[0][0][0]
给出第一个,arr[1][0][0]
给出第七个(偏移 3 * 2)。 arr[0][1][0]
给出第三个(偏移量 2)。
数组衰减到的指针将取决于级别; arr
衰减为指向 3x2 int 数组的指针,arr[0]
衰减为指向 2 元素 int 数组的指针,而 arr[0][0] 衰减为指向 int 的指针。
但是,您也可以拥有一个指针数组,并将其视为多维数组——但它需要一些额外的设置,因为您必须将每个指针设置为它的数组。此外,您会丢失有关数组中数组大小的信息(sizeof
会给出指针的大小)。另一方面,您可以拥有不同大小的子数组并更改指针指向的位置,这在需要调整大小或重新排列时很有用。像这样的指针数组可以像多维数组一样被索引,即使它的分配和排列方式不同并且sizeof
的行为方式并不总是相同。此设置的静态分配示例如下:
int *arr[3];
int aa[2] = 10, 11 ,
ab[2] = 12, 13 ,
ac[2] = 14, 15 ;
arr[0] = aa;
arr[1] = ab;
arr[2] = ac;
在上面之后,arr[1][0]
是12
。但是,它没有给出在数组arr
的起始地址之后的1 * 2 * sizeof(int)
字节处找到的int
,而是给出在0 * sizeof(int)
处找到的int
字节之后的arr[1]
指向的地址。此外,sizeof(arr[0])
等效于 sizeof(int *)
而不是 sizeof(int) * 2
。
【讨论】:
【参考方案3】:在 C 语言中,您无需了解任何特殊知识即可理解多维数组。它们的工作方式与从未被特别提及的方式完全相同。您需要知道的是,您可以创建任何类型的数组,包括数组。
所以当你看到:
整数矩阵[2][4];
试想一下,“matrix
是一个包含 2 个东西的数组——这些东西是 4 个整数的数组”。数组的所有常规规则都适用。例如,matrix
可以很容易地衰减为指向其第一个成员的指针,就像任何其他数组一样,在本例中是一个由四个整数组成的数组。 (当然,它本身会腐烂。)
【讨论】:
【参考方案4】:如果您可以将堆栈用于该数据(小容量),那么您通常定义矩阵:
int matrix[X][Y]
当你想在堆中分配(大容量)时,你通常定义一个:
int** matrix = NULL;
然后用malloc/calloc分配两个维度。 您可以将 2d 数组视为 int** 但这不是一个好习惯,因为它会使代码的可读性降低。除此之外
**matrix == matrix[0][0] is true
【讨论】:
int matrix[X][Y]
是静态 分配,所以你还需要在编译时知道X, Y
的维度。以上是关于二维数组是双指针吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章