5

配列のポインター(プログラム内の一部の関数に必要なパラメーターを含む)を構造体に渡そうとすると、問題が発生します。構造体は、これらの関数に渡される必要があります。たとえば、GSLは、この方法でパラメータを渡すことを望んでいます。

小さなサンプルプログラムは次のようになります。

#include <iostream>

using namespace std;

struct myparams
{
    double  * a;
    double ** b;
};

int main()
{
    double c[10]   = {0,1,2,3,4,5,6,7,8,9};
    double d[4][3] = {{1,2,3},{4,5,6},{7,8,9},{10,11,12}};

    double** e = new double*[4];
    for (int i = 0; i < 4; i++) {
       e[i] = new double[3];
    }

    myparams params;

    // THIS WORKS:
    params.a = c;
    for (int i = 0; i < 10; i++) {
        cout << params.a[i] << endl;
    }

    // THIS DOESN'T WORK
    params.b = d;

    // THIS WORKS:
    params.b = e;

    delete[] e;
}

何が問題なのですか

 params.b = d

"cannot convert 'double[4][3]' to 'double**' in assignment"コンパイラは、(ドイツ語から翻訳された)またはそのようなものに文句を言います。

4

2 に答える 2

9

double d[4][3];配列の配列です。double b**;ポインタへのポインタです。これらの型は同じではありません (インターネットで読んだかもしれない一般的な「配列は単なるポインターです」は間違っています)。

の要素のdタイプはdouble[3]です。配列は、渡されると、最初の要素へのポインターに減衰します (C++ 標準のセクション 4.2. を参照)。(3 つの double の配列へのポインター) にd減衰します。double(*)[3]

簡単に言えば、にdouble(*)[3]変換することはできませdouble**ん。これは、コンパイラがあなたに伝えていることです。

そのままにしておく必要がある場合は、 b を;dとして宣言する必要があります。double (*b)[3]

詳細な説明については、この SO questionを参照してください。

于 2013-02-15T14:16:15.087 に答える
7

これは、ポインターへのポインター (または使用できるポインターの配列) が配列の配列と同じではないためです。メモリ内のレイアウトに互換性がありません。

たとえば、次の 2 つの宣言があるとします。

char aa[2][2] = { { 'a', 'b' }, { 'c', 'd' } };
char **pp;

pp = new char*[2];
pp[0] = new char[2];
pp[1] = new char[2];

配列aaはメモリ内で次のようになります。

+----------+----------+----------+----------+
| aa[0][0] | aa[0][1] | aa[1][0] | aa[1][1] |
+----------+----------+----------+----------+

一方、「配列」ppは次のようになります。

+------+------+
| a[0] | a[1] |
+------+------+
   |      |
   |      v
   |      +---------+---------+
   |      | a[0][0] | a[0][1] |
   |      +---------+---------+
   V
   +---------+---------+
   | a[0][0] | a[0][1] |
   +---------+---------+

「配列」ppには、別の「配列」へのポインタが含まれています

于 2013-02-15T14:08:32.297 に答える