这是一个非常简单的问题,但无论我问谁,他们都无法回答。 在二维数组中,我们必须指定行和列,对吧? 例如:
void foo( int towers **[ ][ 3 ]** , int rings )
{
for (int ring = 0; ring < rings; ring++)
{
... towers[ ring ][ 0 ]...
}
}
如果我们不在你那段代码中看到(提及)行,那么编程就可以了,但我们ALWYAS无论如何都要编写列数。 那么为什么我们应该写出列数的逻辑原因是什么?如果我们不这样做会发生什么?
答案 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将不知道)。
另一方面,列和行的数量不存储在阵列的存储器部分中,并且也不能从存储器导出列数。所有这些意味着计算机将不知道为您提供哪个内存地址。