在c ++的二维数组中为什么我们总是要提到列数?

时间:2011-12-26 08:42:51

标签: c++ arrays

这是一个非常简单的问题,但无论我问谁,他们都无法回答。 在二维数组中,我们必须指定行和列,对吧? 例如:

void foo( int towers **[ ][ 3 ]** , int rings )
{
  for (int ring = 0; ring < rings; ring++)
  {
    ... towers[ ring ][ 0 ]...
  }
}
如果我们不在你那段代码中看到(提及)行,那么

编程就可以了,但我们ALWYAS无论如何都要编写列数。 那么为什么我们应该写出列数的逻辑原因是什么?如果我们不这样做会发生什么?

2 个答案:

答案 0 :(得分:3)

每当您尝试访问二维数组时,都要指定两个索引:array [a] [b]。 C ++确保array[n][...]中的所有元素在内存中对于任何n都是连续的,然后下一位内存用于array[n+1][...]等。例如:

               array[0][0]  ((T*)array)
               array[0][1]  ((T*)array) + 1
               array[0][2]  ((T*)array) + 2
               array[1][0]  ((T*)array) + 3
               array[1][1]  ((T*)array) + 4
               ...

因此,数组[a] [b]的绝对存储器地址,在数组T数组[A] [B]中是:

((T*)array) + a * B + b;

看看计算需要B而不是A?同样,编译器坚持要提供除最左边索引之外的所有索引。

在某些方面,如果编译器验证您没有尝试在A处或之后索引[a]的值,那将是很好的,但语言不会进行此类检查 - 这取决于程序员确保他们的代码安全地索引数组。如果你想要安全,可以使用std::vector<>at()进行运行时索引检查,甚至编写一个固定大小的数组机制,在编译时检查编译时常量索引(不是很有用,因为索引通常在运行时变化。)

答案 1 :(得分:1)

您知道二维数组是如何存储在内存中的。如果它的大小为[n] [m],那么它只需要在存储器中连续n×m个单元。当你被问到元素[a] [b]时,会有一些计算从这些连续的单元格中取出元素a * m + b。但是,如果不提供列数,则无法执行此计算(因为否则m将不知道)。

另一方面,列和行的数量不存储在阵列的存储器部分中,并且也不能从存储器导出列数。所有这些意味着计算机将不知道为您提供哪个内存地址。