C ++ Возврат и вставка объекта 2D-массива - PullRequest
2 голосов
/ 31 декабря 2008

Я пытаюсь вернуть массив Data Member из одного меньшего 2D-объекта Array и пытаюсь вставить массив в более крупный 2D-объект массива. Но, пытаясь это сделать, я столкнулся с двумя проблемами.

Первая проблема заключается в том, что я хочу вернуть имя 2D-массива, но я не знаю, как правильно использовать синтаксис для возврата имени 2D-массива.

Вот так выглядит мой элемент данных 2D Array

private:
int pieceArray[4][4];
// 2D Smaller Array

и я хочу вернуть этот массив в функцию, но эта вызывает ошибку компилятора:

int Piece::returnPiece()
{
    return pieceArray; //not vaild
    // return the 2D array name
}

Я устал использовать этот тип возврата, и он работал:

int Piece::returnPiece()
{
    return pieceArray[4][4];
}

Но я не уверен, что это то, что я хочу, так как я хочу вернуть массив и все его содержимое.

Другая проблема - это функция InsertArray (), где я бы поместил функцию returnPiece () в аргумент InsertArray ().

Проблема с InsertArray () заключается в аргументе, вот код для него:

void Grid::InsertArray( int arr[4][4] ) //Compiler accepts, but does not work
{
    for(int i = 0; i &lt x_ROWS ; ++i)
    {
         for (int j = 0; j &lt y_COLUMNS ; ++j)
         {
             squares[i][j] = arr[i][j];
         }
    }
}

Проблема в том, что он не принимает мой returnPiece (), и если я удаляю «[4] [4]», мой компилятор не принимает.

В основном все это синтаксические ошибки, но как мне решить эти проблемы?

  1. Возвращение целого массива piece в returnPiece ()
  2. Правильный синтаксис для аргумента в InsertArray ()
  3. Аргумент InsertArray (), принимающий returnPiece ()

Эти 3 являются основными проблемами, с которыми мне нужна помощь, и имели ту же проблему, когда я пытался использовать метод указателя указателя. Кто-нибудь знает, как решить эти 3 проблемы?

Ответы [ 4 ]

3 голосов
/ 31 декабря 2008

При передаче вашего массива вы должны решить, хотите ли вы сделать копию массива или просто хотите вернуть указатель на массив. Для возврата массивов вы не можете (легко) вернуть копию - вы можете только вернуть указатель (или ссылку в 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. Это вызов по значению: всякий раз, когда вы вызываете его, вы делаете копию массива 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 ++.

0 голосов
/ 01 января 2009

Проблема с Адамом Розенфилдом arrayPtr в этом Piece :: pieceArray может измениться из-под вас (Копирование по ссылке против копирования по значению.)

Копирование по значению неэффективно. Но если вы действительно хотите это сделать, просто обмануть:

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 объект. (Как предложил Хуан ...)

0 голосов
/ 31 декабря 2008

Вот как бы я это сделал:

class Array {
  public:

    Array() {
      for (int i = 0; i < 4; ++i)
      {
         for (int j = 0; j < 4; ++j)
         {
            (*this)(i, j) = 0;
         }
      }
    }


    int &operator()(int i, int j)
    {
      return pieceArray[i][j];
    }

  private:
    int pieceArray[4][4];
};

Затем вы можете сделать что-то вроде:

  Array x; // create 4x4 array
  x(1, 2) = 3; // modify element
0 голосов
/ 31 декабря 2008

Похоже, вам нужно больше читать об указателях в C ++ и о передаче по ссылке или передаче по значению.

Ваш метод returnPiece определяется как возвращающий значение одной ячейки. Учитывая индекс (например, [4] [4]), вы возвращаете копию содержимого этой ячейки, поэтому вы не сможете ее изменить, или, вернее, изменение ее приведет к изменению копии.

Я уверен, что кто-то даст вам правильный синтаксис, но я действительно рекомендую изучить этот материал, так как в противном случае вы можете использовать код, который вы получили неправильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...