为什么我们不能使用双指针来表示二维数组?

Tha*_*raj 20 c

为什么我们不能使用双指针来表示二维数组?

arr[2][5] = {"hello","hai"};
**ptr = arr;
Run Code Online (Sandbox Code Playgroud)

这里为什么双指针(**ptr)在这个示例中不起作用?

Sha*_*baz 53

我打算画一下

int array[10][6];
Run Code Online (Sandbox Code Playgroud)

int **array2 = malloc(10 * sizeof *array2);
for (int i = 0; i < 10; ++i)
    array2[i] = malloc(6 * sizeof **array2);
Run Code Online (Sandbox Code Playgroud)

看起来像在记忆中以及它们是如何不同的(并且它们不能相互铸造)

array 好像:

 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| | | | | | | | | | | | | ..............| | | (10*6 elements of type int)
 - - - - - - - - - - - - - - - - - - - - - -
< first row >< second row> ...
Run Code Online (Sandbox Code Playgroud)

array2 好像:

 _ _ _ _ _ _ _ _ _ _ 
| | | | | | | | | | | (10 elements of type int *)
 - - - - - - - - - - 
 | |     ....      |     _ _ _ _ _ _
 | |                \-->| | | | | | | (6 elements of type int)
 | |                     - - - - - -
 | |
 | |      _ _ _ _ _ _
 |  \ -->| | | | | | | (6 elements of type int)
 |        - - - - - -
 |
 |
 |      _ _ _ _ _ _
  \ -->| | | | | | | (6 elements of type int)
        - - - - - -
Run Code Online (Sandbox Code Playgroud)

当你说array[x][y],它转化为*((int *)array+x*6+y)

虽然,当你说array2[x][y],它转化为*(*(array2+x)+y)(注意,因为array,这个公式也有效(读到帖子的结尾,然后是评论)).

也就是说,静态2d数组实际上是1d数组,其中行放在一行中.指数由公式计算row * number_of_columns_in_one_row + column.

然而,动态2d数组只是一个指针数组.然后,每个指针被动态分配以指向另一个1d数组.事实上,指针可以是任何东西.可能是NULL,或指向单个变量,或指向另一个数组.并且每个指针都是单独设置的,因此它们可以具有不同的性质.

如果你需要传递array某个地方的指针,你就不能把它投射到int **(想象会发生什么.int单元格的值array被解释为指针和解引用 - > Bam!Segmentation fault!).然而,您可以将其array视为int [6]s 的1d数组; 这是一个带有类型的1d元素数组int [6].要写下来,你说

int (*p)[6] = array;
Run Code Online (Sandbox Code Playgroud)

  • @KohányiRóbert,这是一个很好的观点。实际上,对于一个(非动态)多维数组(在这种情况下为“ array”),两者是等效的。您需要注意表达式中“ array”的类型才能理解它。首先,请注意,在`*((((int *)array)+ x * 6 + y)`中,我首先将`array`转换为`int *`。从本质上讲,这意味着“ x * 6 + y”是对“ int”数组的索引。 (2认同)
  • 现在,当您执行`*(*(array + i)+ j))`时,您无需更改`array`的类型。数组的类型是什么?是`int(*)[6]`。那的“ sizeof”是多少?是`sizeof(int)* 6`。现在`*(array + i)`与`(int [6])((int *)array + i * 6)`一样(有意义吗?)。用j进行索引成为`*((int *)array + i * 6 + j)`。 (2认同)
  • @Rohan,括号很重要。`int *p[6]` 是一个包含 6 个指针的数组。`int (*p)[6]` 是一个指向 6 个整数数组的指针。这与函数指针非常相似。`int *f()` 和 `int (*f)()` 是不同的东西。 (2认同)

Ste*_*sop 9

在C中,二维数组是一个数组数组.

你需要一个指向数组的指针来引用它,而不是一个双指针:

char array[2][6] = {"hello", "hai"};
char (*p)[6] = array;
//char **x = array;  // doesn't compile.
Run Code Online (Sandbox Code Playgroud)

对于引用"二维数据"的双指针,它必须引用指针数组的第一个元素.但是C(数组数组)中的二维数组与指针数组不同,如果只定义一个二维数组,则不存在相应的指针数组.

两者之间唯一的相似之处是[][]用于访问数据的语法:数据本身的结构完全不同.


unw*_*ind 8

具有指向指针的指示意味着每行(或列,如果您愿意以这种方式考虑它)可以具有与其他行/列不同的长度.

您还可以通过指向start元素的指针来表示2D数组,并使用一个整数来指定每行/每列的元素数:

void matrix_set(double *first, size_t row_size, size_t x, size_t y, double value)
{
  first[y * row_size + x] = value;
}
Run Code Online (Sandbox Code Playgroud)

  • 我的问题是为什么以及如何运作。 (2认同)