如何从 c++ 中的函数返回数组

How to return an array from a function in c++

本文关键字:函数 返回 数组 c++      更新时间:2023-10-16

您好,我正在尝试从输入文件中获取数据并将其放置在数组中。我能够完成我的一个函数并让数组返回,如下所示:

string * animal_name_grab() 
{
static string animal_name[SIZE];
int cntr = 0;
static string line_skip[SIZE];
while (!input_animals.eof())
{
getline(input_animals, animal_name[cntr]);
getline(input_animals, line_skip[cntr]);
cntr++;
}
return (animal_name);
}

现在我正在尝试做同样的事情,但将数字的总和相加。我看不出它到底有什么问题。我以与前一个完全相同的方式调用函数,但为了以防万一,我也插入了它。 声明双 *array_animal_total; 函数调用 - array_animal_total = animal_total_grab((;

double * animal_total_grab()
{
static double animal_total[SIZE];
static string line_skip[SIZE];
int cntr = 0;
double sum = 0;
double total_count;
while (!input_animals.eof())
{
getline(input_animals, line_skip[cntr]);
for ( int i ; i < 10 ; i++)
{
input_animals >> total_count;
sum = sum + total_count;    
}
animal_total[cntr] = sum;
cntr++;
}
return (animal_total);
}

请告诉我,如果这是太多的代码,无法在此处输入,以便我可以对其进行编辑。我只是想证明我理解材料,我只是遇到了一点麻烦。我是初学者,所以请友善。

我能够完成我的一个函数并让数组返回,如下所示:

string * animal_name_grab() 

您不会返回数组。您正在返回一个指针。指针指向数组的元素。

如何在 c++ 中从函数返回数组

事实上,从 C++ 中的函数直接返回数组是不可能的。但是,可以返回类的实例,并且类可以具有数组成员,因此如果将数组包装在类中,则可以返回该包装器对象。这样的数组包装器类有一个标准模板。它的名字是std::array.例:

std::array<std::string, SIZE> animal_name_grab()
{
std::array<std::string, SIZE> animal_name;
...
return animal_name;
}

请注意,复制大型数组可能会很慢,您将依靠编译器优化来避免复制返回值。有时使用输出迭代器而不是返回数组更有效,并且通常更灵活。

您征求了建议,所以您就是这样:如果您想使代码更C++和现代,请考虑使用std::arraystd::vector而不是原始数组。 这允许您使用如下STL_functions:

std::for_each(vector.begin(), vector.end(), [&] (int n) {
sum_of_elems += n;
});

获取元素的总和。 您可以返回向量,但我建议您先创建向量,然后通过引用传递它。

std::vector<std::string> input;
input.reserve(approxSpace); // Not necessary
getInput(&input); // Fill vector in external function

还要避免使用"幻数",例如10。如果你的项目变得更大,那么在不破坏代码的情况下改变事情就会变得更加困难。

您可以分解它并为animalanimal_collection定义自己的类型,并添加一些函数以根据需要使用它们。您显然想从流中读取animal,因此让我们为此创建一个函数。您还想阅读整个animal集合,因此让我们为此添加一个函数。

演练:

#include <iostream>
#include <vector>  // std::vector - a dynamically growing container
//               that you can store objects in
#include <sstream> // std::istringstream for demo purposes
// A type to store the characteristics of an animal in. Let's start with a name.
struct animal {
std::string name;
};
// A function to read one "animal" from std::cin or some other istream.
//
// It's functions like these that makes "cin >> variable;" work in your everyday program.
std::istream& operator>>(std::istream& is, animal& a) {
std::getline(is, a.name);
return is;
}
// A function to write one "animal" to std::cout or some other ostream.
std::ostream& operator<<(std::ostream& os, const animal& a) {
return os << a.name;
}
// A collection of animals.
struct animal_collection {
// std::vector - This std::vector stores objects of the type "animal".
//               It has a lot of good features and is often prefered as a container
//               when the exact number of elements to store is unknown.
std::vector<animal> creatures;
// return the number of "animal" objects there are in this "animal_collection"
size_t size() const { return creatures.size(); }
// iterator support functions so that you can loop over an animal_collection.
// In this case, they are mearly proxy functions for the functions in std::vector
// that we need exposed.
// const iterators
auto cbegin() const { return creatures.cbegin(); }
auto cend() const { return creatures.cend(); }
auto begin() const { return cbegin(); }
auto end() const { return cend(); }
// non-const iterators
auto begin() { return creatures.begin(); }
auto end() { return creatures.end(); }
};
// A function to read one "animal_collection" from std::cin or some other istream,
// like a file / ifstream.
std::istream& operator>>(std::istream& is, animal_collection& ac) {
animal tmp;
while(is >> tmp) { // use operator>> for "animal"
// push_back() is a function in std::vector. Since this vector stores "animal"
// objects and "tmp" is an "animal" object, this works:
ac.creatures.push_back(tmp);
}
return is;
}
// A function to write one "animal_collection" to std::cout or some other ostream,
// like a file / ifstream.
std::ostream& operator<<(std::ostream& os, const animal_collection& ac) {
// use the iterator support functions added to the "animal_collection" type
// and loop over all the animal objects inside
for(const animal& a : ac) {
os << a << 'n'; // use operator<< that was added for "animal"
}
return os;
}
// using the two types created above
int main() {
std::istringstream cin(
"Tigern"
"Lionn"
"Zebran"
"Dalekn");
animal_collection ac;
// read all "animal" objects into the "animal_collection"
//
// emulating reading animals from cin - replace with any istream,
// like an open file
cin >> ac; // use operator>> defined for "animal_collection"
// use the size() function in the "animal_collection":
std::cout << "there are " << ac.size() << " animal(s):n";
// output the whole "animal_collection"
std::cout << ac;
}

当您需要向animal添加特征时,只需更改与该类型相关的内容。animal_collection不需要更改。animal_collection内部的std::vector<animal>还有很多其他不错的函数,你也可以通过代理函数公开,就像size()begin() / end()系列函数一样。

如果您不想使用 std 库中的任何内容,您可以随时在堆上声明数组,这样当您返回时它就不会被破坏。

例如:

double * func(){
double * someArray = new double[3]; //declaring 'someArray' on the heap
for(int i = 0; i < 3; i++)   //Filling the array with data
someArray[i] = i;         //filling the array with data
return someArray;            //since 'someArray' is on the heap it wont be destructed when you return
}

尽管不要忘记在完成数组后删除数组。

希望这有帮助。