Mehrdimensionale Arrays an Funktionen übergeben



  • Abend,
    ich versuche zurzeit ein kleines Soduko Spiel zu schreiben. Dabei verwende ich mehrdimensionale Arrays und diese würde ich gerne an Funktionen übergeben. Ich weiß aber mittlerweile einfach nicht mehr weiter. Ich hab so ziemlich alles an Kombinationen ausprobiert, jetzt bin ich bei 'Call by Pointer' hängen geblieben. Ich hab in einigen Foren gelesen, dass es so funktionieren soll. Ich bekomme es aber nicht hin.
    Daher: Könnt ihr da einfach mal drüber schauen und mir helfen?

    #include <iostream>
    #include <conio.h>
    
    using namespace std; 
    
    ////////////////////////////// Feld einlesen ///////////////////////////////////
    void feld_einlesen(int *z_ma1[9][9])
    {   
        //Zahlen einlesen
        //Zeile 1 
        *z_ma1[0][0]= 5; 
        *z_ma1[0][3]= 6; 
        *z_ma1[0][6]= 3;
        *z_ma1[0][8]= 2;
        //Zeile 2
        *z_ma1[1][3]= 2; 
        *z_ma1[1][6]= 8; 
        //Zeile 3
        *z_ma1[2][0]= 2;
        *z_ma1[2][1]= 8; 
        *z_ma1[2][2]= 1; 
        *z_ma1[2][5]= 3; 
        *z_ma1[2][6]= 4; 
        //Zeile 4
        *z_ma1[3][2]= 3; 
        *z_ma1[3][7]= 2; 
        *z_ma1[3][7]= 7; 
        //Zeile 5 
        *z_ma1[4][4]= 4; 
        //Zeile 6
        *z_ma1[5][0]= 6; 
        *z_ma1[5][1]= 5; 
        *z_ma1[5][6]= 1; 
        //Zeile 7
        *z_ma1[6][2]= 6; 
        *z_ma1[6][3]= 1; 
        *z_ma1[6][6]= 2; 
        *z_ma1[6][7]= 9; 
        *z_ma1[6][8]= 5; 
        //Zeile 8 
        *z_ma1[7][2]= 5; 
        *z_ma1[7][5]= 8; 
        //Zeile 9
        *z_ma1[8][0]= 1; 
        *z_ma1[8][2]= 9; 
        *z_ma1[8][5]= 2; 
        *z_ma1[8][8]= 4;  
    }
    ////////////////////////////// Feld ausgeben ///////////////////////////////////
    void feld_ausgeben(int *z_ma1[9][9])
    {
        //Variablen 
        int z_counter=0, s_counter=0; 
    
        //Feld ausgeben 
        for (int i=0; i<9; i++) 
            for (int k=0; k<9; k++)
            {
                    /*if (z_counter == 3)
                    {
                            cout<<"-----------------------------------"; 
                            z_counter = 0; 
                    }
                    */
                    if (s_counter == 3 || s_counter == 6)
                    {
                            cout<<"|"; 
                    }  
                    if (s_counter == 9)
                    {
                            cout<<endl; 
                            s_counter = 0; 
                    }
                    cout<<" "<<*z_ma1[i][k]<<" "; 
    
                    //Counter hochzählen
                    z_counter++;
                    s_counter++;
            }
    }
    ////////////////////////////// Hauptprogramm ///////////////////////////////////
    int main()  
    {        
        //Variablen 
        int ma1[9][9], *z_ma1[9][9]; 
    
        //Feld einlesen lassen 
        feld_einlesen(&ma1[9][9]);   
    
        //Feld ausgeben lassen 
        feld_ausgeben(&ma1[9][9]);  
    
        //Beenden 
        getch(); 
    }
    


  • Phu.. Wo soll man den da Anfangen. 🙂

    Setzt dich mal ein wenig mit den Grundsätzen von mehrdimensionalen Arrays auseinander.
    http://www.softgames.de/developia/viewarticle.php?cid=19547

    Sieht auch vielversprechend aus:
    http://de.wikibooks.org/wiki/C%2B%2B-Programmierung:_Arrays#Mehrere_Dimensionen

    Das sollte mal reichen. Wenn danach immernoch unklarheiten sind, einfach Fragen oder in google mehr zu der Thematik suchen.

    EDIT:
    Hier mal eine kleine Motivation. Arrays werden nie per value übergeben. Sondern immer Referenz. Solange die Dimensionen des Arrays (bei Compilierzeit) bekannt sind, ist es ganz einfach.

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    ////////////////////////////// Feld einlesen ///////////////////////////////////
    void feld_einlesen(int z_ma1[9][9])
    { }
    ////////////////////////////// Feld ausgeben ///////////////////////////////////
    void feld_ausgeben(int z_ma1[9][9])
    {
    }
    ////////////////////////////// Hauptprogramm ///////////////////////////////////
    int main()  
    {        
        //Variablen
        int ma1[9][9], *z_ma1[9][9];
    
        //Feld einlesen lassen
        feld_einlesen(ma1[9][9]);  
    
        //Feld ausgeben lassen
        feld_ausgeben(ma1[9][9]);  
    
        //Beenden
        getch();
    }
    


  • void feld_einlesen(int *z_ma1[9][9])
    

    wenn du das so schreibst sagst du z_mal ist ein 2 dimensionales array aus pointer auf integer (welche potenziell auch wieder auf arrays zeigen können)

    bei arrays in c/cpp ist das so

    const int ARRAY_SIZE = 5;
    
    //du hast ein array mit fixer größe so definiert
    int integerArrayFixedSize[ARRAY_SIZE];
    
    //du allokierst ein array
    int *integerArrayPointer = new int[ARRAY_SIZE];
    
    //wir müssen den speicher hier wieder freigeben am ende
    delete [] integerArrayPointer ;
    
    //grundsätzlich ist es so dass wenn man ein array hat der einfache name der
    //variable bereits ein pointer ist, also können wir auch das machen
    
    integerArrayPointer = integerArrayFixedSize; //jetzt ist integerArrayPointer gleichzusetzen mit integerArrayFixedSize
    
    // im speicher sieht das so aus
    // 
    // 
    // integerArrayFixedSize     |---->     0 1 2 3 4 5
    // integerArrayPointer ------|
    //
    // das ist so zu interpretieren dass diese 5 integer beginnend mit der adresse
    // von integerArrayFixedSize im speicher stehen
    // integerArrayPointer zeigt aber auch einfach auf denselben speicherbereich
    // in diesem fall muss und kann man den speicher mit delete nicht freigeben
    
    //dasselbe würde passieren wenn du eine referenz auf einen zeiger speicherst
    int *&integerRefereceToPointer = (int *&)integerArrayFixedSize;
    //oder auch
    integerReferenceToPointer = integerArrayPointer;
    
    //allerdings sind referenzen zu pointern .. ka ich habs noch nie verwendet eig.
    
    //und letzten endes, musst du natürlich kein array erstellen 
    //du kannst auch einfach sowas machen
    
    int *integerPointer = new int;
    delete integerPointer;
    
    //in dem fall zeigt der integer pointer nicht auf ein array sondern auf
    //einen einzelnen integer, im kann man nicht sagen wo ein pointer hin zeigt
    //in c++ (array, einzelner wert, speichermüll)
    //alles was ein pointer sagt ist dass der speicher beginnend mit der adresse
    //des pointers als ein xyz interpretiert wird
    

    ok das deckt mal denk ich so mehr oder weniger die basics ab ein bisschen

    in deinem fall jetzt würd ich einfach mal vorschlagen sowas zu machen

    //in der main
    
    //gameField ist somit vom typ int ** (ein pointer auf ein array welches wieder
    //int pointer enthält
    int gameField[GAME_FIELD_DIMENSION][GAME_FIELD_DIMENSION];
    
    //du musst dir das so vorstellen
    
    // gameField 
    //    0 ------------> gameField[0]    0 1 2 3
    //    1 ------------> gameField[1]    0 1 2 3
    //    2 ------------> gameField[2]    0 1 2 3
    //    3 ------------> gameField[3]    0 1 2 3
    

    also jeder index aus gameField zeigt auf einen integer pointer welcher wiederrum ein array ist das 5 elemente hat

    über

    int *gameFieldRow = gameField[0];
    

    holst du dir dann zb die erste zeile des spielfelds (oder letzte / oder spalte, je nachdem wie du es interpretieren willst in deinem programm)

    und über

    int gameFieldUnit = gameFieldRow [0];
    

    holst du dir von der ersten zeile das erste element, das wäre also das linke obere sudoku raster feld

    natürlich kannst du das auch zusammenfassen in einem

    int gameFieldUnit = gameField[row][column];
    

    und wenn du das spielfeld einer methode übergeben willst dann übergibst du es einfach (es ist vom typ int[GAME_FIELD_DIMENSION][GAME_FIELD_DIMENSION] wie wir gesagt haben - was gleichzusetzen ist mit int **) über

    void DoSomethingWithMyGameField(int aGameField[GAME_FIELD_DIMENSION][GAME_FIELD_DIMENSION])
    

    oder

    void DoSomethingWithMyGameField(int **aGameField)
    

    wobei ich dir empfehlen würde variante 1 zu verwenden weil - obwohl du ja weisst dass bei variante 2 (int **) aGameField ein array ist mit X zeilen und X spalten könnte es theoretisch auch 5 zeilen haben die jeweils 3, 1, 5, 6, 6 spalten haben
    mit variante 1 gehst du über die syntax mehr oder weniger einen vertrag mit dem compiler ein und sagst ihm (und allen anderen programmierern die dein programm lesen) sofort was genau der parameter ist


Anmelden zum Antworten