我尝试使用这个版本:
int n;
cin >> n;
int a[n]; // compiler error
但它不起作用。我做错了什么?
答案 0 :(得分:9)
在编译时声明一个大小未知的数组有三种标准的符合方法。从大多数推荐到最少。
社区最喜欢的容器,有充分理由。它不仅可以使用运行时大小声明,而且可以随时更改大小。当不能预先确定大小时,例如当重复轮询用户输入时,这便于使用。例子:
// Known size
size_t n;
std::cin >> n;
std::vector<int> vec(n);
// Unknown size
std::vector<int> vec;
int input;
while (std::cin >> input) { // Note: not always the best way to read input
vec.push_back(in);
}
使用std::vector
并没有太大的缺点。已知大小的情况只需要一个动态分配。在一般情况下,未知大小需要更多,但无论如何你都无法做得更好。因此,性能或多或少是最佳的。
从语义上讲,对于在整个执行过程中保持不变的大小,它可能并不理想。读者可能不明白这个容器不是要改变的。编译器不知道它是否允许你在push_back
中做一些错误的事情,而vector
逻辑上是恒定大小。
如果强制执行静态大小对您来说最安全的解决方案。
size_t n;
std::cin >> n;
auto arr = std::make_unique<int[]>(n);
arr
的大小无法更改,但可以释放当前数组并指向另一个不同大小的数组。因此,如果逻辑上容器的大小是恒定的,这将以更清晰的方式传达意图。不幸的是,即使在恒定大小的情况下,它也比std::vector
弱得多。它不是可识别大小的,因此您必须明确存储大小。出于同样的原因,它不提供迭代器,也不能用于循环范围。如果您想牺牲这些功能来强制执行静态大小,则由您(以及相关项目)决定。
从技术上讲,这是一个解决方案,但除非您被迫使用旧的C ++标准,或者您正在编写一个内部管理内存的低级库,否则它们严格地比std::unique_ptr
或std::shared_ptr
解决方案更糟糕。它们没有提供更多功能,但安全性显着降低,因为您必须在完成内存后明确释放内存。否则,您将泄漏它,这可能会导致严重的问题。更糟糕的是,正确使用delete[]
对于具有复杂的执行流程和异常处理的程序来说可能是非常重要的。当您可以使用上述解决方案时,请不要使用此功能!
size_t n;
std::cin >> n;
int* arr = new int[n];
...
// Control flow must reach exactly one corresponding delete[] !!!
delete[] arr;
有些编译器实际上可以使用以下代码
size_t n;
std::cin >> n;
int arr[n];
依靠这有严重的缺点。您的代码无法在所有符合C ++标准的编译器上编译。它可能甚至不能在给定编译器的所有版本上编译。此外,我怀疑生成的可执行文件检查n
的值并在需要时在堆上分配意味着您可以炸毁堆栈。只有当您知道n
的上限很小且性能对您如此重要以至于您愿意依赖编译器特定的行为才能获得它时,此解决方案才有意义。这些都是非常特殊的情况。
答案 1 :(得分:4)
您可以在堆上分配一个数组:
EventHandler
您还可以使用int n;
cin >> n;
int *a = new int[n];
// use 'a'
delete[] a;
:
std::vector
您可以使用数组数组(“矩阵”):
int n;
cin >> n;
vector<int> a(n);
您还可以拥有vector of vectors。
答案 2 :(得分:2)
Google:C++ dynamic arrays
int n;
cin >> n;
int *a = new int[n];
// use 'a'
delete[] a;
答案 3 :(得分:2)
C ++没有可变长度数组。 另一种方法是使用@ user70960提到的动态数组:
int n(0);
cin >> n;
int *a(new int[n]);
// use 'a'
delete[] a;
或者您可以使用以下向量执行相同的操作:
int n(0);
cin >> n;
vector<int> a(n);