Seite 1 von 1

Kleine Frage zu Zeigern

Verfasst: Mi Okt 21, 2009 6:50 pm
von Bebu
Hallo zusammen, ich habe ein kleines Verständnisproblem bei den Zeigern. Ich arbeite mich gerade durch diverse Übungen dazu. Ich habe damit ein bisschen herumexperimentiert. Es geht um die Erhöhung von Zeigern, wenn diese z.B. auf ein Array zeigen.

Code: Alles auswählen

int main()
{
int wert[3] = {11,12,13};
int *ptr = wert;

cout << *ptr << endl;
cout << *(ptr+1) << endl;
cout << *(ptr+2) << endl;
}

Code: Alles auswählen

int main()
{
int wert[3] = {11,12,13};
int *ptr = wert;

cout << ptr[0] << endl;
cout << ptr[1] << endl;
cout << ptr[2] << endl;
}
Diese Codeschnippsel geben mir beide die Zahlen 11,12,13 auf der Konsole aus, genau wie sie sollten.

Schreibe ich den Code dagegen so:

Code: Alles auswählen

int main()
{
int wert[3] = {11,12,13};
int *ptr = wert;

cout << *ptr << endl;
cout << *(++ptr) << endl;
cout << ptr[2] << endl;
}
bekomme ich als Ergebnis 11,12,0 zurück. Warum ist das so? Hab ich irgendwo einen Denkfehler? Ich benutze Code::Blocks mit den GNU GCC Compiler.

Gruß Bebu

Re: Kleine Frage zu Zeigern

Verfasst: Mi Okt 21, 2009 7:01 pm
von nufan
Willkommen im Forum :)

Code: Alles auswählen

cout << *ptr << endl;
cout << *(++ptr) << endl;
cout << ptr[2] << endl;
In der zweiten Zeile erhöhst du den Zeiger. Wie du wahrscheinlich schon gelesen hast, speichert ein Zeiger die Adresse des ersten Feldelementes. Jetzt erhöhst du ihn aber und dein Zeiger zeigt auf das Element, das vorher den Index 1 hatte. Aufgrund der Erhöhung ist das nun das mit Index 0. Wenn du jetzt in der dritten Zeile versuchst Index 2 auszugeben, überschreitest du deinen Array. Um 13 auszegeben brauchst du nur ptr[1] verwenden.
Hoffe du verstehst was ich meine, ist ein bisschen umständlich zu erklären ^^

Re: Kleine Frage zu Zeigern

Verfasst: Mi Okt 21, 2009 7:02 pm
von Dirty Oerti
Hallo und erstmal willkommen im Forum :)

Du hast einen kleinen (aber wie du siehst wirkungsvollen) Denkfehler:

Bei

Code: Alles auswählen

*(ptr+1)
wird dein Zeiger ptr nicht verändert.
Also ist liefert ptr[2] vor und nach dieser Anweisung das gleiche Ergebnis.

Schreibst du hingegen

Code: Alles auswählen

*(++ptr)
oder auch

Code: Alles auswählen

*(ptr++)
, so veränderst du deinen ptr.
Was vorher ptr[2] (das bedeutet das gleiche wie *(ptr+2) ) war ist nun ptr[1], da du den Zeiger um eins erhöht hast.

Verstanden? :)

(Mist, zu langsam^^)

Re: Kleine Frage zu Zeigern

Verfasst: Mi Okt 21, 2009 7:17 pm
von Bebu
OK vielen Dank, ich hab jetzt beide Antworten je 3 mal gelesen und jetzt glaube ich es begriffen zu haben :D

Ich sollte also die Finger von *(++ptr) lassen, wenn ich nicht gerade meinen Index durcheinander wirbeln will. Spass beiseite, es bedeutet also im Grunde dass ich durch *(++ptr) die Adresse des Zeigers selbst ändere, während *(ptr+1) die Adresse selber nicht ändert, sondern nur aussagt "Dein Ziel ist meine Adresse nur um den Wert da anders"

Wenn das da so stimmen sollte, dann hab ichs wirklich begriffen.

Danke euch beiden

Gruß Bebu

Re: Kleine Frage zu Zeigern

Verfasst: Mi Okt 21, 2009 7:36 pm
von Dirty Oerti
Ja, ich würde sagen das kann man so sagen :)

ptr++ verändert ptr, während ptr+1 keine Änderung am Zeiger ptr vornimmt.
Deswegen musst du natürlich nicht die Finger davon lassen, du musst nur wissen, wie man es einsetzt ;)

Re: Kleine Frage zu Zeigern

Verfasst: Mi Okt 21, 2009 10:51 pm
von Kerli
An der Stelle von mir auch noch ein Willkommen ;)
Dirty Oerti hat geschrieben:Schreibst du hingegen

Code: Alles auswählen

*(++ptr)
oder auch

Code: Alles auswählen

*(ptr++)
, so veränderst du deinen ptr.
Dabei musst du nur aufpassen, da die beiden Schreibweisen nicht gleichwertig sind. Beim ersten Schnippsel steht das ++ vor dem Zeiger, weshalb man hier von dem Preinkrement-Operator spricht und beim zweiten vom Postinkrement-Operator. Der Unterschied ist der das beim Preinkrementoperator zuerst der Zeiger um eins weiter gesetzt wird und dann der Wert an der Stelle derefernziert wird und beim Postinkrementoperator zuerst der Wert derefernziert wird und dann erst der Zeiger erhöht wird.

Wenn du auf Nummer sicher gehen möchtest und nicht weißt was jetzt was ist, ist es am Besten einfach das Inkrementieren und Derefernzieren zu trennen:

Preinkrement:

Code: Alles auswählen

// Entweder so:
*(++ptr);
// oder so (beides macht das gleiche)
++ptr; // ptr zuerst erhöht
*ptr;
Postinkrement:

Code: Alles auswählen

// Entweder so:
*(ptr++);
// oder so (beides macht das gleiche)
*ptr; // ptr zuerst dereferenziert
++ptr;

Re: Kleine Frage zu Zeigern

Verfasst: Do Okt 22, 2009 9:04 am
von Xin
Kerli hat geschrieben:Dabei musst du nur aufpassen, da die beiden Schreibweisen nicht gleichwertig sind. Beim ersten Schnippsel steht das ++ vor dem Zeiger, weshalb man hier von dem Preinkrement-Operator spricht und beim zweiten vom Postinkrement-Operator. Der Unterschied ist der das beim Preinkrementoperator zuerst der Zeiger um eins weiter gesetzt wird und dann der Wert an der Stelle derefernziert wird und beim Postinkrementoperator zuerst der Wert derefernziert wird und dann erst der Zeiger erhöht wird.

Wenn du auf Nummer sicher gehen möchtest ...
Schöne Beschreibung... haben wir die eigentlich schon im Wiki?

Re: Kleine Frage zu Zeigern

Verfasst: Do Okt 22, 2009 11:19 am
von Bebu
Vielen Dank für eure Antworten. Das mit den Prä- und Postoperatoren wurde zum Glück in meinem Buch rechtzeitig behandelt, obwohl ich da bestimmt noch das eine oder andere Mal drüberstolpern werde, wie immer halt. :roll: