二维数组是双指针吗? [复制]

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 个ints 的数组。 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 的维度。

以上是关于二维数组是双指针吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何将二维数组分配给**指针? [复制]

C中结构体内有一个成员是二维数组,可以直接赋值另一个一维数组吗?

如何利用memcpy将二维指针复制给一维指针?

C语言中的二维数组名是一个二重指针吗?

我可以使用 C++ 中的指针访问二维数组的元素吗?

数组指针是二级指针吗?请解释一下!谢谢!