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

时间:2014-02-07 10:12:29

标签: c arrays multidimensional-array jagged-arrays ansi-c

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

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

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

困扰我的是我确信:

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

6 个答案:

答案 0 :(得分:13)

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

int m[4][5];

由4个int[5]组成,在记忆中彼此相邻。

指针数组:

int *m[4];

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

m[i][j]相当于*(*(m+i)+j)。请参阅C11 standard,第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 m子阵列的指针。
  • m[i]相当于*(m+i),取消引用指向i m子阵列的指针。由于这是数组类型的表达式,因此它会衰减为指向m[i][0]
  • 的指针
  • m[i][j]相当于*(*(m+i)+j),取消引用指向j i子阵列的m元素的指针。

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

答案 1 :(得分: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)),仅在第一种情况下。

答案 2 :(得分:2)

这取决于。

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

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

答案 3 :(得分:1)

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

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

这种差异是初学者C程序员非常困惑的原因。

答案 4 :(得分:0)

int matrix[A][B]之类的数组不是锯齿状的,因为matrix的每个元素都是array of B int

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

由于matrix的类型为array of A array of B int,因此表达式matrix+i是指向i array of B int matrix的指针},其类型为int (*)[B]。取消引用此表达式会生成array of B int。表达式*(matrix+i)+j)会生成指向该数组的j int的指针。取消引用该表达式会产生int。这相当于表达式matrix[i][j]的作用。

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

答案 5 :(得分:0)

您是对的,matrix[i][j]相当于*(*(matrix + i) + j),因为arr[i]相当于*(arr + i)。但是,请注意,如果arr被声明为

int arr[64];

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

int matrix[8][8];

此处matrix的类型为int[8][8],当您向其添加整数时会自动转换为int (*)[8],如matrix + i中所示。然后*(matrix + i)int[8]类型,当您添加int *时会再次转换为j,因此*(matrix + i) + j的类型为int *,因此{{} 1}}具有预期的类型*(*(matrix + i) + j)

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

因此,如果您分配上述数组(int),那么所有元素在内存中都是连续的。