[Novize] Reihenfolge der Operatoren ?!
-
Hey Leute,
Habe mich heute durchs Thema Pointers gekämpft und hänge nun an einer Stelle die ich im Ganzen zwar verstehe aber über eine Unklarheit möchte ich nicht hinwegsehen.
Es geht um die Reihenfolge von Operatoren
while((*pbuffer++ = getchar()) != '\n');
Ich kenne die Liste für Reihenfolgen - insofern liegt der das unäre * und die Prefix ++ auf gleichem Niveu daher bestimmt das "Rechts nach Links" Gebot.
Was mich stört ist das Postfix ++ nicht in dieser Liste vorkommt?Heisst dies das Postfix ++ als ALLERLETZTES kommt egal was vorher passiert - d.h. vor dem ausführen von ";" wird das Postfix ++ noch ausgeführt?
Denn ich wundere mich das ich in der Expression oben den Wert von
*pbuffer
mit
!= '\n'
vergleiche und nicht
*pbuffer + 1 != '\n'
.
Da ich
(*pbuffer++ = getchar())
immerhin in eine Klammer gefasst sehe...somit denke ich bevor dass Ganze außerhalb der Klammer verglichen wird - wird erstmal das Postfix ++ angefügt.
Kann mich da jemand genauer aufklären um die Zweifel auszuräumen
mfg Charlie
-
Falke88 schrieb:
Was mich stört ist das Postfix ++ nicht in dieser Liste vorkommt?
Dann ist deine Liste kaputt. Postfix-Inkrement ist ganz oben.
-
Nach dem Zugriff auf *pbuffer wird pbuffer inkrementiert. Das kann direkt danach sein oder auch erst kurz vorm ; -> Sequenzpoint
Der Rückgabewert wird wegen der Klammerung in *pbuffer gespeichert und dann wird dieser Wert mit '\n' verglichen.
Ohne Klammerung :
(*pbuffer++ = getchar() != '\n');
wird erst der Rückgabewert mit \n' verglichen und dieses Ergebnis wird in *pbuffer gespeichert (also 0 oder 1 (unwahr,wahr) ). Nqach dem Zugriff auf *pbuffer wird pbuffer inkrementiert
-
also wird ein Postfix erst nach Benutzung der Variablen zu welcher es gehört ausgeführt
-
Falke88 schrieb:
also wird ein Postfix erst nach Benutzung der Variablen zu welcher es gehört ausgeführt
Er kann auch sofort ausgeführt werden. Da du bis zum nächsten Sequence Point sowieso nicht lesend auf diese Variable zugreifen darfst, ist es egal, wann genau das passiert.
Entscheidend ist: Der Ausdruck a++ liefert dir den Wert, den a vor der Erhöhung hatte.
-
z.B ergibt
n = a++ + a++;
undefiniertes Verhalten für n, weil nicht klar ist wann a erhöht wird.
Aber nach der Zeile ist a um 2 größer.
-
DirkB schrieb:
z.B ergibt
n = a++ + a++;
undefiniertes Verhalten für n, weil nicht klar ist wann a erhöht wird.
Aber nach der Zeile ist a um 2 größer.Wenn undefiniertes Verhalten auftritt, ist automatisch das gesamte Programm betroffen.
Die Auswertung eines Ausdrucks besteht grundsätzlich aus 2 Komponenten:
1. einer Wertberechnung, das ist der Wert der verwendet wird, wenn der betreffende Ausdruck Teil eines anderen Ausdrucks ist.
2. Nebeneffekten (side effects): Zugriff auf Variablen, Veränderung von Dateien oder der Aufruf von Funktionen, die das tun.
Es besteht bei der Ausführung dieser Schritte grundsätzlich keine Reihenfolge (nicht einmal eine unbestimmte), und auch nicht in Relation zur Auswertung anderer Ausdrücke,
es sei denn, das eine entsprechende zusätzliche Regel greift.Wird dasselbe Objekt modifiziert als auch in irgendeiner anderen Weise darauf zugegriffen, so ist das Verhalten unbestimmt, sofern keine Reihenfolge zwischen diesen beiden Operationen gegeben ist.
Im Falle des Postfix-Inkrements sind 3 Schritte durchzuführen:
1. Lesen des gespeicherten Wertes (=Nebeneffekt)
2. Bestimmung des Wertes des Ausrucks (=gelesener Wert)
3. Modifikation des gespeicherten Wertes
Aus der Semantik des Operators folgt, das Schritt 1 zwingend sowohl vor Schritt 2 und auch vor Schritt 3 erfolgen muss. Zwischen den Schritten 2 und 3 besteht dagegen keine zusätzliche Bestimmung der Reihenfolge.In
n = a++ + a++;
sind folgende Schritte auszuführen:
1. Lesen des Wertes von a (linker Operand)
2. Bestimmung des Wertes des Ausrucks (linker Operand)
3. Modifikation des gespeicherten Wertes von a (linker Operand)
4. Lesen des Wertes von a (rechter Operand)
5. Bestimmung des Wertes des Ausrucks (rechter Operand)
6. Modifikation des gespeicherten Wertes von a (rechter Operand)
7. Bestimmung der Summe (Addition hat keine weiteren Nebeneffekte)
8. Modifikation von n1 2 3 4 5 6 7 8 1 x < < !!! < < 2 > x < < 3 > x !!! !!! 4 !!! x < < < < 5 > x < < 6 !!! !!! > x 7 > > > > x < 8 > > > > > x
Zeile->Spalte
< Zeilenoperation vor Spaltenoperation
> Zeilenoperation nach Spaltenoperation
leer: keine Reihenfolge
!!!: keine Reihenfolge aber gleiches Objekt: undefiniertes Verhalten