我刚开始学习C ++。我正在阅读互联网上的礼仪,现在我在功能上创建了一个动态分配的数组。
void array_() {
int size;
cin >> size;
int * Array = new int[size];
for (int i = 0; i < size; ++i)
cin >> Array[i];
}
如何将此函数返回到main()
答案 0 :(得分:7)
嗯,返回大小和指针是明智的,因为否则就无法安全地使用生成的数组。
所以我们正在寻找一种从函数中返回两个值的方法。这可以通过获取参考参数来完成,您可以通过参数指定其中一个值:
int *array_(int &size) {
std::cin >> size;
int *Array = new int[size];
for (int i = 0; i < size; ++i)
std::cin >> Array[i];
return Array;
}
int main() {
int size;
int *arr = array_(size);
// ...
delete[] arr; // Don't forget to delete[] what has been new[]'d!
}
或者,您可以返回包含两个值的std::pair
:
std::pair<int *, int> array_() {
int size;
std::cin >> size;
int * Array = new int[size];
for (int i = 0; i < size; ++i)
std::cin >> Array[i];
return {Array, size};
}
int main() {
auto arr = array_(size);
// ...
delete[] arr.second; // Don't forget still!
}
但这两个都是疯狂的坏主意,所以你现在可以开始编写实际的 C ++,这样它就不会像使用标准容器一样变形C:
std::vector<int> array_() {
int size = 0;
std::cin >> size;
std::vector<int> vec(size);
for(int &i : vec)
std::cin >> i;
return vec;
}
int main() {
auto arr = array_(size);
// ...
// Now you can forget delete: no raw owning pointer, no worries.
}
简单,防漏和异常安全(理想情况下,您也可以清理用户输入)。
答案 1 :(得分:4)
在大多数情况下,在C ++中,我们不需要使用operator new
手动分配资源。
我建议改用std::vector<int>
。与动态分配的普通数组相比,它具有以下优点:
delete
)。size()
方法,因此您始终可以知道向量中包含的元素数量。将其与动态普通数组进行比较,您必须将该大小存储在另一个变量中。resize()
方法)。std::vector<int> array_()
{
int size;
cin >> size;
// Create a dynamic "array" with the given size.
std::vector<int> result( size );
for (int i = 0; i < size; ++i)
cin >> result[i];
return result;
}
使用&#34;数组&#34;来自main()
:
int main()
{
// Call function array_() and store the result in variable v.
std::vector<int> v = array_();
// Print all elements of v using range-based loop.
for( int x : v )
{
std::cout << x << '\n';
}
// Alternatively print all elements using classic loop with index.
for( int i = 0; i < v.size(); ++i )
{
std::cout << v[i] << '\n';
}
}
答案 2 :(得分:3)
在C ++中,您不能从“按原样”的函数返回数组类型的变量(即int arr[]
),尽管您可以返回引用或指针一个数组。这是一些相当笨拙的语法。在显示的代码中,没有数组,而是指向一块动态分配的内存的指针。然而,主要的问题是,由于内存是动态分配的,当你返回一个指向该内存的指针时,你只给客户端一半的信息:数组的大小仍然未知。
因此,如果你真的想坚持动态分配的传统数组,你可以将数组的大小作为参考参数(“out-value”)传递给像这样的函数:
int* func(std::size_t& size_out) {
// int n = ...;
int* array = new int[n];
size_out = n;
return array;
}
int main() {
int size;
int* result = func(size);
delete[] result;
result = nullptr;
}
正如您所看到的,手动分配内存的副作用是客户端负责它,并且您必须在分配它的函数之外手动删除 。
但“超值”真的是一种糟糕的风格,特别是在API中。尽可能避免使用它们!
当然最好使用适当的动态数组工具,例如std::vector<T>
,但这似乎不是练习的重点。
答案 3 :(得分:0)
您可以返回动态分配的数组,返回其指针:
int* ProduceArray() {
...
int* arrayPtr = new int[size];
...
return arrayPtr;
}
但是,请注意,在他的方式中,您丢失了数组的 size 的重要信息(这对于使用该数组的代码非常重要,以避免缓冲区溢出)。
在现代C ++中,更好的方法是返回标准库容器,如std::vector
,而不是原始指针。
请注意,std::vector
个实例确实知道它们的大小,并自动释放它们的内存(相反,当你拥有原始拥有指针时,必须显式调用delete[]
。)