Pregunta

Estoy tratando de devolver un miembro de datos de matriz de un objeto de matriz 2D más pequeño, y estoy tratando de insertar la matriz en un objeto de matriz 2D más grande. Pero al intentar esto, tuve dos problemas.

El primer problema es que quiero devolver el nombre de la matriz 2D, pero no sé cómo configurar correctamente la sintaxis para devolver el nombre de la matriz 2D.

Así es como se ve mi miembro de datos de matriz 2D

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

y quiero devolver esta matriz a una función, pero esta causa un error de compilación:

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

Me cansé de usar este tipo de retorno y funcionó:

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

Pero no estoy seguro de si esto es lo que quiero, ya que quiero devolver la matriz y todo su contenido.

El otro problema es la función InsertArray (), donde pondría la función returnPiece () en el argumento de InsertArray ().

El problema con InsertArray () es el argumento, aquí está el código:

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

El problema con esto es que no acepta mi returnPiece (), y si elimino el " [4] [4] " ;, mi compilador no acepta.

En su mayoría, todos estos son errores de sintaxis, pero ¿cómo resuelvo estos problemas?

  1. Devolver toda la pieza Array in returnPiece ()
  2. La sintaxis correcta para el argumento en InsertArray ()
  3. El argumento de InsertArray () que acepta el returnPiece ()

Estos 3 son los principales problemas con los que necesito ayuda, y tuve el mismo problema cuando intento usar el método del puntero del puntero. ¿Alguien sabe cómo resolver estos 3 problemas?

¿Fue útil?

Solución

Al pasar su matriz, debe decidir si desea hacer una copia de la matriz o si desea devolver un puntero a la matriz. Para devolver matrices, no puede (fácilmente) devolver una copia, solo puede devolver un puntero (o referencia en C ++). Por ejemplo:

// 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 usarlo, llámelo así:

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

Observe la similitud entre la declaración de tipo y su uso: los paréntesis, el operador de referencia * y los corchetes están en los mismos lugares.

Su declaración para Grid :: InsertArray es correcta: toma un argumento, que es una matriz de enteros 4x4. Esto es una llamada por valor: cada vez que lo llama, hace una copia de su matriz 4x4, por lo que cualquier modificación que realice no se refleja en la matriz que se pasa. Si en su lugar desea utilizar la llamada por referencia, podría pasar un puntero a una matriz en su lugar:

// 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 declaraciones de tipo con punteros a matrices multidimensionales pueden volverse realmente confusas rápidamente. Recomiendo hacer un typedef para que sea así:

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

Luego puedes declarar tus funciones mucho más legibles:

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

También puede usar el programa cdecl para ayudar descifrar tipos complicados de C / C ++.

Otros consejos

Parece que necesita leer más sobre punteros en C ++ y sobre pasar por referencia frente a pasar por valor.

Su método returnPiece se define como devolver el valor de una sola celda. Dado el índice (por ejemplo, [4] [4]), devuelve una copia del contenido de esa celda, por lo que no podrá cambiarla, o más correctamente, cambiarla cambiaría la copia.

Estoy seguro de que alguien te dará la sintaxis correcta, pero realmente recomendaría aprender esto, ya que de lo contrario, puedes usar el código que obtienes de manera incorrecta.

Así es como lo haría:

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

Luego puedes hacer algo como:

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

Problemas con Adam Rosenfield's arrayPtr en que Piece :: pieceArray puede cambiar desde debajo de ti. (Copia por referencia vs Copia por valor.)

La copia por valor es ineficiente. Pero si realmente quieres hacerlo, solo haz trampa:

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

Por supuesto, una solución mejor, más orientada a objetos, sería hacer que returnPiece () cree y devuelva un Piece o Array objeto. (Como Juan sugirió ...)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top