Question

J'essaie de renvoyer un membre de données de tableau à partir d'un objet de tableau 2D plus petit et d'essayer d'insérer le tableau dans un objet de tableau 2D plus grand. Mais en essayant cela, je suis tombé sur deux problèmes.

Le premier problème est que je veux renvoyer le nom du tableau 2D, mais je ne sais pas comment utiliser correctement la syntaxe pour renvoyer le nom du tableau 2D.

Voici à quoi ressemble mon membre de données de tableau 2D

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

et je veux retourner ce tableau dans une fonction, mais celle-ci provoque une erreur de compilation:

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

Je me suis fatigué avec ce type de retour et cela a fonctionné:

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

Mais je ne sais pas si c'est ce que je veux, car je veux renvoyer le tableau et tout son contenu.

L’autre problème est la fonction InsertArray (), dans laquelle je mettrais la fonction returnPiece () dans l’argument de InsertArray ().

Le problème avec InsertArray () est l'argument, voici le code correspondant:

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

Le problème, c'est qu'il n'accepte pas mon returnPiece (), et si je supprime le "[4] [4]", mon compilateur n'accepte pas.

Ce sont principalement des erreurs de syntaxe, mais comment puis-je résoudre ces problèmes?

  1. Renvoyer l'intégralité de pieceArray dans returnPiece ()
  2. La syntaxe correcte pour l'argument dans InsertArray ()
  3. L'argument de InsertArray () acceptant le returnPiece ()

Ce sont les 3 principaux problèmes pour lesquels j’ai besoin d’aide. Ils ont eu le même problème lorsque j’ai essayé d’utiliser la méthode du pointeur. Est-ce que quelqu'un sait comment résoudre ces 3 problèmes?

Était-ce utile?

La solution

Lorsque vous faites passer votre tableau, vous devez décider si vous voulez ou non en copier le tableau ou si vous voulez simplement renvoyer un pointeur sur le tableau. Pour renvoyer des tableaux, vous ne pouvez pas (facilement) renvoyer une copie. Vous pouvez uniquement renvoyer un pointeur (ou une référence en C ++). Par exemple:

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

Pour l'utiliser, appelez-le comme suit:

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

Notez la similitude entre la déclaration de type et son utilisation: les parenthèses, l'opérateur de déréférencement * et les crochets se trouvent au même endroit.

Votre déclaration pour Grid :: InsertArray est correcte - elle prend un argument, qui est un tableau d'entiers 4x4. C’est appel par valeur: chaque fois que vous l’appelez, vous copiez votre tableau 4x4. Ainsi, les modifications que vous apportez ne sont pas reflétées dans le tableau transmis. Si vous préférez utiliser appel par référence, vous pouvez passez un pointeur sur un tableau à la place:

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

Ces déclarations de type avec des pointeurs sur des tableaux multidimensionnels peuvent être très déroutantes. Je recommande de faire un typedef pour cela comme ceci:

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

Ensuite, vous pouvez déclarer vos fonctions beaucoup plus lisibles:

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

Vous pouvez également utiliser le programme cdecl pour vous aider. déchiffrer des types C / C ++ compliqués.

Autres conseils

Il semble que vous deviez en savoir plus sur les pointeurs en C ++ et sur les passages par référence vs passage par valeur.

Votre méthode returnPiece est définie comme renvoyant la valeur d'une cellule unique. Étant donné l'index (par exemple, [4] [4]), vous renvoyez une copie du contenu de cette cellule. Par conséquent, vous ne pourrez pas le modifier, ou plus correctement, le changer modifierait la copie.

Je suis sûr que quelqu'un vous donnera la syntaxe correcte, mais je vous conseillerais vraiment d'apprendre cette matière, sinon vous risquez d'utiliser le code que vous obtenez de manière incorrecte.

Voici comment je le ferais:

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

Vous pouvez ensuite faire quelque chose comme:

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

Problème avec le arrayPtr d'Adam Rosenfield en ce que Piece :: pieceArray peut changer de vue. (Copie par référence vs Copie par valeur.)

La copie par valeur est inefficace. Mais si vous voulez vraiment le faire, il suffit de tricher:

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

Bien sûr, une meilleure solution, plus orientée objet, serait que returnPiece () crée et retourne une pièce ou un tableau . objet. (Comme Juan l'a suggéré ...)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top