Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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++_Arrays_Initialization - Fatal编程技术网

C++ 为什么我们要将单个或多维数组的大小声明为常量值?

C++ 为什么我们要将单个或多维数组的大小声明为常量值?,c++,arrays,initialization,C++,Arrays,Initialization,自从我开始竞争性编程以来,我总是发现人们总是基于输入规范的最大值的一个常量最大值来初始化单个或二维数组 但我一直想知道,当您可以基于输入初始化数组时,为什么人们会这样做 例如,假设一个问题在接收数组(或向量)大小的输入时,输入规格为0到10到5的幂 为什么人们会这样做: 表示法:整数n表示输入,a表示数组: #include<bits/stdc++.h> using namespace std; const int MXN = 1e5; int a[MXN], n; int m

自从我开始竞争性编程以来,我总是发现人们总是基于输入规范的最大值的一个常量最大值来初始化单个或二维数组

但我一直想知道,当您可以基于输入初始化数组时,为什么人们会这样做

例如,假设一个问题在接收数组(或向量)大小的输入时,输入规格为0到10到5的幂

为什么人们会这样做:

表示法:整数
n
表示输入,
a
表示数组:

#include<bits/stdc++.h>

using namespace std;

const int MXN = 1e5;
int a[MXN], n;

int main() {
    cin >> n;

    for(int i = 0; i<n; i++)
        cin >> a[i];
}
#包括
使用名称空间std;
常数int MXN=1e5;
int a[MXN],n;
int main(){
cin>>n;
对于(int i=0;i>a[i];
}
与此相反:

#include<bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    int a[n];

    for(int i = 0; i<n; i++)
        cin >> a[i];
}
#包括
使用名称空间std;
int main(){
int n;
cin>>n;
int a[n];
对于(int i=0;i>a[i];
}
或者这是最好的方法(我通常会这么做):

#包括
使用名称空间std;
int main(){
int n;
cin>>n;
向量(n);
对于(int i=0;i>a[i];
//对于(自动&i:a)cin>>i;
}

这样做有什么好处吗?谢谢。

标准要求数组长度是一个在编译时可以计算的值,以便编译器能够在堆栈上分配足够的空间

在本例中,您试图将数组长度设置为编译时未知的值。是的,编译器显然应该知道它,但这里不是这样。编译器无法对非常量变量的内容做出任何假设

这就是为什么我们应该使用常量来声明数组大小的一个突出原因,这样编译器就可以知道在创建数组的过程中应该在堆栈上分配多少内存

对于动态分配,我们可以使用
data\u type variable=new data\u type[len]
format或
vector
。请注意,C99中支持VLA(与您试图声明数组的方式类似
arr[n]

例如,假设您告诉编译器

int vla = 100;
int a[vla];

如果不做大量非常复杂的分析来追踪
vla
值发生变化的每一个地方,编译器将无法考虑您在运行时实际需要多少内存。

这三种方法各有优缺点。选择取决于目标

第一种方法:静态存储持续时间数组

  • 该数组在程序执行期间保持不变
  • 内存分配在程序启动时执行(可能由操作系统执行),而且非常便宜
  • 它不提供值语义。(它不容易复制、移动或分配)
在小型项目中,这种方法可能有助于提高执行速度,但不具有可扩展性

第二种方法:在堆栈上分配数组

  • 阵列生存时间从其定义开始,到块作用域出口结束
  • 内存分配是在程序执行期间执行的,它只包含一条非常便宜的汇编指令
  • 它不提供值语义。(它不容易复制、移动或分配)
  • 它是标准语言的编译器扩展
对于临时缓冲区,此方法是一个很好的选择,但它又是不可伸缩的,这是导致堆栈溢出的原因之一

第三种方法:动态分配数组,std::vector

  • 阵列使用寿命在需要时开始和结束
  • 内存分配是在程序执行期间执行的,而且相对昂贵
  • 它确实提供了语义值(可以轻松复制、移动或分配)

这是默认的选择。

第一个片段是内存的浪费或越界访问,第二个片段不是标准的C++。它们都不应该使用,使用<代码> STD::vector < /COD>(技术上没有一个是标准C++)。首先,因为你在看“竞争”代码。网站,人们不知道好的编程实践,使用许多坏习惯(包括你提出的)。也不是标准C++的一部分。在非常相关的注释中,请阅读,最后请不要使用竞争网站作为学习或教学资源,或者作为好代码的知识库来学习,因为它们不是。(我认为恰恰相反)。在使用此类网站之前,先上课、阅读、正确学习。唯一的“优势”(我使用的术语比较松散)这些技术中有一种是在竞争性编程网站上被接受的。如果你想学习在现实世界中不好的编程技术,那么继续使用这些方法。如果你希望得到一份体面的工作,作为一名程序员做一些你可以引以为傲的工作,那么就必须放弃学习这些技术。
int vla = 100;
int a[vla];