19

关于 C 编程语言 (ANSI-C) 的一个简单问题:

C 中的多维数组是锯齿状的吗?

我的意思是-我们是在谈论“数组数组”(一个指向内存中其他地址的指针数组),还是只是“长一维数组”(按顺序存储在内存中)?

困扰我的是,我有点确定:

matrix[i][j]相当于* ( * (matrix + i) + j)

4

6 回答 6

13

C 中的多维数组是连续的。以下:

int m[4][5];

由 4 个int[5]s 组成,在内存中彼此相邻。

指针数组:

int *m[4];

是锯齿状的。每个指针都可以指向不同长度的单独数组(的第一个元素)。

m[i][j]相当于*(*(m+i)+j)。请参阅C11 标准,第 6.5.2.1 节:

下标运算符 [] 的定义是 E1[E2] 等同于 (*((E1)+(E2)))

因此,m[i][j]等价于(*(m+i))[j],即等价于*(*(m+i)+j)

存在这种等价性是因为在大多数情况下,数组类型的表达式会衰减为指向其第一个元素的指针(C11 标准,6.3.2.1)。m[i][j]解释如下:

  • m是一个数组数组,所以它衰减到指向m[0]第一个子数组的指针。
  • m+i是指向 的i第 th 个子数组的指针m
  • m[i]等价于*(m+i),取消引用指向 的i第 th 个子数组的指针m。由于这是一个数组类型的表达式,它衰减为指向 的指针m[i][0]
  • m[i][j]等价于*(*(m+i)+j),取消引用指向 的第th 子数组的第jth 元素的指针。im

请注意,指向数组的指针不同于指向其第一个元素的指针。m+i是指向数组的指针;它不是数组类型的表达式,并且无论是指向指针的指针还是指向任何其他类型的指针,它都不会衰减。

于 2014-02-07T10:33:24.467 回答
3

一个连续的内存区域:

int arr[N][M];

一个非连续的内存区域:

int** arr = malloc(N*sizeof(int*));
for (int i=0; i<N; i++)
    arr[i] = malloc(M*sizeof(int));

在这两种情况下,您都可以将arr其用作二维数组(例如arr[1][2] = 3)。但是您可以安全地应用更大的复制操作,例如memset(arr,0,N*M*sizeof(int)),仅在第一种情况下。

于 2014-02-07T10:21:55.440 回答
2

这将取决于。

C中的多维数组是按顺序排列的。

如果你想使用指针,你可以创建锯齿状数组。

于 2014-02-07T10:16:04.820 回答
1

如果你声明一个多维数组,你会得到“长一维数组”(它是按顺序存储在内存中的)。

如果你声明一个指向指针的指针(指向指针......),你会得到数组的数组。

这种差异对于初学者 C 程序员来说是一个很困惑的根源。

于 2014-02-07T10:15:18.573 回答
0

一个或多个数组,例如int matrix[A][B]不是锯齿状的,因为 的每个元素matrix都是一个array of B int.

您想知道*(*(matrix+i)+j)is 的结果并将其与 的结果进行比较matrix[i][j]

既然 的类型matrixarray of A array of B int,那么表达式matrix+i就是一个指向itharray of B int的指针,matrix它的类型是int (*)[B]。取消引用此表达式会导致array of B int. 该表达式*(matrix+i)+j)产生一个指向该数组的jth的指针。int取消引用该表达式会导致int. 这相当于表达式的matrix[i][j]作用。

一个指针数组,例如int *matrix[A],可能是锯齿状的,因为 的每个元素matrix可能指向不同大小的分配。

于 2014-02-07T10:19:03.707 回答
0

你是对的,那matrix[i][j]等价于*(*(matrix + i) + j),因为arr[i]等价于*(arr + i)。但是,请记住,如果arr声明为

int arr[64];

那么任何对的引用arr都可以隐式转换为&arr[0],即指向第一个元素的指针。数组数组也会发生同样的事情:

int matrix[8][8];

这里matrix有 type ,当你添加一个整数时int[8][8]会自动转换为,如. 然后有 type ,当您添加时再次转换为 type ,因此有type ,因此具有预期的 type 。int (*)[8]matrix + i*(matrix + i)int[8]int *j*(matrix + i) + jint **(*(matrix + i) + j)int

所以重点是,数组不是指针,只是它们可以隐式转换为指向其第一个元素的指针。

因此,如果您像上面 ( ) 那样分配数组的数组int matrix[8][8];,那么所有元素在内存中都是连续的。

于 2014-02-07T15:34:28.987 回答