Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从函数返回数组?_C++_Arrays_Method Signature - Fatal编程技术网

C++ 如何从函数返回数组?

C++ 如何从函数返回数组?,c++,arrays,method-signature,C++,Arrays,Method Signature,如何从方法返回数组,以及如何声明它 int[] test(void); // ?? int*test() 但使用向量“更像C++”: std::vectortest() 编辑 我要澄清一点。自从提到C++,我将与NeX[]/Cuff>和Dele[]/Calp>运算符进行比较,但MalC/C++/-Pr>是相同的。 在第一种情况下,您将编写如下内容: int* test() { return new int[size_needed]; } 但这不是一个好主意,因为函数的客户端并不真正知

如何从方法返回数组,以及如何声明它

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

但使用向量“更像C++”:

std::vectortest()

编辑
我要澄清一点。自从提到C++,我将与NeX[]/Cuff>和Dele[]/Calp>运算符进行比较,但MalC/C++/-Pr>是相同的。 在第一种情况下,您将编写如下内容:

int* test() {
    return new int[size_needed];
}
但这不是一个好主意,因为函数的客户端并不真正知道要返回的数组的大小,尽管客户端可以通过调用
delete[]
安全地解除对它的分配

int* theArray = test();
for (size_t i; i < ???; ++i) { // I don't know what is the array size!
    // ...
}
delete[] theArray; // ok.
您的客户端代码现在是:

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.

更简单、更安全。

如果要从函数返回数组,必须确保值不会存储在堆栈中,因为它们在离开函数时会消失

因此,要么使数组保持静态,要么分配内存(或者传入内存,但最初尝试使用void参数)。对于您的方法,我将如下定义:

int *gnabber(){
  static int foo[] = {1,2,3}
  return foo;
}
如何在C++方法中返回数组,如何声明?int[]测试(无效)

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

  • ,动态增长到运行时遇到的元素数量,或

  • (由C++11引入),它总是存储编译时指定的大量元素

…当他们为您管理内存时,可确保正确的行为并大大简化事情:

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();
}
另一个选项是将数组包装在一个结构中,与原始数组不同,从函数按值返回是合法的:

struct X
{
    int x[10];
};

X fn()
{
    X x;
    x.x[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];
};
<>为了帮助简化堆对象的管理,许多C++程序员使用“智能指针”,当指针指向对象的范围时,确保删除。使用C++11:

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

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

函数不应具有数组或函数[…]类型的返回类型

最常用的替代方法是返回类类型的值,其中该类包含数组,例如

struct ArrayHolder
{
    int array[10];
};

ArrayHolder test();
或者,要返回指向静态或动态分配数组的第一个元素的指针,文档必须向用户指示是否需要(如果需要,应该如何)释放返回指针指向的数组

例如

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

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

int (*test5())[10]
{
        static int array[10];
        return &array;
}
如何在C++方法中返回数组,我必须如何声明它? int[]测试(无效);??“

范例

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

delete [] n_data;

我会返回一个
std::vector
到“如何返回C++中的数组”的问题,如果你不解释它实际上不返回数组而是指针,那么我会误导你。我增加了一些必要的澄清。当你把向量的引用传递给函数时,它是否更有效,函数然后添加了它想要的元素?你不必复制整个向量,包括所有元素(当你返回向量时会发生什么,对吗?)@Kapichu,如果RVO失败,向量将被移动,而不是复制。我不相信
new[]int(10)
是一个有效的新表达式。你是说
new int[10]
?@Charles:可能吧,我讨厌整天被困在C#中,然后试图回答这里的问题。。。啊…;-)我完全明白了。这个问题已经作为一个标题非常相似的问题的副本结束了。然而,这个问题是关于返回作为参数传递给函数的数组。这是一个非常不同的命题,意味着这是一个不同的(更有趣的问题)返回
std::array
std::vector
。不是C样式的数组。
int* fn()
{
    int* p = new int[2];
    p[0] = 0;
    p[1] = 1;
    return p;
}

void caller()
{
    int* p = fn();
    // use p...
    delete[] p;
}
std::shared_ptr<int> p(new int[2], [](int* p) { delete[] p; } );
std::unique_ptr<int[]> p(new int[3]);
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...
}
struct ArrayHolder
{
    int array[10];
};

ArrayHolder test();
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;
}
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;
    }
}; 
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;
IntArray   array;
int       *n_data = NULL;
int        data_size;
if(data_size = array.Get(n_data))
{  // work with array  }

delete [] n_data;