2010-10-11 16 views
13

Jestem nowy w C/C++ i byłem pękanie głowę, ale wciąż mam pojęcia jak to zrobić "strukturę" jak totablica 3D C++ przy użyciu int [] operator

alt text

Powinien to być dynamiczna tablica 3D wykorzystująca wskaźniki.

zacząłem tak, ale utknął tam

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

byłoby na tyle, aby wiedzieć, jak to zrobić dla statycznego wielkości Y i Z;

Bardzo proszę, pomóż mi.

Z góry dziękuję.

Odpowiedz

19

Aby utworzyć dynamicznie tablicę 3D z liczb całkowitych, lepiej najpierw zrozumieć tablice 1D i 2D.

1D tablicę: Można to zrobić bardzo łatwo przez

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

Tutaj tworzysz INT-wskaźnik, który będzie wskazywał na fragmencie pamięci, gdzie mogą być przechowywane całkowitymi.

Tablica 2D: Możesz użyć rozwiązania powyższej tablicy 1D do utworzenia tablicy 2D. Najpierw utwórz wskaźnik, który powinien wskazywać na blok pamięci, w którym przechowywane są tylko inne wskaźniki całkowite, które ostatecznie wskazują na rzeczywiste dane. Ponieważ nasz pierwszy wskaźnik wskazuje na tablicę wskaźników, zostanie to nazwane jako wskaźnik do wskaźnika (podwójny wskaźnik).

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 Array: To jest to, co chcesz robić. Tutaj możesz wypróbować oba schematy użyte w powyższych dwóch przypadkach. Zastosuj tę samą logikę co tablica 2D. Omawiany diagram wyjaśnia wszystko. Pierwsza tablica będzie wskaźnikiem do wskaźnika do wskaźnika (int *** - ponieważ wskazuje na podwójne wskaźniki). Rozwiązanie jest następujące:

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

Możesz również użyć tej metody dla tablic N-Dimension z N-1 dla pętli. –

+7

może wspomnieć o odpowiedniej funkcji usuwania również .. – stijn

+0

@Manish Shukla W kodzie 3D Array, który z X, Y i Z oznacza szerokość, wysokość i głębokość? – Mariya

0

OK weźmy wasze początki

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

s jest teraz tablica int ** S o długości x, więc teraz jestem po prostu zamiar skupić się na tworzeniu element zeroeth być co chcesz

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

teraz s [0] wskazuje na tablicę int * S o długości r, teraz wystarczy, aby dostać ostatni kawałek drzewa zrobione, więc

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

I wreszcie dostać je w formie diagramu

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

To wydaje się trochę jak pytanie zadanie domowe, upewnij się, że rzeczywiście zrozumieć odpowiedź i dlaczego to działa.

+0

'sec' nie jest tablicą. Jest to wskaźnik wskazujący na pierwszy element tablicy. – sellibitze

+0

To jest raczej semantyczne. Aby być sprawiedliwym w przypadkach takich jak int x [10]; x jest tak naprawdę wskaźnikiem do pierwszego elementu tablicy i do tablicy. Tak naprawdę nie ma różnicy między byciem wskaźnikiem do pierwszego elementu tablicy a byciem tablicą. –

1

Można spróbować:

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

A kiedy są wykonywane przy użyciu tej pamięci można cofnąć przydział jako:

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; 

(jest to oznaczone C++, po wszystkich)

EDYCJA w odpowiedzi na pytanie Joe'a

cześć jeszcze raz Joe =) pewnie. oto przykład:

#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 dla sposobu, w jaki można przejść * jeśli * ten układ pamięci jest rzeczywiście tym, co OP chce – sellibitze

1

Kompleksowe odpowiedzi.

Jeśli naprawdę piszesz to w C++ (nie jest to surowe C), powinieneś rzucić okiem na tę skomplikowaną strukturę danych. Przeprojektowanie IMO, mając na uwadze to, co próbujesz zrobić, byłoby lepsze.

1

Co próbujesz zrobić, nie jest idiomatyczne w C++. Oczywiście, możesz może użyć do tego celu int***pointer, ale jest to zdecydowanie odradzane. W C++ mamy lepsze sposoby, aby się tam dostać.

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

Spowoduje to coś z układem pamięci podobny do tego, co prosiliśmy. Obsługuje dynamiczne zmiany rozmiaru i wewnętrzne wektory, aby mieć różne rozmiary, tak jak na zdjęciu. Ponadto nie musisz się martwić ręcznym przydzielaniem/usuwaniem któregokolwiek z nich. Również wektory znają swój rozmiar, więc nie musisz go gdzieś zapamiętywać.

Ale jeśli chcesz tylko "prostokątnej" tablicy 3D, w której wszystkie elementy są kolejno przechowywane w tym samym bloku pamięci, możesz użyć boost::multiarray.