C++ Возврат и вставка объекта двумерного массива

StackOverflow https://stackoverflow.com/questions/402432

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

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 < x_ROWS ; ++i)
    {
         for (int j = 0; j < y_COLUMNS ; ++j)
         {
             squares[i][j] = arr[i][j];
         }
    }
}

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

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

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

Проблема с Адам Розенфилд массивПтр в этом Часть::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() создать и вернуть Кусок или Множество объект.(Как Хуан предложенный...)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top