如何从函数返回数组?

我怎样才能从一个方法返回一个数组,我怎样才能声明它呢?

int[] test(void); // ?? 

int* test();

但是使用向量会是“更多的C ++”:

std::vector< int > test();

编辑
我会澄清一点。 既然你提到了C ++,我将使用new[]delete[]运算符,但是和malloc / free一样。

在第一种情况下,你会写如下的东西:

 int* test() { return new int[size_needed]; } 

但是这不是一个好主意,因为你的函数的客户端并不知道你正在返回的数组的大小,尽pipe客户端可以通过调用delete[]来安全地释放它。

 int* theArray = test(); for (size_t i; i < ???; ++i) { // I don't know what is the array size! // ... } delete[] theArray; // ok. 

更好的签名将是这一个:

 int* test(size_t& arraySize) { array_size = 10; return new int[array_size]; } 

而你的客户端代码现在是:

 size_t theSize = 0; int* theArray = test(theSize); for (size_t i; i < theSize; ++i) { // now I can safely iterate the array // ... } delete[] theArray; // still ok. 

既然这是C ++,`std :: vector <T>是一个广泛使用的解决scheme:

 std::vector<int> test() { std::vector<int> vector(10); return vector; } 

现在你不必调用delete[] ,因为它将被对象处理,你可以安全地迭代它:

 std::vector<int> v = test(); std::vector<int>::iterator it = v.begin(); for (; it != v.end(); ++it) { // do your things } 

这更简单,更安全。

我怎样才能返回一个数组在c + +方法,我该如何申报呢? int [] test(void); ??

这听起来像一个简单的问题,但在C ++中,你有很多select。 首先,你应该更喜欢…

  • std::vector<> ,它dynamic地增长到在运行时遇到的许多元素,或者

  • std::array<> (在C ++ 11中引入),它总是存储编译时指定的许多元素,

…为他们pipe理记忆,确保正确的行为和相当简化的事情:

 std::vector<int> fn() { std::vector<int> x; x.push_back(10); return x; } std::array<int, 2> fn2() // C++11 { return {3, 4}; } void caller() { std::vector<int> a = fn(); const std::vector<int>& b = fn(); // extend lifetime but read-only // b valid until scope exit/return std::array<int, 2> c = fn2(); const std::array<int, 2>& d = fn2(); } 

创build一个返回数据的const引用的做法有时可以避免一个副本,但通常你可以只依靠返回值优化,或者 – 对于vector而不是array – 移动语义(用C ++ 11引入)。

如果你真的想要使用一个内置的数组(与上面提到的标准库类叫做array ),一个方法是让调用者保留空间并告诉函数使用它:

 void fn(int x[], int n) { for (int i = 0; i < n; ++i) x[i] = n; } void caller() { // local space on the stack - destroyed when caller() returns int x[10]; fn(x, sizeof x / sizeof x[0]); // or, use the heap, lives until delete[](p) called... int* p = new int[10]; fn(p, 10); } 

另一个select是将数组包装在一个结构中,与原始数组不同,这个结构是合法的,可以从函数返回值:

 struct X { int x[10]; }; X fn() { X x; xx[0] = 10; // ... return x; } void caller() { X x = fn(); } 

从上面开始,如果你使用C ++ 03,你可能想把它推广到更接近C ++ 11 std::array

 template <typename T, size_t N> struct array { T& operator[](size_t n) { return x[n]; } const T& operator[](size_t n) const { return x[n]; } size_t size() const { return N; } // iterators, constructors etc.... private: T x[N]; }; 

另一个select是让被调用的函数在堆上分配内存:

 int* fn() { int* p = new int[2]; p[0] = 0; p[1] = 1; return p; } void caller() { int* p = fn(); // use p... delete[] p; } 

为了帮助简化堆对象的pipe理,许多C ++程序员使用“智能指针”来确保当指向对象的指针离开它们的作用域时被删除。 用C ++ 11:

 std::shared_ptr<int> p(new int[2], [](int* p) { delete[] p; } ); std::unique_ptr<int[]> p(new int[3]); 

如果你停留在C ++ 03上,最好的办法是看你的机器上是否有boost库:它提供了boost::shared_array

另外一个select是使用fn()保留一些静态内存,虽然这不是线程安全的,并且意味着每次调用fn()覆盖任何人从前面的调用指针指向的数据。 也就是说,简单的单线程代码可以方便(快速)。

 int* fn(int n) { static int x[2]; // clobbered by each call to fn() x[0] = n; x[1] = n + 1; return x; // every call to fn() returns a pointer to the same static x memory } void caller() { int* p = fn(3); // use p, hoping no other thread calls fn() meanwhile and clobbers the values... // no clean up necessary... } 

从C ++函数中返回数组是不可能的。 8.3.5 [dcl.fct] / 6:

函数不应该有返回types的数组或函数[…]

最常用的select是返回一个类types的值,其中该类包含一个数组,例如

 struct ArrayHolder { int array[10]; }; ArrayHolder test(); 

或者返回一个指向静态或dynamic分配数组的第一个元素的指针,文档必须指示用户他是否需要(以及如何如何)解除分配返回的指针指向的数组。

例如

 int* test2() { return new int[10]; } int* test3() { static int array[10]; return array; } 

虽然可以返回一个引用或一个指向数组的指针,但是这是非常罕见的,因为它是一个更复杂的语法,没有任何上述方法的实际优势。

 int (&test4())[10] { static int array[10]; return array; } int (*test5())[10] { static int array[10]; return &array; } 

那么如果你想从一个函数返回你的数组,你必须确保这些值不会被存储在堆栈上,因为当你离开函数的时候它们将会消失。

所以要么让你的数组是静态的,要么分配内存(或者把它传入,但是你最初的尝试是用一个void参数)。 对于你的方法,我会这样定义它:

 int *gnabber(){ static int foo[] = {1,2,3} return foo; } 

“我怎样才能返回一个数组在c + +方法,我该如何声明呢?int [] test(void); ??”

 template <class X> class Array { X *m_data; int m_size; public: // there constructor, destructor, some methods int Get(X* &_null_pointer) { if(!_null_pointer) { _null_pointer = new X [m_size]; memcpy(_null_pointer, m_data, m_size * sizeof(X)); return m_size; } return 0; } }; 

只是为了int

 class IntArray { int *m_data; int m_size; public: // there constructor, destructor, some methods int Get(int* &_null_pointer) { if(!_null_pointer) { _null_pointer = new int [m_size]; memcpy(_null_pointer, m_data, m_size * sizeof(int)); return m_size; } return 0; } }; 

 Array<float> array; float *n_data = NULL; int data_size; if(data_size = array.Get(n_data)) { // work with array } delete [] n_data; 

例如int

 IntArray array; int *n_data = NULL; int data_size; if(data_size = array.Get(n_data)) { // work with array } delete [] n_data;