Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Trójwymiarowe tablice dynamiczne

Ostatnio zmodyfikowano 2017-10-19 23:57
Autor Wiadomość
Matticzek
Temat założony przez niniejszego użytkownika
[C++] Trójwymiarowe tablice dynamiczne
» 2017-10-19 21:14:57
Witam. Zadeklarowanie samej tablicy 3D nie sprawia mi większego problemu

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

ale jak chcę potem przekazać taką tablicę do argumentu funkcji to jest jakaś katastrofa. Od znajomego usłyszałem aby robić jednowymiarową tablicę dynamiczną a potem bawić się na wskaźnikach. Chciałbym się dowiedzieć jak pracować na takich tablicach dynamicznych w funkcji i jak najlepiej je przekazywać.
P-165891
Kinexity
» 2017-10-19 21:50:19
Opisz problemy jakie występują po przekazaniu jako argument (a najlepiej wrzuć kod), bo nie rozumiem problemu.
P-165892
YooSy
» 2017-10-19 21:54:15
Napisać interfejs trójwymiarowej tablicy dla » Kurs STL, C++Kontener tablicy (std::vector) lekcja.
P-165893
Matticzek
Temat założony przez niniejszego użytkownika
» 2017-10-19 21:57:50
Problem polega na tym, że nawet nie wiem jak to robić, tak samo potem nie wiem jak działać na tej tablicy, z tego co wiem zamienia się ona w postać liniową.
P-165894
Kinexity
» 2017-10-19 22:12:55
Tablice wielowymiarowe są liniowe tylko wtedy, gdy umieszczasz je na stercie. Gdy alokujesz je na stosie najprawdopodobniej nie są liniowe. Aby przekazać je do funkcji musisz zrobić to przez wskaźnik (inaczej się nie da) i nie musisz martwić o dostęp do nich. Jedyny problem jaki napotkasz to próba np. przekopiowania całej wielowymiarowej tablicy dynamicznej, ale wszystko po kolei (nauczysz się z czasem).
P-165895
Matticzek
Temat założony przez niniejszego użytkownika
» 2017-10-19 22:26:39
Mam taką tablicę 200x200x200 nie sądzę aby na stosie się zmieściła, dlatego też używam dynamicznych bo na statycznych nawet zainicjować się takich nie da.
P-165896
mateczek
» 2017-10-19 22:53:53
wklej kod to się zobaczy co robisz źle, Bo takie gadanie "że się nie da" do niczego nie prowadzi.


 z tego co wiem zamienia się ona w postać liniową.

C/C++
int tab[ 3 ][ 3 ] // taka tablica znajduje się jako ciągły blok w pamięci


//tu już jest inna sprawa, nie ma mowy o liniowości
int ** tab = new * int[ 3 ]; //najpierw alokujesz tablice na wskaźniki
for( int i = 0; i < 3; i++ ) {
    tab[ i ] = new int[ 3 ]; //potem w pętli alokujesz normalne tablice 
}


Jeśli chcesz alokować całą tablicę jako jeden blok (w liniowej przestrzeni) wygodnie Ci będzie napisać klasę, i przeciążyć operator. Wtedy nie będziesz musiał być za każdym razem wyliczać na nowo elementu bo to łątwo o pomyłkę. Przeciążony operator ma za zadanie zwrócić referencję do żądanego elementu. Tym samym chodzi o napisanie interfejsu jak dla tablicy 2D, który de facto działa na tablicy 1D. W ten sposób uzyskasz to co nazwałeś jako "postać liniową"
C/C++
#include <iostream>
using namespace std;
class matrix {
    int * tab = nullptr;
    int wiersze = 0, kolumny = 0;
public:
    friend ostream & operator <<( ostream & s, matrix & m );
   
    matrix( int w, int k )
        : wiersze( w )
         , kolumny( k )
    {
        int rozmiar = w * k; //rozmiar macierzy 2D
        tab = new int[ rozmiar ]; //blok na macierz 2D
    }
   
    matrix() { } //konstruktor domyślny nic nie robi
    ~matrix() {
        if( tab ) {
            delete[] tab;
            tab = nullptr;
        }
    }
   
   
    int & operator ()( int w, int k ) {
        // 1 1 1 1 2 2 (-2-) 2 3 3 3 3 // tablica 3X4 widziana jako jeden blok
        //dla  w=1 k=2 szukany element oznaczyłem w tablicy (-2-)
        // współrzędna elementu to 1*4+2 = 6
        return tab[( w - 1 ) * kolumny + k - 1 ]; // rzeczony operator zwraca referencję na element określony numerem wiersza (w) i kolumny (k)
        // tutaj akurat indeksowanie od "1"; jeśli ktoś chce od "0" po prostu zastosować formułę jak poniżej
        //return tab[w * kolumny + k];       //indeksowanie od zera
    }
   
    int row() { return wiersze; }
    int column() { return kolumny; }
};

ostream & operator <<( ostream & s, matrix & m ) {
    for( int w = 1; w <= m.wiersze; w++ ) {
        for( int k = 1; k <= m.kolumny; k++ ) {
            s << m( w, k ) << " ";
        }
        s << endl;
    }
    return s;
}
int main() {
    matrix m1( 5, 5 ); //macierz 5 na 5
   
    //w - wiersze
    //k - kolumny
    for( int w = 1; w <= m1.row(); w++ ) {
        for( int k = 1; k <= m1.column(); k++ ) {
            m1( w, k ) = 1;
        }
    }
    cout << m1 << endl;
   
    return 0;
}

Pełniejszy kod, oczywiście dla macierzy 2D, Z operatorami mnożenia macierzy i kilkoma pomocniczymi konstruktorami (w tym konstruktory przenoszące) wrzuciłem kiedyś tutaj http://cpp0x.pl/forum/temat/​?id=23012
P-165897
Matticzek
Temat założony przez niniejszego użytkownika
» 2017-10-19 23:10:54
Nie da się bo jak robię int tab[200][200][200] to program się nie kompiluje, tzn. przestaje działać. Nie mam co wklejać, bo nie wiem jak przenieść tę tablicę do funkcji.
P-165898
« 1 » 2
  Strona 1 z 2 Następna strona