Domanda

Sto cercando di restituire un membro di dati dell'array da un oggetto array 2D più piccolo e sto cercando di inserire l'array in un oggetto array 2D più grande. Ma quando ho tentato questo, ho riscontrato due problemi.

Il primo problema è che voglio restituire il nome dell'array 2D, ma non so come sintassi correttamente per restituire il nome dell'array 2D.

Ecco come appare il mio membro di dati dell'array 2D

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

e voglio restituire questa matrice in una funzione, ma questa causa un errore del compilatore:

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

Mi sono stancato di usare questo tipo di ritorno e ha funzionato:

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

Ma non sono sicuro se questo è quello che voglio, poiché voglio restituire l'array e tutto il suo contenuto.

L'altro problema è la funzione InsertArray (), in cui vorrei inserire la funzione returnPiece () nell'argomento di InsertArray ().

Il problema con InsertArray () è l'argomento, ecco il codice per questo:

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

Il problema è che non accetta il mio returnPiece () e se rimuovo " [4] [4] " ;, il mio compilatore non accetta.

Principalmente tutti questi sono errori di sintassi, ma come posso risolvere questi problemi?

  1. Restituzione dell'intero pezzoArray in returnPiece ()
  2. La sintassi corretta per l'argomento in InsertArray ()
  3. L'argomento di InsertArray () che accetta returnPiece ()

Questi 3 sono i principali problemi con cui ho bisogno di aiuto e hanno avuto lo stesso problema quando provo ad usare il metodo puntatore puntatore. Qualcuno sa come risolvere questi 3 problemi?

È stato utile?

Soluzione

Quando si passa in giro l'array, è necessario decidere se si desidera creare una copia dell'array o se si desidera semplicemente restituire un puntatore all'array. Per restituire array, non è possibile (facilmente) restituire una copia - è possibile restituire solo un puntatore (o riferimento in C ++). Ad esempio:

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

Per usarlo, chiamalo così:

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

Nota la somiglianza tra la dichiarazione del tipo e il suo utilizzo: le parentesi, l'operatore di dereferenziazione * e le parentesi si trovano negli stessi punti.

La tua dichiarazione per Grid :: InsertArray è corretta - richiede un argomento, che è un array 4x4 di numeri interi. Questo è call-by-value: ogni volta che lo chiami, fai una copia del tuo array 4x4, quindi qualsiasi modifica che fai non si riflette nell'array passato. Se invece volessi usare il call-by-reference, potresti passa invece un puntatore a un array:

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

Queste dichiarazioni di tipo con puntatori ad array multidimensionali possono diventare molto rapidamente confuse. Ti consiglio di creare un typedef in questo modo:

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

Quindi puoi dichiarare le tue funzioni molto più leggibili:

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

Puoi anche usare il cdecl per aiutarti decifrare complicati tipi C / C ++.

Altri suggerimenti

Sembra che tu abbia bisogno di leggere di più sui puntatori in C ++ e sul passaggio per riferimento rispetto al passaggio per valore.

Il metodo returnPiece è definito come la restituzione del valore di una singola cella. Dato l'indice (ad esempio, [4] [4]) restituisci una copia del contenuto di quella cella, quindi non sarai in grado di cambiarlo, o più correttamente, cambiandolo cambierebbe la copia.

Sono sicuro che qualcuno ti fornirà la sintassi corretta, ma consiglierei davvero di imparare queste cose poiché altrimenti potresti usare il codice che ottieni in modo errato.

Ecco come lo farei:

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

Puoi quindi fare qualcosa del tipo:

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

Problemi con Adam Rosenfield arrayPtr in quanto Piece :: pieceArray può cambiare da sotto di te. (Copia per riferimento vs Copia per valore.)

La copia per valore è inefficiente. Ma se vuoi davvero farlo, cheat:

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

Naturalmente, una soluzione migliore e più orientata agli oggetti sarebbe quella di avere returnPiece () creare e restituire un pezzo o matrice oggetto. (Come suggerito da Juan ...)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top