Probleme mit Pointer!



  • Ich hab hier en Quellcodes, weis zwar, was er machen, aber absolut nicht warum 😉

    Nr. 1:

    ...
    int iAFeld[4]={15,23,113,40};
    int *piZeiger1=NULL, *piZeiger2=NULL;
    
    piZeiger1 = iAFeld;
    *(piZeiger1 + 1) = *iAFeld*4;
    
    piZeiger2 = (piZeiger1 + 1);
    *(++piZeiger2) = *piZeiger %2;
    
    piZeiger2 = (piZeiger1);
    *piZeiger2 += (*piZeiger1) + 1;
    
    iAFeld[3] == 5;
    
    ...
    

    Die wollen nun von mir die Werte der einzelnen Array Elemente wissen, welche wären: 31, 60, 1, 40

    Wiso, ist mir ein Rätsel.
    Grundsätzlich komm ich mit Zeigern recht gut klar, nur versteh ich hier nicht, welcher Ausdruck im Code die Zeigeradresse erhöht und welcher den wert des Arrays beeinflusst! z.B. kann ich mit *iAFeld*4 überhauptnichts anfangen. Was wird hier gemacht?

    und was ist der Unterschied zwischen *(piZeiger + 1) und (*piZeiger) + 1 ?
    beides mal wird die Adresse des Pointers um eins erhöht oder?
    kann vll jemand versuchen den ganzen verwirrenden Wirrwar vor mir zu entwirren 😉 Vielen Dank für eure Hilfe

    P.S: ist en Programmcode aus ner Prüfung, also gute Semantik hat das, was da steht sicherlich nicht


  • Mod

    Operatorpräzedenz! Klammern!

    `

    *(piZeiger + 1)`
    Zeiger wird um eins erhöht (aber Wert des Zeigers nicht verändert), dann dereferenziert.

    (*piZeiger) + 1
    Zeiger wird dereferenziert, das was rauskommt dann um 1 erhöht (und auch nicht gespeichert).

    Das war noch einfach, weil die Klammern die Reihenfolge vorgeben.
    *iAFeld*4
    Hier müssen wir in eine Tabelle gucken: Aha! Dereferenzierung kommt vor Multiplikation. Folglich wird zuerst dereferenziert, dann wird das Ergebnis mal 4 genommen.

    Reicht dies als Erläuterung, um den Rest zu entschlüsseln?



  • noch nicht ganz, aber fast!

    zum Verständniss:

    heist *(piZeiger + 1) in dem Zusammenhang, dass der Zeiger auf das feld iAFeld[1] zeit, und dann dereferenziert wird?

    heist *iAfeld*4 , dass der Inhalt von iAFeld[0] mit 4 multipliziert wird?

    heist *(piZeiger +1) = *iAFeld*4, dass iAFeld[0], (also 15) mit vier multipliziert wird und dann in pizeiger + 1, also iAFeld[1] gespeichert wird?
    würde ja passen, denn dann wäre iAfeld[1] = 60 und das dekt sich mit der ausgabe!

    heist dereferenzieren nichts anderes als zur Manipulation (lesen, schreiben) freigegeben?



  • DaiVied schrieb:

    noch nicht ganz, aber fast!

    zum Verständniss:

    heist *(piZeiger + 1) in dem Zusammenhang, dass der Zeiger auf das feld iAFeld[1] zeit, und dann dereferenziert wird?

    Genau!

    DaiVied schrieb:

    heist *iAfeld*4 , dass der Inhalt von iAFeld[0] mit 4 multipliziert wird?

    Auch richtig!

    DaiVied schrieb:

    heist *(piZeiger +1) = *iAFeld*4, dass iAFeld[0], (also 15) mit vier multipliziert wird und dann in pizeiger + 1, also iAFeld[1] gespeichert wird?
    würde ja passen, denn dann wäre iAfeld[1] = 60 und das dekt sich mit der ausgabe!

    Auch richtig! 😃

    DaiVied schrieb:

    heist dereferenzieren nichts anderes als zur Manipulation (lesen, schreiben) freigegeben?

    Dereferenzieren heißt soviel wie, dass mit dem Wert und nicht mit der Adresse gearbeitet wird. Es wird also der Wert an der Adresse geändert, auf die der Zeiger zeigt.

    Das hat ja schonmal was gebracht. 🙂



  • ok, dann müssts eigentlich passen.
    Ich schau mal morgen die Aufgabe durch und falls noch fragen offen sind, meld ich mich einfach nochmal! Ansonsten schonmal ein dickes dankeschön 🙂



  • Hab noch zwo fragen:

    Beispiel:

    int iAFeld[4] ={0};
    int *piZeiger1 = iAFeld;      /*piZeiger zeigt auf iAFeld[0], Adressoperator(&) 
                                    braucht man bei der zuweisung mit einem Array 
                                    nicht, oder?*/
    
    *(piZeiger + 1) = 15;        /*iAFeld[1] wird auf 15 gesetzt. piZeiger beleibt 
                                   aber nach der Operation auf iAFeld[0], oder?
                                   Also das Erhöhen in der Klammer nach dem 
                                   dereferenzierungsoperator wirkt sich nur auf  
                                   diesen einen schritt aus und verändert die 
                                   adresse des Zeigers nicht?*/
    

    und wenn ich zb. eine rechenoperation in einem Array ausführen wollte, dann würde

    iAFeld[1] ++; die adresse erhöhen?

    und *iAFeld[1]++; den Wert um 1 erhöhen?

    wenn das so wäre, dann wäre alles Klar 😉


  • Mod

    DaiVied schrieb:

    wenn das so wäre, dann wäre alles Klar 😉

    Ist aber nicht so 😞 . Arrayzugriff ist auch Dereferenzierung. Folglich würde iAFeld[1] ++; den Wert der an Arrayadresse 1 steht erhöhen. *iAFeld[1]++; würde das was an Arrayadresse 1 steht dereferenzieren und das Dereferenzierte dann erhöhen. Da aber in deinem Beispiel in dem Array int-Werte stehen, kann man diese nicht dereferenzieren und das wird daher nicht compilieren.

    Bei der anderen Frage mit dem Codebeispiel liegst du richtig.



  • Ok gut,

    würde dann:

    iArray[1] = iArray[1] +1; funktionieren?
    (also iArray[1] += 1; )

    und dann hat sich mir noch ne frage gestellt:

    ich habe ein Array (iArray) und einen pointer (piArray)

    piArray = iArray;

    piArray[i-1] = piArray[i];

    --> Hier brauch ich den Dereferenzierungsoperator nicht, ich spreche durch die eckigen klammern bereits den Wert der Adresse an. Ist das richtig?
    könnte ich dann vereinfacht auch sagen, das [] den Dereferenzierungsoperator ersetzen?


  • Mod

    DaiVied schrieb:

    Ok gut,

    würde dann:

    iArray[1] = iArray[1] +1; funktionieren?
    (also iArray[1] += 1; )

    Ja. Das würde den Wert an der Stelle 1 um 1 erhöhen.

    und dann hat sich mir noch ne frage gestellt:

    ich habe ein Array (iArray) und einen pointer (piArray)

    piArray = iArray;

    piArray[i-1] = piArray[i];

    --> Hier brauch ich den Dereferenzierungsoperator nicht, ich spreche durch die eckigen klammern bereits den Wert der Adresse an. Ist das richtig?
    könnte ich dann vereinfacht auch sagen, das [] den Dereferenzierungsoperator ersetzen?

    Ja. Das ist es wie Arrays funktionieren. Der Operator [] ist bloß eine Abkürzung für Pointeraddition und Dereferenzierung in einem Schritt. Array[i] entspricht *(Array+i)



  • sehr schön, dann ist das Thema jetzt klar! Ich danke euch vielmals für eure Hilfe! 😋



  • Wobei eine Frage habe ich noch!

    Folgendes szenario:

    typedef strukt {int iWert;
                    int iIndex;} MEINWERT;
    
    MEINWERT *neuerWert;
    
    scanf("%d",&(*neuerWert).iWert); //oder scanf("%d", &neuerWert->iWert);
    

    Das sind beides Gültige sequenzen aus der Lösung zu meinem Problem.

    Warum steht hier aber der Adress Operator bei scanf, denn eigentlich dachte ich, das man den bei einem Pointer nicht azugeben braucht? kann mir hier jemand weiterhelfen?


  • Mod

    Aber wenn du ihn dereferenzierst, ist es doch kein Pointer mehr und dann brauchst du wieder den Adressoperator. Beachte auch, dass der Memberzugriffsoperator eine höhere Priorität hat. Es wird zuerst der Zeiger dereferenziert, dann der Member iWert genommen und darauf der Adressoperator angewendet.



  • was ich bei dem ersten beispiel nicht verstehe:
    warum führt
    iAFeld[3] == 5;
    dazu dass das Array an der Stelle 3 40 wird..
    könnte das mir bitte jemand erklären?
    🙂



  • moni schrieb:

    warum führt
    iAFeld[3] == 5;
    dazu dass das Array an der Stelle 3 40 wird..
    könnte das mir bitte jemand erklären?

    Tut es nicht. Die Anweisung hat keinen Effekt, weil das Ergebnis des Vergleiches verworfen wird.
    🙂



  • ach ok stimmt == ist einfach ein vergleich..super danke 🙂


Anmelden zum Antworten