Tableaux dynamiques, comment faire proprement et efficacement

Contenu du snippet

Voici l'ABC de faire des tableaux dynamiques je crois que ça se passe assez de commentaire puisqu'ils sont nombreux dans le code. C'est un application console, le main est là simplement comme démo, tout ce qui importe se passe dans les fonctions

have fun

Source / Exemple :


#include "stdafx.h"
#include <stdio.h>
#include <conio.h>

//toutes les fonctions...
int* AllouerVecteur(int Nb_Element);
void AllouerVecteurDansBuffer(int **pVec,int Nb_Element,int* &buffer);
void AllouerTableau2D(int ***pTab,int Nb_Element_X,int Nb_Element_Y);
void AllouerTableau3D(int ****pTab,
                      int Nb_Element_X,
                      int Nb_Element_Y,
                      int Nb_Element_Z);

void DetruireVecteur(int **pVec);
void Detruire_Tableau2D(int **pTab);
void Detruire_Tableau3D(int ***pTab);

int main(int argc, char* argv[])
{
   //on va créer un tableau 2D dynamiquement de 10 * 10
   int x = 10, y = 10,z=10;//les dimensions des tableau
   int **Tab;//notre tableau 2D;
   int ***Tab3D;

   AllouerTableau2D(&Tab,x,y);
   
   //on va remplir ça
   int i,j,k;
   for(i=0;i<x;i++)
   {
      for(j=0;j<y;j++)
      {
         Tab[i][j] = (i*10)+j;
      }
   }
   //on va l'afficher...
   for(i=0;i<x;i++)
   {
      for(j=0;j<y;j++)
      {
         printf("%d\t",Tab[i][j]);
      }
      printf("\n");
   }
   printf("voici votre tableau 2D, appuyez sur un touche pour passer au 3D");

      
   //on va le détruire
   Detruire_Tableau2D(Tab); 
   _getch();

   //maintenant on va créer un tableau 3d
   AllouerTableau3D(&Tab3D,x,y,z); 
 //on va remplir ça
   for(i=0;i<x;i++)
   {
      for(j=0;j<y;j++)
      {
         for(k=0;k<z;k++)
         {
            Tab3D[i][j][k] = (i*100)+(j*10)+k;
         }
      }
   }

   //on va l'afficher...
   for(i=0;i<x;i++)
   {
      //un clear screen cheap
      printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
      for(j=0;j<y;j++)
      {
         for(k=0;k<z;k++)
         {
            printf("%d\t",Tab3D[i][j][k]);
         }
         printf("\n");
      }
      printf("\npage %d\n",i);
      _getch(); 
   }

   Detruire_Tableau3D(Tab3D); 

  

	return 0;
}
/***************************************************************************
//int* AllouerVecteur(int Nb_Element)
//
//Cette fonction est un bel exemple de fonction pour rien, en effet elle 
//encapsule le new sans rien y apporter de nouveau.  Par contre je l'ai mise
//ici juste pour montrer la graduation au fur et a mesure que nos fonctions 
//travaillent avec un grand nombre de dimensions.
//

                                                                                                                                                      • /
int* AllouerVecteur(int Nb_Element) { return new int[Nb_Element]; } /*************************************************************************** //void AllouerVecteurDansBuffer(int **pVec,int Nb_Element,int* &buffer) // //Une autre fonction qui sert à rien, mais celle ci explique le principe //d'allouer un petit vecteur à partir d'un grand. Ici on reçoit en paramètre //un buffer et une référence sur un vecteur. On utilise le buffer, au lieu du //new pour allouer notre vecteur. L'intérêt est que lorsque l'on alloue des //tableau avec ça on peut ensuite parcourir les tableau comme des vecteurs ou //encore utilisé les braquettes. Bref, le tableau devient INDISCERNABLE d'un //tableau statique
                                                                                                                                                      • /
void AllouerVecteurDansBuffer(int **pVec,int Nb_Element,int* &buffer) {
  • pVec = buffer;
//on incrémente le buffer buffer = buffer + Nb_Element; } /*************************************************************************** //void AllouerTableau2D(int ***pTab,int Nb_Element_X,int Nb_Element_Y) // //Bon ici commence la vraie grosse job de bras, en premier on va allouer un //gros buffer contenant le nombre d'élément désiré dans notre tableau. Ensuite //on se crée un vecteur de pointeur d'entier. Pour chacune des position de ce //vecteur on référence un SEGMENT de notre gros buffer. Ainsi notre tableau //est créer. (*pTab)[0][0] pointe alors sur l'élément 0,0 et //(*pTab)[Nb_Element_X-1][Nb_Element_Y-1] est le dernier element. Comme notre //allocation s'est fait à partir de buffer on sait que //&(*pTab)[0][0] + ((Nb_Element_X-1)*(Nb_Element_Y-1)) est encore le dernier //élément, bref son comportement est identique à celui d'un tableau statique.
                                                                                                                                                      • /
void AllouerTableau2D(int ***pTab,int Nb_Element_X,int Nb_Element_Y) { int i=0; int *Vect_Buffer; //on alloue tout le tableau comme s'il était un vecteur; Vect_Buffer = AllouerVecteur(Nb_Element_X*Nb_Element_Y); //on alloue un vecteur de pointeur
  • pTab = new int*[Nb_Element_X];
//pour chaque élément de notre vecteur de pointeur for(i=0;i<Nb_Element_X;i++) { //on référence à une section de notre buffer (*pTab)[i] = Vect_Buffer; //on incrément notre référence sur le buffer Vect_Buffer = Vect_Buffer + Nb_Element_Y; } } /*************************************************************************** //void AllouerTableau3D(int ****pTab, // int Nb_Element_X, // int Nb_Element_Y, // int Nb_Element_Z) // //Si vous avez bien compris le 2D vous allez voir c'est pareil. En premier on //alloue un buffer d'entier du nombre total d'entier de notre tableau. // //ensuite on alloue un buffer de pointeur d'entier du nombre total de pointeur //d'entier que le tableau va avoir // //ensuite on crée la base de notre tableau 3D c'est à dire un vecteur de //pointeur de pointeur. Le reste expliqué dans le code...
                                                                                                                                                      • /
void AllouerTableau3D(int ****pTab, int Nb_Element_X, int Nb_Element_Y, int Nb_Element_Z) { int i=0; int j=0; int *Vect_Buffer; int **Buffer_Pointeur; int **Curseur; //on alloue tout le tableau comme s'il était un vecteur; Vect_Buffer = AllouerVecteur(Nb_Element_X*Nb_Element_Y*Nb_Element_Z); //ensuite on s'alloue un vecteur de pointeur de int Buffer_Pointeur = new int*[Nb_Element_X*Nb_Element_Y]; Curseur = Buffer_Pointeur; //ensuite on alloue un vecteur de pointeur de pointeur qui représente la //première couche de notre tableau (*pTab) = new int**[Nb_Element_X]; //maintenant pour tout les pointeur de pointeur que l'on trouve à *pTab, //on leur assigne un petit vecteur de pointeur qui se trouve à être un //segment de notre buffer de pointeur for(i=0;i<Nb_Element_X;i++) { (*pTab)[i] = Curseur; Curseur = Curseur + Nb_Element_Y; //ensuite on va allouer un petit vecteur de int à chacun de nos //pointeur de int for(j=0;j<Nb_Element_Y;j++) { (*pTab)[i][j] = Vect_Buffer; Vect_Buffer = Vect_Buffer + Nb_Element_Z; } } //voilà notre tableau 3D est terminé. } /*************************************************************************** //void DetruireVecteur(int *pVec) // //Cette fonction ne fait rien de plus qu'un delete, elle est là simplement pour //mettre en évidence la suppression lorsque l'on monte en nombre de dimensions // // //
                                                                                                                                                      • /
void DetruireVecteur(int *pVec) { delete pVec; } /*************************************************************************** //void Detruire_Tableau2D(int **pTab) // //Cette fonction fait la suppression d'un tableau à deux dimension, il importe //de bien désalouer le tableau, alors on supprimer toujours de l'élément puis //son pointeur donc on supprime en premier tout les éléments "int" puis ensuite //on supprimer tout les éléments "int*" et c'est terminé. // //vous devez voir le tableau 2D comme un vecteur de vecteur d'entier. Donc en //premier lieu on supprimer les vecteurs d'entier ce que fait le premier delete //mais comme nous avons alloué la totalité des entiers en une seule operation //nous les supprimons en une seule operation. // //ensuite on supprime le vecteur de référence sur des vecteurs, Il importe //beaucoup de comprendre cet exemple, sinon attachez votre tuque avec de la //broche pis serré à part ça le 3D s'en vient
                                                                                                                                                      • /
void Detruire_Tableau2D(int **pTab) { delete pTab[0]; delete pTab; } /*************************************************************************** //void Detruire_Tableau3D(int ***pTab) // //bon on considère notre tableau 3D comme étant trois vecteurs, un vecteur qui //lui contient des vecteurs qui eux contiennent des entiers. On procède comme //avec le 2D, on supprimer les entiers, puis les références sur les entiers, //puis les références sur les références des entiers. et voilà c'est tout. //
                                                                                                                                                      • /
void Detruire_Tableau3D(int ***pTab) { delete pTab[0][0]; delete pTab[0]; delete pTab; }

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.