2

1 つの小さい 2D 配列オブジェクトから配列データ メンバーを返そうとしていて、その配列をより大きな 2D 配列オブジェクトに挿入しようとしています。しかし、これを試みたとき、私は2つの問題に遭遇しました。

最初の問題は、2D 配列の名前を返したいのですが、2D 配列名を返すための適切な構文がわかりません。

これは、私の 2D 配列データ メンバーがどのように見えるかです

プライベート:
int pieceArray[4][4];
// 2D の小さい配列

この配列を関数に返したいのですが、これはコンパイラエラーを引き起こします:

int ピース::returnPiece()
{
    pieceArray を返します。//無効
    // 2D 配列名を返す
}

この戻り値の型を使用するのに疲れましたが、うまくいきました:

int ピース::returnPiece()
{
    pieceArray[4][4] を返します。
}

しかし、配列とそのすべてのコンテンツを返したいので、これが私が望むものかどうかはわかりません。

もう 1 つの問題は、InsertArray() 関数です。ここで、returnPiece() 関数を InsertArray() の引数に入れます。

InsertArray() の問題は引数です。そのコードは次のとおりです。

void Grid::InsertArray( int arr[4][4] ) //コンパイラは受け入れますが、動作しません
{
    for(int i = 0; i < x_ROWS ; ++i)
    {
         for (int j = 0; j < y_COLUMNS ; ++j)
         {
             squares[i][j] = arr[i][j];
         }
    }
}

これの問題は、returnPiece() を受け入れないことです。"[4][4]" を削除すると、コンパイラは受け入れません。

ほとんどの場合、これらはすべて構文エラーですが、これらの問題を解決するにはどうすればよいですか?

  1. returnPiece() で pieceArray 全体を返す
  2. InsertArray() の引数の正しい構文
  3. returnPiece() を受け入れる InsertArray() の引数

これら 3 つは私が助けを必要とする主要な問題であり、ポインター ポインター メソッドを使用しようとしたときに同じ問題が発生しました。この3つの問題を解決する方法を知っている人はいますか?

4

4 に答える 4

4

配列を渡すときは、配列のコピーを作成するかどうか、または配列へのポインターを返すだけかどうかを決定する必要があります。配列を返す場合、(簡単に) コピーを返すことはできません。ポインター (または C++ では参照) のみを返すことができます。例えば:

// Piece::returnPiece is a function taking no arguments and returning a pointer to a
// 4x4 array of integers
int (*Piece::returnPiece(void))[4][4]
{
    // return pointer to the array
    return &pieceArray;
}

それを使用するには、次のように呼び出します。

int (*arrayPtr)[4][4] = myPiece->returnPiece();
int cell = (*arrayPtr)[i][j];  // cell now stores the contents of the (i,j)th element

型宣言とそれを使用することの類似性に注意してください。括弧、逆参照演算子*、および括弧は同じ場所にあります。

の宣言Grid::InsertArrayは正しいです。4x4 の整数配列である 1 つの引数を取ります。これは値渡しです: 呼び出すたびに 4x4 配列のコピーを作成するため、行った変更は渡された配列には反映されません。代わりに参照渡しを使用したい場合は、代わりに配列へのポインターを渡します。

// InsertArray takes one argument which is a pointer to a 4x4 array of integers
void Grid::InsertArray(int (*arr)[4][4])
{
     for(int i = 0; i < x_ROWS; i++)
     {
         for(int j = 0; j < y_COLUMNS ; j++)
             squares[i][j] = (*arr)[i][j];
     }
}

多次元配列へのポインターを使用したこれらの型宣言は、すぐに混乱を招く可能性があります。次のように作成することをお勧めしtypedefます。

// Declare IntArray4x4Ptr to be a pointer to a 4x4 array of ints
typedef int (*IntArray4x4Ptr)[4][4];

次に、関数をより読みやすく宣言できます。

IntArray4x4Ptr Piece::returnPiece(void) { ... }
void Grid::InsertArray(IntArray4x4Ptr arr) { ... }

cdeclプログラムを使用して、複雑な C/C++ 型を解読することもできます。

于 2008-12-31T07:12:36.727 に答える
0

C++ のポインターと、参照渡しと値渡しについて詳しく読む必要があるようです。

returnPiece メソッドは、単一のセルの値を返すように定義されています。インデックス ([4][4] など) を指定すると、そのセルの内容のコピーが返されるため、それを変更することはできません。より正確には、変更するとコピーが変更されます。

誰かが正しい構文を教えてくれると確信していますが、このことを学ぶことを強くお勧めします。

于 2008-12-31T06:58:26.537 に答える
0

これが私がそれを行う方法です:

クラス配列{
  公衆:

    配列() {
      for (int i = 0; i < 4; ++i)
      {
         for (int j = 0; j < 4; ++j)
         {
            (*これ)(i, j) = 0;
         }
      }
    }


    int &operator()(int i, int j)
    {
      pieceArray[i][j] を返します。
    }

  プライベート:
    int pieceArray[4][4];
};

次に、次のようなことができます。

  配列 x; // 4x4 配列を作成
  x(1, 2) = 3; // 要素を変更
于 2008-12-31T07:07:01.217 に答える
0

そのPiece::pieceArrayの Adam Rosenfield の arrayPtrの問題は、あなたの下から変わる可能性があります。(参照によるコピーと値によるコピー。)

値によるコピーは非効率的です。しかし、本当にやりたい場合は、ごまかすだけです。

struct FOO { int  piece [4][4]; };

FOO Piece::returnPiece()
{
  FOO f;
  memcpy( f.piece, pieceArray, sizeof(pieceArray) );
  return f;
}

void Grid::InsertArray( const FOO & theFoo )
{
  // use theFoo.piece[i][j]
}

もちろん、より優れた、よりオブジェクト指向のソリューションは、returnPiece()でPieceまたはArrayオブジェクトを作成して返すことです。(フアンが提案したように...)

于 2009-01-01T06:01:04.373 に答える