0

関数から配列を返すにはどうすればよいですか? 私のコードは

float ClassArray::arr_sub(float a[100][100], float b[100][100]) {
    int i,j;
    for(i = 1; i < 10; i++) {
        for(j = 1; j < 10; j++){
            f[i][j]=b[i][j]-a[i][j];
        }
    }
    return f;
}

この関数から返された f は、他のクラスで宣言された別の配列 g に割り当てられる必要があります。

float g[100][100];
g= cm.arr_sub(T,W);

しかし、クラスを構築している間、それは言いincompatible type assignment of float to float[100][100]ます.

4

4 に答える 4

11

配列に関する別の質問に対する私の答えは、配列を使用したくない理由を説明しています

その答えで私が言っているように、あなたが試みているように配列を割り当てることはできません:

float g[100];
g = foo(); // illegal, assigning to arrays is not allowed

配列に関するもう1つの奇妙な制限は、関数から配列を返すことが許可されていないことです。

float foo()[100]; // illegal, returning an array from a function is not allowed

float arr_sub(float a[100][100])また、配列を値で渡していると思うかもしれないような関数を宣言すると、実際には、配列に対して行われた別の奇妙な例外が呼び出されることに注意してください。CおよびC++では、関数の仮パラメーターを配列として宣言するたびに、型は「配列」から「配列の要素型へのポインター」に調整されます。


配列は本来の動作をしないため、代わりにstd::arrayまたはstd::vector:を使用する必要があります。

std::array<float,100> foo(); // works

std::array<float,100> g;
g = foo(); // works

多次元配列を実行するには、次を使用できます。

std::array<std::array<float,100>,100> g;

それは少し面倒なので、typedefすることができます:

typedef std::array<std::array<float,100>,100> Matrix;

Matrix ClassArray::arr_sub(Matrix a, Matrix b) {
    ...
}

Matrix g;
g = cm.arr_sub(T,W);

また、C ++ 11をサポートするコンパイラがある場合は、テンプレートタイプのエイリアスを実行することもできます。

template<typename T,int Rows,int Columns>
using Matrix2d = std::array<std::array<T,Columns>,Rows>;

Matrix2d<float,100,100> g;

パフォーマンスに関する注意

std::arrayを値で返したくない理由が1つあります。配列が大きい場合は、データを戻り値から割り当てた変数にコピーする際に、パフォーマンスが大幅に低下する可能性があります。それが問題になる場合は、std::arrayを使用したソリューションは他の大きなタイプの場合と同じです。値で返す代わりに、「out」パラメーターを使用します。

void arr_sub(Matrix a, Matrix b, Matrix &result);

Matrix g;
arr_sub(T,W,g);

std :: vectorは移動セマンティクスを利用して、すべての要素をコピーする必要がないため、これはstd::vectorには適用されません。

于 2012-04-22T01:01:57.493 に答える
2

「プレーンC」の2D配列を使用する場合は、配列を値で渡すのではなく、2つの入力パラメーターとともに結果へのポインターを渡すのが最善です。

ただし、C ++で行う最善の方法は、vector<vector<float> >代わりに使用し、参照によって渡すことです。

void ClassArray::arr_sub(
    const vector<vector<float> > &a
,   const vector<vector<float> > &b
,   vector<vector<float> > &res)
{
    for(int i=0 ; i != a.size() ; i++)
        for(int j=0 ; j != b.size() ; j++)
            res[i][j] = b[i][j] - a[i][j];
}

void main() {
    vector<vector<float> > a(100, vector<float>(100, 12.345));
    vector<vector<float> > b(100, vector<float>(100, 98.765));
    vector<vector<float> > res(100, vector<float>(100, 0));
    arr_sub(a, b, res);
}
于 2012-04-22T01:02:59.233 に答える
0

これを行う最良の方法は、すべてをクラスにラップすることです。物事の外観から、それはマトリックスです。

おそらくすでに100のMatrixクラスがあるので、別のクラスを作成することは本当に無意味です。

しかし、これが学習演習である場合、それは価値があるかもしれません。

尋ねられた質問に答えるには、関数に3番目の引数を付けますfloat result[100][100]。関数内で、結果を結果配列に書き込みます。

これが機能するのは、CおよびC ++では、配列は常に参照によって渡され、値によって渡されることはないためです。これは、C++が配列の先頭へのポインターのみを渡すためです。

于 2012-04-22T01:05:05.547 に答える
0

本当に配列を返したいのに、それを main() でなんとか使用したい場合、最も効率的な方法は、返される配列を動的として宣言することです。そうすれば、スタックではなくヒープに割り当てられるため、この新しい配列へのポインターが失われることを回避できます。

于 2012-04-22T02:33:47.117 に答える