Operator Reihenfolge - zweiter Operand
hallo,
ich habe schon seit geraumer Zeit mit PHP zu tun, aber scheinbar bei simplen Sachen lernt man immer was dazu.
Bitte kann mir jemand die Ergebnisse der folgenden Berechnungen erklären ?
ich habe schon seit geraumer Zeit mit PHP zu tun, aber scheinbar bei simplen Sachen lernt man immer was dazu.
Bitte kann mir jemand die Ergebnisse der folgenden Berechnungen erklären ?
$foo = 5;
echo $foo + $foo++ + $foo ."\n"; # 5+5+6 - Ergebnis: 17
$foo = 5;
echo $foo + $foo++ ."\n"; # 5+5 (+1)? - Ergebnis: 11
$foo = 5;
echo $foo + $foo + $foo++ ."\n"; # 5+5+5 (+1)? - Ergebins: 15
$foo = 5;
echo (int) $foo + $foo++ + $foo ."\n"; # 5+5+6 - Ergebnis: 16
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Kommentar vom Moderator masterG am 28.03.2011 um 17:14:18 Uhr
Editierfunktion ist auch nützlich
Content-ID: 162833
Url: https://administrator.de/forum/operator-reihenfolge-zweiter-operand-162833.html
Ausgedruckt am: 22.12.2024 um 07:12 Uhr
6 Kommentare
Neuester Kommentar
$foo = 5;
echo $foo + $foo++ + $foo ."\n"; # 5+5+6 - Ergebnis: 17
5 + 6 + 6 = 17echo $foo + $foo++ + $foo ."\n"; # 5+5+6 - Ergebnis: 17
$foo hast du ab dem 2. Operator um 1 erhöht und bleibt später natürlich so erhalten.
Besser zu verstehen wäre es vllt. so: $foo = $foo + 1 ; ist das gleiche.
$foo = 5;
echo $foo + $foo++ ."\n"; # 5+5 (+1)? - Ergebnis: 11
5 + 6 = 11echo $foo + $foo++ ."\n"; # 5+5 (+1)? - Ergebnis: 11
$foo ist ja 5 und erhöhst in beim 2. Operator wiede rum 1.
$foo = 5;
echo $foo + $foo + $foo++ ."\n"; # 5+5+5 (+1)? - Ergebins: 15
Mhh komisch, kann ich mir auch nicht erklären warum da 15 raus kommt und nicht 16.echo $foo + $foo + $foo++ ."\n"; # 5+5+5 (+1)? - Ergebins: 15
$foo = 5;
echo (int) $foo + $foo++ + $foo ."\n"; # 5+5+6 - Ergebnis: 16
Passt irgentwie auch nicht in meine Logik, ich hätte auf 5+6+6 getippt.echo (int) $foo + $foo++ + $foo ."\n"; # 5+5+6 - Ergebnis: 16
Ich vermute mal das es ein Problem von den Typen sein kann.
@nxclass,
anscheinend hast du hier einen Fall (oder einen Bug ) konstruiert, den der Interpreter nicht korrekt verarbeitet, weil du immer
den selben Varablennamen verwendest.
Operatoren geben wie Funktionen ein Ergebnis zurück. Für den zusammengesetzten Operator ++ gibt es zwei Notationen:
Die Präfix-Notation (++$var) und die Postfix-Notation ($var++). Im ersten Fall wird der Variableninhalt um 1 inkrementiert und danach
das Ergebnis zurückgegeben. Im zweiten Fall wird der Variableninhalt zurückgegeben und danach inkrementiert.
Was jetzt bei deinem Beispiel passiert, kann ich auch (noch) nicht nachvollziehen, aber wenn du anstatt einem Variablennamen
versch. Variablennamen verwendest, arbeiten die Operatoren auch korrekt:
Gruß
Günni
anscheinend hast du hier einen Fall (oder einen Bug ) konstruiert, den der Interpreter nicht korrekt verarbeitet, weil du immer
den selben Varablennamen verwendest.
Operatoren geben wie Funktionen ein Ergebnis zurück. Für den zusammengesetzten Operator ++ gibt es zwei Notationen:
Die Präfix-Notation (++$var) und die Postfix-Notation ($var++). Im ersten Fall wird der Variableninhalt um 1 inkrementiert und danach
das Ergebnis zurückgegeben. Im zweiten Fall wird der Variableninhalt zurückgegeben und danach inkrementiert.
<?php
$foo=5;
echo $foo++."<br>"; // Ergebnis: 5, Wert wird "nach" der Ausgabe inkrementiert
echo ++$foo."<br>"; // Ergebnis: 7, Wert wurde "vor" der Ausgabe nochmal inkrementiert
?>
Was jetzt bei deinem Beispiel passiert, kann ich auch (noch) nicht nachvollziehen, aber wenn du anstatt einem Variablennamen
versch. Variablennamen verwendest, arbeiten die Operatoren auch korrekt:
<?php
$foo1=5;
$foo2=5;
$foo3=5;
echo $foo1 + $foo2++ + $foo3."<br>"; //Ergebnis: 15, Wert($foo2) wird "nach" der Ausgabe inkrementiert
$foo1=5;
$foo2=5;
$foo3=5;
echo $foo1 + ++$foo2 + $foo3."<br>"; //Ergebnis: 16, Wert($foo2) wird "vor" der Ausgabe inkrementiert
$foo1=5;
$foo2=5;
$foo3=5;
echo $foo1 + $foo2 + $foo3++."<br>"; //Ergebnis: 15, Wert($foo3) wird "nach" der Ausgabe inkrementiert
$foo1=5;
$foo2=5;
$foo3=5;
echo $foo1 + $foo2 + ++$foo3."<br>"; //Ergebnis: 16, Wert($foo3) wird "vor" der Ausgabe inkrementiert
$foo1=5;
$foo2=5;
$foo3=5;
echo $foo1 + ++$foo2 + ++$foo3."<br>"; //Ergebnis: 17, Werte($foo2,$foo3) werden "vor" der Ausgabe inkrementiert
$foo1=5;
$foo2=5;
$foo3=5;
echo $foo1 + $foo2++ + $foo3++."<br>"; //Ergebnis: 15, Werte($foo2,$foo3) werden "nach" der Ausgabe inkrementiert
?>
Gruß
Günni
Die Ursache ist hier ganz einfach die Operator-Präzedenz (Das wäre übrigens eine nette Frage für einen Programmiertest ).
++ ist ein unärer Operator und bindet immer stärker als alle binären Operatoren.
Entsprechend ist die Rechnung:
(Warum ich da jetzt klammern gesetzt habe erkläre ich unten)
Der Grund ist hier, dass + ein Binärer Operator ist.
Er hat nur exakt zwei Seiten (links und rechts), PHP muss also implizit Klammern, und klammern binden immer noch stärker also unäre Operatoren.
Hier steht also:
Anders gesagt: Für Programmiersprachen gilt das Assoziativgesetz (Klammervertauschungsgesetz) nicht!
Das Casten ist ebenfalls ein unärer Operator.
Die unären Operatoren werden wieder von links ausgewertet, weshalb folgendes passiert:
Das ist natürlich nicht zu verwechseln mit
Frage beantwortet?
Kleine Überlegung zum Schluss:
Kommt hier true oder false raus und warum?
Der Code funktioniert nicht in PHP, aber in C
++ ist ein unärer Operator und bindet immer stärker als alle binären Operatoren.
Entsprechend ist die Rechnung:
echo $foo + $foo++ + $foo ."\n"; # 5+5+6 - Ergebnis: 17
= ($foo + $foo++) + $foo
= 2 1 3 #Auswertungsreihenfolge
= 6 + 5 + 6
echo $foo + $foo++ ."\n"; # 5+5 (+1)? - Ergebnis: 11
= $foo + $foo++
= 2 + 1 #Auswertungsreihenfolge
= 6 + 5
echo $foo + $foo + $foo++ ."\n"; # 5+5+5 (+1)? - Ergebins: 15
Der Grund ist hier, dass + ein Binärer Operator ist.
Er hat nur exakt zwei Seiten (links und rechts), PHP muss also implizit Klammern, und klammern binden immer noch stärker also unäre Operatoren.
Hier steht also:
= ($foo + $foo) + $foo++
= 1 2 3 #Auswertungsreihenfolge
= 5 + 5 + 5
Anders gesagt: Für Programmiersprachen gilt das Assoziativgesetz (Klammervertauschungsgesetz) nicht!
echo (int) $foo + $foo++ + $foo ."\n"; # 5+5+6 - Ergebnis: 16
Das Casten ist ebenfalls ein unärer Operator.
Die unären Operatoren werden wieder von links ausgewertet, weshalb folgendes passiert:
= (int)($foo) + $foo++ + $foo
= 1 2 3 #Auswertungsreihenfolge
= 5 + 5 + 6
Das ist natürlich nicht zu verwechseln mit
(int)($foo + $foo++ + $foo)
Frage beantwortet?
Kleine Überlegung zum Schluss:
0 < 7 < 5
Kommt hier true oder false raus und warum?
Der Code funktioniert nicht in PHP, aber in C
Frage beantwortet?
Nöö!
<?php
$foo=5;
echo $foo + $foo++ + $foo;
?>
Ergibt 17
<?php
$foo1=5;
$foo2=5;
$foo3=5;
echo $foo1 + $foo2++ + $foo3;
?>
Ergibt 15
Auch Klammern bringt nix:
<?php
$foo=5;
echo $foo + $foo++ + $foo;
?>
Ergibt 17
<?php
$foo=5;
echo ($foo + $foo++) + $foo;
?>
Ergibt?? Na . . . , 17
Gruß
Günni
Ergibt 17 face-sad
Richtig, wie von mir oben erklärt
Ergibt 15 face-smile
Weil es 3 Variablen sind.
Das Postkrement wird zwar angewendet, aber gleich verworfen im Gegensatz zu oben, wo die variable nach dem Postkrement gleich noch zweimal benutzt wird!
Ergibt 17
Kein Unterschied zum ersten Beispiel?
Ergibt?? Na . . . , 17
Das ist genau das erste Beispiel mit der Klammerung, die PHP implizit selber einsetzt.
Nochmal:
- Ein binärer Operator wie + hat nur genau EINE linke und EINE rechte Seite
- Ein + bindet stärker als ein anderes + (von links, wenn mehrere gleichberechtigt auftreten)
- Das Assoziativgesetz gilt hier nicht