pointer 2 dimensionales array



  • Die Startadressen vom ersten int[10]-Array und vom ersten int sind natürlich "zufällig" die gleichen. 😉



  • AbsoluterBeginner schrieb:

    entweder ich verstehe es falsch aber du meinst hier

    aa != &(square[0][0])
    

    aber mein erster code zeigt das dies das selbe ist (durch die ausgabe der adressen) also adresse gleich auch gleiches element...

    Da ein int[10]* nicht das gleiche ist, wie ein int* geht die Zuweisung nicht.

    ich verstehe nicht was mit int[10]* für ein typ ist ist, auch ein int array das 10 pointer auf int beinhalten kann?

    fragen ueber fragen 🙂

    update zu vorerigem post haha ich bin ein trottel 😉 danke!

    Es kommt auf dasselbe raus, wenn du es castest. Es ist "lediglich" ein Typproblem, auf das dich der Compiler hinweist.

    int[10]* a;
    

    liest sich:
    a ist ein Zeiger auf ein Array von 10 ints.

    EDIT:
    I-net ist hier wirklich saulahm.. Beim letzen aktualisieren waren die letzen 2 Posts noch nicht da..
    @Tachyon:
    Sorry für Wiederholung.. 😉



  • _matze schrieb:

    Die Startadressen vom ersten int[10]-Array und vom ersten int sind natürlich "zufällig" die gleichen. 😉

    hae? 🙂

    Tachyon schrieb:

    Wir bauen das int[10][10] mal von Hand:

    danke fuer den code.
    also ist es nicht moeglich mit einem normalen int pointer das komplette array zu durchlaufen, sollte schon oder?
    also zb:

    int *p = &(square[0][0]);
     for(int i = 0; i < 100; i+=10)
      cout << p+i << endl;
    

    liefert selben output wie vorhin, aber wie zeige ich auf die adresse des ersten int[10] wertes ohne

    &(square[0][0])
    

    denn array indizes soll ich vermeiden...



  • Nochmal als Nachtrag:
    Der Compiler kann viele Dinge selbst umwandeln. Das setzt aber voraus, dass er auch eine passende Umwandlung dafür kennt.

    int a[10];
    int* pa = a; //hierfuer kennt der Compiler eine Umwandlung, obwohl int* NICHT das gleiche ist, wie int[10]
    
    int aa[10][10];
    int* paa = aa; //hierfür hat der Compiler keine Umwandlung parat, deshalb gibt es einen Fehler.
    int* paa2 = &(aa[10][10]); //hier machst Du selbst eine Umwandlung in den passenden Typen.
    
    //anderes Beispiel ohne Arrays:
    int i = 10;
    float f = i; //hiefür kennt der Compiler eine Umwandlung und wandelt int -> float
    std::string s = i; //Fehler: Hierfür gibts keine Umwandlung
    


  • aaah langsam glaube ich es zu verstehen 😃
    also nicht moeglich auf das erste element des 2dim arrays zu zeigen ohne selbst umzuwandeln und somit die indizes ([0][0]) brauche?

    wage mich mal weiter im code, mal sehen ob ich es schaffe 🙂

    echt vielen dank, pointer dacht ich sind halbwegs klar, aber in verbindung mit arrays brauch ich noch denke ich 🙂



  • lange hats nicht gebraucht 😉
    also ich soll das array jetzt initialisieren.
    mit lauter nullen, in der diagonale 1, aber im mom nicht das problem.
    mein problem ist, dass ich nur zwei zusaetzliche pointer variablen verwenden darf, welche jeweils in den zwei for schleichen verwendet werden.

    //bp code
    
    for(int *p1;....)
    {
      for(int *p2;....)
    
    }
    

    moeglich sollte es ja sein, alles ist moeglich ^^

    ich habe mal auf funktionen versichter und versuche alles in einer main zu machen, hier mein code:

    int main()
    {
     int square[10][10];
     int (*row)[10] = square; //save all ten row addresses in this array
    
      //show the addresses of each row (works!)
      for(int i = 0; i < 10; ++i)
     	cout << *(row+i) << endl; 
      //distance is exactly 28hex (40dec) 
      //which is 10times a int per row
    
     //nun will ich hier mit einem pointer das selbe machen
     for(int *rw = *row; *rw; rw += 10)
     {
      cout << "RW: " << rw << endl;
     }
     cout << endl;
     return 0;
    }
    

    output:

    0x22cb50
    0x22cb78
    0x22cba0
    0x22cbc8
    0x22cbf0
    0x22cc18
    0x22cc40
    0x22cc68
    0x22cc90
    0x22ccb8
    RW: 0x22cb50
    RW: 0x22cb78
    RW: 0x22cba0
    RW: 0x22cbc8

    warum wird hier gestoppt?!
    mein gedanke zu der for schleife:

    for(int *rw = *row; *rw; rw += 10)
    

    einen pointer auf ein int. dieser zeigt auf das erste element der ersten zeile.
    ich mache es so lange so lange der pointer auf etwas zeigt, zuerst hatte ich die bedenken dass es weiter geht also bis ans ende des array, weil es kann ja sein, dass im speicher nach dem array zufaellig weitere ints gespeichert sind oder?
    aber er hoert zu frueh auf, was mir nicht eingeht 🙂

    ist mein gedanke ueberhaupt richtig ein array auf diese art mit pointern durchzugehen?

    kann ja nicht sein dass ich es einfach nicht begreifen kann 😞



  • Ne. Normalerweise gehst du da über den Index rein.

    for (int y ..
       for (int x ..
        a[y*width+x] = 2;
    ...
    


  • aber irgend eine moeglichkeit es mit pointern zu machen muss es doch gebn, sonst wuerde es mein prof nicht verlangen 😃

    btw. width ist die dimension des arrays oder was meinst du damit?



  • AbsoluterBeginner schrieb:

    aber irgend eine moeglichkeit es mit pointern zu machen muss es doch gebn, sonst wuerde es mein prof nicht verlangen 😃

    btw. width ist die dimension des arrays oder was meinst du damit?

    Doch, doch. Geht schon, aber ist nicht üblich sich da unnötigerweise mit Pointern zu verrenken, wenn man das elegant über den Index machen kann. 😉

    Ich persönlich finde es unsinnig das unbedingt per Zeigernotation zu lösen. Das ist einfach nur unleserlich und unintuitiv. Vor allem kannst du den Indexzugriff ja ganz einfach auf Zeigernotation umwandeln. Das so in der Schleife zu machen finde ich auch nicht wirklich gut.



  • AbsoluterBeginner schrieb:

    aber irgend eine moeglichkeit es mit pointern zu machen muss es doch gebn...

    const size_t xDim = 10;
    const size_t yDim = 10;
    int a[xDim][yDim];
    for(int *iter(&(a[0][0])), *end(iter + xDim + yDim); iter != end; ++iter)
    {
        *iter = 0;
    }
    

    drakon schrieb:

    Ich persönlich finde es unsinnig das unbedingt per Zeigernotation zu lösen. Das ist einfach nur unleserlich und unintuitiv. Vor allem kannst du den Indexzugriff ja ganz einfach auf Zeigernotation umwandeln. Das so in der Schleife zu machen finde ich auch nicht wirklich gut.

    Ich finde das gut. Das geht nämlich Hand in Hand mit der Iteratorennotation.



  • Tachyon schrieb:

    Ich finde das gut. Das geht nämlich Hand in Hand mit der Iteratorennotation.

    Ja, wenn du das jetzt noch anständig verbirgst, bin ich einverstanden. Aber diesen Code da möchte ich nicht 2 mal schreiben müssen. 😉



  • meine aufgabenstellung:
    funktion identity() welche ein 2dim array bekommt (bzw. ich denke ein array mit zeigern auf die jeweiligen zeilen).
    die funktion initialisiert das array mit lauter nullen, nur in der diagonale 1en.
    gefordert ist die funktion darf als variablen nur den parameter und jeweils einen pointer pro for schleife haben. und es soll in 2fors geloest werden mit nur einem zuweisungs operation.

    als tipp steht pointer arethmetik verwenden, ich denke wird dann irgend etwas sein, wenn das ergebnis aus spalten pointer weniger zeilen pointer null ist bedeutet das ich hab ein element der diagonale...
    aber wie gesagt hab probleme mit den for's 😞 (du verwendest ja zwei variablen)

    danke!!



  • AbsoluterBeginner schrieb:

    meine aufgabenstellung:
    funktion identity() welche ein 2dim array bekommt (bzw. ich denke ein array mit zeigern auf die jeweiligen zeilen).
    die funktion initialisiert das array mit lauter nullen, nur in der diagonale 1en.
    gefordert ist die funktion darf als variablen nur den parameter und jeweils einen pointer pro for schleife haben. und es soll in 2fors geloest werden mit nur einem zuweisungs operation.

    als tipp steht pointer arethmetik verwenden, ich denke wird dann irgend etwas sein, wenn das ergebnis aus spalten pointer weniger zeilen pointer null ist bedeutet das ich hab ein element der diagonale...
    aber wie gesagt hab probleme mit den for's 😞 (du verwendest ja zwei variablen)

    danke!!

    Wieder so eine blödsinnige Aufgabe ohne wirklichen Sinn.
    Zeig mal alles, was Du dazu bis jetzt so gemacht hast.



  • hehe, nicht meine schuld 😃
    danke fuer die hilfe also hier mein code:

    #include <iostream>
    using namespace std;
    
    void identity(int *row); //ich dachte es funktioniert mit einem normalen pointer
    //tut es aber nicht, gibt es ne andere moeglichkeit als den typ (*row)[10] zu verwenden?
    
    int main()
    {
     int square[10][10]; //das array
     int (*row)[10] = square; //adressen jeder zeile
    
      //show the addresses of each row 
      for(int i = 0; i < 10; ++i)
     	cout << *(row+i) << endl; 
      //distance is exactly 28hex (40dec) 
      //which is 10times a int per row
    
      //das funktioniert in meinen vorherigen post wollte ich eben nur das problem der fors machen aber ok machen wir es gleich mit funktion
    
       identity(row);
    
    void identity((*row)[10])
    {
     for(...)
       for(...)
    
    }
    

    soweit die struktur, hier schon fehler?
    die erste for sollte doch nur reihe fuer reiher durchgehen, also den parameter durchgehen. aber wie?!
    oben in meiner testausgabe der werte des arrays sehe ich dass ich mit

    (row+i)
    

    die adressen bekommen, aber wie mache ich es nur mit pointern?

    danke fuer deine hilfe!



  • update da ich gerade versuche das array bzw seine adressen zu uebergeben.
    ueber main definiert:

    void identity(int (*row)[10]);
    

    kein problem, implementiere ich die funktion

    ich fuege unter main folgendes hinzu:

    void identity(int (*row)[10] row)
    {
     cout << "in identity\n";
    }
    

    lauter errors, warum?!

    ex39.cc:30: error: variable or field identity' declared void ex39.cc:30: error:int identity' redeclared as different kind of symbol
    ex39.cc:8: error: previous declaration of void identity(int (*)[10])' ex39.cc:30: error: declaration ofint identity'
    ex39.cc:8: error: conflicts with previous declaration void identity(int (*)[10])' ex39.cc:30: error:row' was not declared in this scope
    ex39.cc:31: error: expected ,' or;' before '{' token

    ich sehe wenn ich das row entferne beim inmplementieren der funktion unter main kein error mehr aber ich muss ja in der funktion den parameter ansprechen koennen, ich dachte das ist der typ fuck ich kenn mich echt nimmer aus...



  • Du hast in der Deklaration den Namen des Parameters ("row") bereits drin. In der Implementierung dann zweimal, das muss krachen.



  • hallo ja sorry hab vorherigen post editiert, verzweifle echt langsam...
    was is dann jez der typ fuer die funktion?
    wenn ich es mit

    void identity(int *[10]);
    

    ueber main definiere klappt es, ist das richtig? kann ich das sagen dass es ein array mit 10 plaetzen fuer int zeiger ist?



  • ALLES NEU 🙂

    habe es jetzt geschafft 😉

    void identity(int (*)[10]); //muss ich das so definieren? geht mir nicht ganz ein, wie wird das gelesen? array von 10 elementen welche pointer auf ints sind?
    
    int main()
    {
     int square[10][10];
     int (*row)[10] = square;
    
      //show the addresses of each row 
      for(int i = 0; i < 10; ++i)
     	cout << *(row+i) << endl; 
      //distance is exactly 28hex (40dec) 
      //which is 10times a int per row
    
     identity(row);
    
     cout << endl;
     return 0;
    }
    
    void identity(int (*tst)[10]) //es war das prob dass ich die klammern rund um den pointer vergessen habe, warum brauche ich die klammern? also auch hier wieder die frage wie es interpretiert wird. ???
    {
     cout << "in identity\n" << *tst;
    
    }
    


  • zusatz, habe jetz auf verschiedenste arten versucht das array zu initialisieren - klaglos gescheitert 😡
    also falls jemand hier neu liest, es geht um obigen code, hier moechte ich in der funktion das array initialisieren, verwendet werden duerfen nur pointer (definiert in zwei vorschleifen)

    mein idee:

    for(int *x = *row; x != *(row+9); x += sizeof(int)*10)
    

    ich mache einen int pointer (fuer zeile) welchen ich so lange um 10 ints inkrementiere (10 da jede zeile 10 ints hat) und das ganze so lang bis der pointer die adresse des letzen array elemntes bekommt.
    nur funktioniert es nich 😃

    will das endlich verstehen...



  • Was soll deine Funktion jetzt genau machen? Das ist mir in diesem Thread nicht ganz klar geworden...

    Falls es nur darum geht, ein 2D-Array mit Nullen zu füllen, kannst du Folgendes tun. Ich würde es zuerst mal mit operator[] versuchen, das ist einleuchtender. Wenn du das wirklich verstanden hast, kannst du immer noch direkte Zeigerarithmetik verwenden.

    // (1): statisches Array mit Initialisierungsliste
    int Array[w][h] = {};
    
    // (2): statisches Array mit For-Schleife
    int Array[w][h];
    for (unsigned int x = 0; x < w; ++x)
    {
        for (unsigned int y = 0; y < h; ++y)
        {
            Array[x][y] = 0;
        }
    }
    
    // (3): dynamisches Array
    int** Array = new int*[w];
    for (unsigned int x = 0; x < w; ++x)
    {
        Array[x] = new int[h];
        for (unsigned int y = 0; y < h; ++y)
        {
            Array[x][y] = 0;
        }
    }
    // beim dynamischen Array wieder in umgekehrter Reihenfolge delete[] anwenden.
    

Anmelden zum Antworten