【问题标题】:Returning an array ... rather a reference or pointer to an array返回一个数组...而不是指向数组的引用或指针
【发布时间】:2012-12-12 07:52:38
【问题描述】:

我有点困惑。从方法返回数组有两种方法。第一个建议如下:

typedef int arrT[10];
arrT *func(int i);

但是,我如何捕获返回的 int (*)[]?

另一种方式是通过引用或指针:

int (*func(int i)[10];

int (&func(int i)[10];

返回类型是 int (*)[] 或 int (&)[]。

我遇到的问题是如何分配一个变量来接受这一点,但我仍然会遇到以下错误:

can't convert int* to int (*)[]

知道我做错了什么或者我缺乏什么知识吗?

【问题讨论】:

  • 函数原型中的括号不匹配。
  • 您似乎不小心设置了函数指针。那是你想做的吗?
  • 如果你不想要一个 C++ 结构,只需要一个普通的 C 数组,那么:"int* array (int* size); int size = 0; int* arr = array (&size); "
  • 在可能的情况下不要忘记接受答案。您还应该考虑接受其他问题的答案。

标签: c++ arrays return


【解决方案1】:

如果要按值返回数组,请将其放入结构中。

标准委员会已经这样做了,因此您可以使用std::array<int,10>

std::array<int,10> func(int i);
std::array<int,10> x = func(77);

这使得通过引用返回也非常简单:

std::array<int,10>& func2(int i);
std::array<int,10>& y = func2(5);

【讨论】:

  • 我明白了……我每天都会学到一些东西,但特别是针对我的情况,如何将 func 的返回值分配给变量?如果我使用指针,则会收到 int * 无法转换为 int (*)[] 的错误。
  • 你能举个例子,说明返回非const std::array 的引用是个好主意。我只能想到一种自然用法(在仅标头模块中提供一个数组,供整个程序使用),我认为作为初学者的 OP 不会理解这种用法​​
  • @Alf:在map&lt; string, array&lt;int,10&gt; &gt; m; 中,m["Ben"] 的返回类型是array&lt;int,10&gt;&amp;(非const)。也许你想拥有 session-local-storage(类似于 thread-local-storage)。访问者可能会返回一个array&lt;int,10&gt;&amp;。如果你用心思考,我相信你可以想到其他例子。
  • @Alf:是的,我认为它对成员函数最有用,但非成员的说明更简单。
【解决方案2】:

首先,您提供的信息不正确。

你写,

“从方法返回数组有两种方式”

然后你给出方法的例子

typedef int arrT[10];
arrT *func(int i);

int (*func(int i))[10];

(我添加了缺少的右括号),你说后一种方式,与第一种方式相比,是一个例子

“通过引用或指针”

嗯,这两个声明的意思完全一样,也就是说:

typedef int A[10];
A* fp1( int i ) { return 0; }

int (*fp2( int i ))[10] { return 0; }

int main()
{
    int (*p1)[10]   = fp1( 100 );
    int (*p2)[10]   = fp2( 200 );
}

在这两种情况下都会返回一个指向数组的指针,并且这个指针的类型是“指向数组的指针”。取消引用该指针会产生数组本身,它会再次衰减为指向自身的指针,但现在键入为“指向项目的指针”。它是指向数组第一项的指针。在机器代码级别,这两个指针实际上是完全相同的。来自帕斯卡的背景让我困惑了很长时间,但结果是,因为在类型中携带数组大小通常是不切实际的(这排除了处理不同运行时大小的数组),大多数数组处理代码处理指向第一项的指针,而不是指向整个数组的指针。

也就是说,通常像函数这样的低级 C 语言会被声明为 just

int* func()

返回指向在运行时建立的大小数组的第一项的指针。

现在,如果您想按值返回一个数组,那么您有两种选择:

  • 按值返回固定大小的数组:将其放入struct
    该标准已经提供了一个模板类,std::array

  • 按值返回可变大小的数组:使用处理复制的类。
    该标准已经提供了一个模板类,std::vector

例如,

#include <vector>
using namespace std;

vector<int> foo() { return vector<int>( 10 ); }

int main()
{
    vector<int> const   v = foo();
    // ...
}

这是最一般的。使用std::array 更多的是针对特殊情况的优化。作为初学者,请记住 Donald Knuth 的建议:“过早的优化是万恶之源。”即,只使用std::vector,除非有非常好的理由使用std::array

【讨论】:

  • 不要误会我的意思,我知道 C++ 应该使用向量而不是数组,但在我目前的学习中,我正在学习如何从 func 返回数组。此外,第一个声明是 typedef,然后使用 typedef。它们不是返回数组的两种方式。第二个上市是第二种方式。这仍然不能帮助我理解如何将变量分配给返回......哇,这是我的问题。如果我有一个 func 定义如下: auto func(int i) -> int (*)[10] 那么我如何定义一个变量来获取数组?这是我的问题!!!!!!
  • @user633658:关于“第二个列表是第二种方式”,NO。它的含义与第一个完全相同。如上所示。
  • @user633658:关于“如何定义变量来获取数组”,请参阅此答案中给出的完整示例代码。
  • 是的,你是正确的......我错过了上面的一些阅读内容以获得你的答案。我确实输入了 int (*arr)[] 并没有给它一个数组的大小。最后可能把我搞砸了。
【解决方案3】:
using arrT10 = int[10]; // Or you can use typedef if you want

arrT10 * func(int i)
{
    arrT10 a10;
    return &a10;

    // int a[10];
    // return a;    // ERROR: can't convert int* to int (*)[]
}

这会给你一个警告,因为func 返回一个局部变量的地址,所以我们不应该这样编码,但我相信这段代码可以帮助你。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    相关资源
    最近更新 更多