2010-10-11 28 views
13

Je suis nouveau à C/C++ et j'ai fissuration ma tête, mais encore eu aucune idée de comment faire une « structure » comme celui-citableau 3D C++ en utilisant int [] opérateur

alt text

C'est supposé être un tableau dynamique en 3D utilisant des pointeurs.

j'ai commencé comme ça, mais nous avons eu coincé là-bas

int x=5,y=4,z=3; 
    int ***sec=new int **[x]; 

Il suffit de savoir comment faire pour une taille statique de y et z;

S'il vous plaît, j'apprécierais que vous m'aidiez.

Merci d'avance.

Répondre

19

Pour créer dynamiquement un tableau 3D d'entiers, mieux vaut d'abord comprendre les tableaux 1D et 2D.

tableau 1D: Vous pouvez le faire très facilement par

const int MAX_SIZE=128; 
int *arr1D = new int[MAX_SIZE]; 

Ici, nous créons un pointeur int qui pointera vers un morceau de mémoire où les entiers peuvent être stockés.

Tableau 2D: Vous pouvez utiliser la solution du tableau 1D ci-dessus pour créer un tableau 2D. Tout d'abord, créez un pointeur qui doit pointer vers un bloc de mémoire où sont uniquement stockés d'autres pointeurs entiers qui pointent finalement vers des données réelles. Puisque notre premier pointeur pointe vers un tableau de pointeurs, cela sera appelé pointer-to-pointer (double pointeur).

const int HEIGHT=20; 
const int WIDTH=20; 

int **arr2D = new int*[WIDTH]; //create an array of int pointers (int*), that will point to 
           //data as described in 1D array. 
for(int i = 0;i < WIDTH; i++){ 
     arr2D[i] = new int[HEIGHT]; 
} 

3D Tableau: Voici ce que vous voulez faire. Ici, vous pouvez essayer les deux schémas ci-dessus. Applique la même logique que le tableau 2D. Le diagramme en question explique tout. Le premier tableau sera pointer-pointer-vers-pointeur (int *** - puisqu'il pointe vers des pointeurs doubles). La solution est la suivante:

const int X=20; 
const int Y=20; 
const int z=20; 

int ***arr3D = new int**[X]; 
for(int i =0; i<X; i++){ 
    arr3D[i] = new int*[Y]; 
    for(int j =0; j<Y; j++){ 
     arr3D[i][j] = new int[Z]; 
     for(int k = 0; k<Z;k++){ 
      arr3D[i][j][k] = 0; 
     } 
    } 
} 
+0

Vous pouvez également utiliser cette méthode pour les tableaux N-Dimension avec N-1 pour les boucles. –

+7

peut-être mentionner la fonctionnalité de suppression correspondante ainsi .. – stijn

+0

@Manish Shukla Dans le code 3D Array qui de X, Y et Z représente Largeur, hauteur et profondeur ?? – Mariya

0

OK prenons vos débuts

int ***sec = new int**[x]; 

sec est maintenant un tableau de s int ** de longueur x, alors maintenant je vais juste se concentrer sur faire l'élément zeroeth ce que vous voulez

sec[0] = new int*[y]; 

maintenant sec [0] points au tableau de int * s de longueur y, maintenant besoin juste pour obtenir le dernier morceau de l'arbre fait, si

sec[0][0] = new int[z]; 

Et enfin pour obtenir la forme dans votre diagramme

sec[0][0][z-1] = 0; 

Cela ne semble un peu comme une question de devoirs, assurez-vous réellement comprendre la réponse et pourquoi cela fonctionne.

+0

'sec' n'est pas un tableau. C'est un pointeur qui pointe vers le premier élément d'un tableau. – sellibitze

+0

C'est plutôt sémantique. Pour être juste dans des cas comme int x [10]; x est vraiment un pointeur vers le premier élément d'un tableau, et un tableau à la fois. Il n'y a vraiment pas de différence entre être un pointeur sur le premier élément d'un tableau et être un tableau. –

1

Vous pouvez essayer:

for(int i=0;i<x;i++) { 
    sec[i] = new int *[y]; 
    for(int j=0;j<y;j++) { 
    sec[i][j] = new int [z]; 
    } 
} 

Et une fois que vous avez fini d'utiliser cette mémoire, vous pouvez désaffecter comme:

for(int i=0;i<x;i++) { 
    for(int j=0;j<y;j++) { 
    delete [] sec[i][j]; 
    } 
    delete [] sec[i]; 
} 
delete [] sec; 
11
// one-liner 
typedef std::vector<std::vector<std::vector<int> > > ThreeDimensions; 
// expanded 
typedef std::vector<int> OneDimension; 
typedef std::vector<OneDimension> TwoDimensions; 
typedef std::vector<TwoDimension> ThreeDimensions; 

(c'est marqué C++, après tout)

EDIT en réponse à la question de Joe

Bonjour à nouveau Joe =) bien sûr. voici l'exemple:

#include <vector> 
#include <iostream> 

int main(int argc, char* const argv[]) { 

    /* one-liner */ 
    typedef std::vector<std::vector<std::vector<int> > >ThreeDimensions; 
    /* expanded */ 
    typedef std::vector<int>OneDimension; 
    typedef std::vector<OneDimension>TwoDimensions; 
    typedef std::vector<TwoDimensions>ThreeDimensions; 

    /* 
     create 3 * 10 * 25 array filled with '12' 
    */ 
    const size_t NElements1(25); 
    const size_t NElements2(10); 
    const size_t NElements3(3); 
    const int InitialValueForAllEntries(12); 

    ThreeDimensions three_dim(NElements3, TwoDimensions(NElements2, OneDimension(NElements1, InitialValueForAllEntries))); 

    /* the easiest way to assign a value is to use the subscript operator */ 
    three_dim[0][0][0] = 11; 
    /* now read the value: */ 
    std::cout << "It should be 11: " << three_dim[0][0][0] << "\n"; 
    /* every other value should be 12: */ 
    std::cout << "It should be 12: " << three_dim[0][1][0] << "\n"; 

    /* get a reference to a 2d vector: */ 
    TwoDimensions& two_dim(three_dim[1]); 

    /* assignment */ 
    two_dim[2][4] = -1; 
    /* read it: */ 
    std::cout << "It should be -1: " << two_dim[2][4] << "\n"; 

    /* get a reference to a 1d vector: */ 
    OneDimension& one_dim(two_dim[2]); 

    /* read it (this is two_dim[2][4], aka three_dim[1][2][4]): */ 
    std::cout << "It should be -1: " << one_dim[4] << "\n"; 
    /* you can also use at(size_t): */ 
    std::cout << "It should be 12: " << one_dim.at(5) << "\n"; 

    return 0; 
} 
+0

+1 pour le chemin à suivre * si * cette disposition de la mémoire est vraiment ce que l'OP veut – sellibitze

1

Des réponses complètes.

Si vous écrivez réellement ceci en C++ (pas brut C), je pense que vous devriez jeter un autre regard sur cette structure de données compliquée. La refonte de l'OMI tout en gardant à l'esprit ce que vous essayez de faire serait mieux.

1

Ce que vous essayez de faire n'est pas idiomatique en C++. Bien sûr, vous pouvez utiliser un int***pointer pour cela, mais cela est fortement déconseillé. En C++, nous avons de meilleurs moyens d'y arriver.

vector<vector<vector<int> > > foo (5,vector<vector<int> >(4, vector<int>(3))); 

Cela se traduira par quelque chose avec la disposition de la mémoire similaire à ce que vous avez demandé. Il prend en charge le redimensionnement dynamique et les vecteurs internes pour avoir différentes tailles comme dans votre image. En outre, vous n'avez pas à vous inquiéter de l'allocation/suppression manuelle de tout cela. De plus, les vecteurs connaissent leur taille, donc vous n'avez pas à vous en souvenir quelque part. Mais si vous voulez juste un tableau 3D "rectangulaire" où tous les éléments sont stockés consécutivement dans le même bloc de mémoire, vous pouvez utiliser un boost::multiarray.