我有一个接收变量int的方法。 该变量构成了数组的大小(请不要给我一个向量)。 因此,我需要初始化我的方法内的const int的初始化特定大小的阵列。 问:我该怎么做呢?
void foo(int variable_int){
int a[variable_int] = {0}; //error
}
我有一个接收变量int的方法。 该变量构成了数组的大小(请不要给我一个向量)。 因此,我需要初始化我的方法内的const int的初始化特定大小的阵列。 问:我该怎么做呢?
void foo(int variable_int){
int a[variable_int] = {0}; //error
}
int *a = new int[variable_int];
记得删除[]分配的空间,当你用它做!
C ++不支持可变长度的阵列。 相反,你需要动态分配数组:
std::vector<int> a(variable_int);
或者,因为你说你不希望使用矢量出于某种原因:
class not_a_vector
{
public:
explicit not_a_vector(size_t size) : a(new int[size]()) {}
~not_a_vector() {delete [] a;}
int & operator[](size_t i) {return a[i];}
int operator[](size_t i) const {return a[i];}
not_a_vector(not_a_vector const &) = delete;
void operator=(not_a_vector const &) = delete;
private:
int * a;
};
not_a_vector a(variable_int);
更新:这个问题刚刚用“C”标记更新以及“C ++”。 C(自1999年),不支持变长数组,所以你的代码应该是在语言精炼。
你问一个非向量解决方案,但我们去了,因为你可能已经拒绝了错误的原因。 你不应该因为任何有能力的编译器它是将具有几乎相同的开销,就像其他任何标准符合性解决方案的手担心性能。 在另一方面,也有一些可读性和安全问题,我会去到下面。 让我们来看看你能做到这一点从大多数建议最少的方式。
社区最喜爱的容器中,并有很好的理由。 它不仅可以与运行时的大小声明,但大小可随时更改。 这有利于使用时大小不能被预先确定,例如,当重复地轮询用户输入。 例子:
// 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
,即使在固定尺寸的情况下。 这不是大小感知,所以你必须明确地存储大小。 出于同样的原因,它不提供迭代器,并且不能在范围内使用for循环。 如果要牺牲这些功能来执行静态大小这是给你(和有问题的项目)。
最初,我曾建议boost::scoped_array
但经过进一步思考,我不认为它有很多提供了这种解决方案,所以我会坚持的标准库。
技术上的解决方案,但除非你是被迫使用旧的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
小,当性能对您非常重要的,你愿意依赖于特定的编译器行为得到它。 这是一届真正的无与伦比的案件。
你可以很容易地从一个非const变量一个const变量写const int bar = variable_int;
- 但这不会帮助你。 在C ++中具有自动存储阵列的尺寸必须是编译时间常数。 你不能把一个变量插入一个编译时间常数,所以你想要的东西是根本不可能的。
根据您的需求,你可以做a
指针,并使用分配内存new
(再后来delete
它),或者,如果参数foo
将始终在编译时是已知的,你可以把foo
变成一个像这样的模板函数:
template<int n> void foo() {
int a[n] = {0};
}
做你想做什么,你将需要使用动态分配。 在这种情况下,我会认真地建议使用矢量来代替 - 这是“正确”的东西在C ++做。
但是,如果你还是不希望使用矢量为什么你就不会超越我],正确的代码是:
void foo(int variable_int){
int *a = new int[variable_int](); // Parenthesis to initialize to zero.
... do stuff with a ...
delete [] a;
}
正如其他人建议,你也可以使用释放calloc,它具有初始化为零的效果相同,但没有真正的“C ++”的解决方案。
如果您使用数组这是一个好主意,把它们封装:
template<typename Type>
class Vector {
//...
};
标准库自带的实现: 性病::矢量