2

私は少し混乱しています。メソッドから配列を返す方法は 2 つあります。最初は次のことを示唆しています。

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 (*)[]

私が間違っていること、または私の知識に欠けていることは何か分かりますか?

4

3 に答える 3

9

配列を値で返したい場合は、それを構造体に入れます。

標準委員会はすでにそれを行っているので、 を使用できます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);
于 2012-12-26T20:35:52.127 に答える
1

まず、あなたが提供する情報が間違っています。

あなたが書く、

「メソッドから配列を返す方法は 2 つあります」

そして、あなたは方法の例として挙げます

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

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

(欠けている右括弧を追加しました)、この後者の方法は、最初の方法とは対照的に、

「参照またはポインタを介して」

さて、これら 2 つの宣言はまったく同じ意味です。

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 );
}

どちらの場合も、配列へのポインターが返され、このポインターは「配列へのポインター」として型指定されます。そのポインターを逆参照すると、配列自体が生成され、それ自体へのポインターに再び減衰しますが、「アイテムへのポインター」として型付けされます。配列の最初の項目へのポインタです。マシン コード レベルでは、これら 2 つのポインターは実際にはまったく同じです。長い間私を混乱させた Pascal のバックグラウンドから来ましたが、結果として、配列のサイズを型に含めることは一般に非現実的であるため (実行時のサイズが異なる配列を扱うことができなくなります)、ほとんどの配列処理コードは、配列全体へのポインタではなく、最初の項目へのポインタ。

つまり、通常、このような低レベルの C 言語のような関数は、次のように宣言されます。

int* func()

実行時に確立されたサイズの配列の最初の項目へのポインターを返します。

ここで、配列を値で返したい場合は、次の2 つの選択肢があります。

  • 固定サイズの配列を値で返す: に入れます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ください。

于 2012-12-26T21:22:08.583 に答える
0
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このようなコーディングは絶対に行わないでください。ただし、このコードが役立つと確信しています。

于 2016-05-31T18:54:46.860 に答える