Pergunta

Eu estou tentando retornar uma matriz membro de dados a partir de um menor matriz de objeto 2D, e tentar inserir a matriz em um objeto de matriz 2D maior. Mas ao tentar isso, eu vim em dois problemas.

O primeiro problema é que eu quero para retornar o nome da matriz 2D, mas eu não sei como a sintaxe adequada para retornar nome de matriz 2D.

Isto é o que os meus 2D membro de dados de matriz se parece com

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

e eu quero voltar essa matriz em uma função, mas este faz com que um erro do compilador:

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

Eu cansei de usar este tipo de retorno e funcionou:

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

Mas não tenho certeza se é isso que eu quero, como eu quero voltar a matriz e tudo isso do conteúdo.

O outro problema é a função InsertArray (), onde eu iria colocar a função returnPiece () no InsertArray () 's argumento.

O problema com o InsertArray () é o argumento, aqui está o código para ele:

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];
         }
    }
}

O problema com isso é que ele não aceita minha returnPiece (), e se eu remover o "[4] [4]", meu compilador não aceitar.

Na maior parte todos estes são erros de sintaxe, mas como faço para resolver esses problemas?

  1. Voltando todo o pieceArray em returnPiece ()
  2. A sintaxe correta para o argumento em InsertArray ()
  3. O argumento de InsertArray () aceitar a returnPiece ()

Estes 3 são os principais problemas que eu preciso de ajuda com, e teve o mesmo problema quando tento usar o método de ponteiro ponteiro. Alguém sabe como resolver esses 3 problemas?

Foi útil?

Solução

Ao passar seu redor array, você tem que decidir se quer ou não quer fazer uma cópia da matriz, ou se você só quer retornar um ponteiro para a matriz. Para retornar arrays, você não pode (facilmente) devolver uma cópia - você só pode retornar um ponteiro (ou referência em C ++). Por exemplo:

// 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;
}

Para usá-lo, chamá-lo assim:

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

Observe a semelhança entre a declaração de tipo e usá-lo -. Parênteses, dereferencing * operador e suportes estão nos mesmos lugares

A sua declaração para Grid::InsertArray está correto - que leva um argumento, que é uma matriz 4x4 de inteiros. Esta é chamada por valor: sempre que você chamá-lo, você faz uma cópia de sua matriz 4x4, portanto, qualquer modificação que você faz não são refletidas na matriz passada Se você, em vez queria usar chamada por referência, você poderia. passar um ponteiro para uma matriz em vez:

// 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];
     }
}

Estas declarações de tipo com ponteiros para arrays multidimensionais podem ficar realmente confuso rápido. Eu recomendo fazer uma typedef para ele assim:

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

Depois, você pode declarar suas funções muito mais legível:

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

Você também pode usar o cdecl programa para ajudar decifrar complicados tipos de C / C ++.

Outras dicas

Parece que você precisa ler mais sobre ponteiros em C ++ e na passagem por passagem de referência vs. por valor.

Seu método returnPiece é definida como retornando o valor de uma única célula. Dado o índice (por exemplo, [4] [4]), você retornar uma cópia do conteúdo dessa célula, então você não será capaz de mudá-lo, ou, mais corretamente, mudando isso mudaria a cópia.

Eu tenho certeza que alguém vai lhe dar a sintaxe correta, mas eu realmente recomendo aprender essas coisas pois, caso contrário você pode usar o código que você começa de forma incorreta.

Aqui está como eu faria isso:

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];
};

Você pode então fazer algo como:

  Array x; // create 4x4 array
  x(1, 2) = 3; // modify element

Problemas com de Adam Rosenfield arrayPtr em que Peça :: pieceArray pode mudar para fora debaixo de você. (Copie por referência vs cópia por valor).

Copiar por valor é ineficiente. Mas se você realmente quiser fazê-lo, apenas enganar:

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]
}

É claro, uma solução orientada a objeto melhor, mais, seria ter returnPiece () criar e retornar um Peça ou array objeto. (Como Juan sugeriu ...)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top