Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在c++;为什么我们总是要提到列数?_C++_Arrays - Fatal编程技术网

C++ 在c++;为什么我们总是要提到列数?

C++ 在c++;为什么我们总是要提到列数?,c++,arrays,C++,Arrays,这是一个非常简单的问题,但无论我问谁,他们都无法回答。 在二维数组中,我们必须指定行和列,对吗? 例如: void foo( int towers **[ ][ 3 ]** , int rings ) { for (int ring = 0; ring < rings; ring++) { ... towers[ ring ][ 0 ]... } } array[0][0] ((T*)array) arra

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

void foo( int towers **[ ][ 3 ]** , int rings )
{
  for (int ring = 0; ring < rings; ring++)
  {
    ... towers[ ring ][ 0 ]...
  }
}
               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
               ...
void foo(内塔**[][3]**,内环)
{
for(int-ring=0;ring
在编程中,如果我们不写(提到)你在那段代码中看到的行是可以的,但是不管怎样,我们总是要写很多列。
那么,我们应该写多少列的逻辑原因是什么呢?如果我们不这样做会发生什么

无论何时尝试访问二维数组,都需要指定两个索引:array[a][b]。C++确保<代码>数组[n]……/代码>中的所有元素在内存中都是连续的,对于< <代码> n>代码>,然后使用下一个内存位用于<代码>数组[n+1]……/代码>等。例如:

void foo( int towers **[ ][ 3 ]** , int rings )
{
  for (int ring = 0; ring < rings; ring++)
  {
    ... towers[ ring ][ 0 ]...
  }
}
               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()
进行运行时索引检查,甚至可以编写一个固定大小的数组机制,在编译时检查编译时常量索引(这不是很有用,因为索引通常在运行时会发生变化)。

每当您尝试访问二维数组时,您可以指定两个索引:数组[a][b]。C++确保<代码>数组[n]……/代码>中的所有元素在内存中都是连续的,对于< <代码> n>代码>,然后使用下一个内存位用于<代码>数组[n+1]……/代码>等。例如:

void foo( int towers **[ ][ 3 ]** , int rings )
{
  for (int ring = 0; ring < rings; ring++)
  {
    ... towers[ ring ][ 0 ]...
  }
}
               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()
进行运行时索引检查,甚至可以编写一个固定大小的数组机制,在编译时检查编译时常量索引(不是很有用,因为索引通常在运行时会发生变化)。

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


另一方面,列数和行数不存储在数组的内存部分,列数也不能从内存中导出。所有这些都意味着计算机将不知道为您服务的内存地址。

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


另一方面,列数和行数不存储在数组的内存部分,列数也不能从内存中导出。所有这些都意味着计算机将不知道为您服务的内存地址。

您可以认为,您正在传递一个指针数组,其中每个指针指向一行。因此,您也可以将2D数组作为“Func(int(*towers)[3])传递。我的意思是,一般来说,这段代码只是一个示例。上述原因在一般情况下也是正确的。如果列数为“Y”,则仍然可以接受二维数组为“Func(int(*arr2)[Y]){}”。这只是另一种方式。您可以认为,您正在传递一个指针数组,其中每个指针都指向一行。因此,您也可以将2D数组作为“Func(int(*towers)[3])传递。我的意思是,一般来说,这段代码只是一个示例。上述原因在一般情况下也是正确的。如果列数为“Y”,则仍然可以接受二维数组为“Func(int(*arr2)[Y]){}”。这只是另一种方式。谢谢,但我的一位朋友在编译[]时提到了这一原因(抱歉,我不知道如何更好地解释它),因此它会造成混乱,因为在删除[]后可能会有两个大小相同的数组,那么它就不知道给哪个数组赋值了。@sam:我不太明白你对你朋友的观点的解释,所以不能正确地对它进行评论。外围地,当调用代码调用时,说
foo(my_towers,4)
这是“有希望的”
foo
使用
0的数据是安全和有意义的谢谢,但我的一个朋友在编译[]时提到了这一原因被删除(对不起,我不知道如何更好地解释)因此它会造成混乱,因为在消除[]之后可能会有两个大小相同的数组,所以它不知道给哪个数组赋值。@sam:我不太理解你朋友的观点,无法正确地对其进行评论。外围设备,当调用代码调用时,说
foo(my_towers,4)
它“承诺”
foo
使用
0的数据是安全和有意义的