Was ist der Unterschied zwischen
1 | if(a > b && c > d) |
2 | {
|
3 | . . . . . . . . |
4 | }
|
und
1 | if(a > b) |
2 | {
|
3 | if(c > d) |
4 | {
|
5 | . . . . . . . . |
6 | }
|
7 | }
|
?
|
Forum: Mikrocontroller und Digitale Elektronik C: Bedingte Anweisung "if"Was ist der Unterschied zwischen
und
? Georg M. schrieb: > Was ist der Unterschied Kompiliert in Maschinenbefehle kommt dasselbe raus Beim zweiten kannst du mehr else-Zweige nutzen. Ist beides wirklich das gleiche. Auch in der Ausführung: Wenn a>b, dann wird c>d nicht mehr abgefragt/ausgeführt. a>b wird garantiert vor c>d abgefragt. Bei einfachen Zahlen/Variablen ist das egal. Wenn c oder d jedoch Makro/Funktion/HW-Register sind, dann kann das wichtig sein. Und beide Versionen verhalten sich exakt gleich (solange a,b,c oder d kein Makro ist, dass irgendeine ganz andere Sache macht) Bruno V. schrieb: > Wenn a>b, dann wird c>d nicht mehr abgefragt/ausgeführt. Da fehlt das Wörtchen "nur" und das "nicht" ist zu viel. Nur wenn a>b, dann wird c>d ausgewertet. Bei ODER "||" wäre dein Satz richtig. Gilt dann aber nicht mehr für den zweiten Snipped. :
Bearbeitet durch User
Obelix X. schrieb: > Nur wenn a>b, dann wird c>d ausgewertet. Ist die Abarbeitung ohne Klammerung nicht von rechts nach links? Warum sollte? Würde Michael und Bruno widersprechen. Und der Satz von Bruno wäre dann immer noch nicht richtiger. :
Bearbeitet durch User
Wenn die Abarbeitung von rechts nach links geschieht (ich weiss es nicht ob es so ist) dann würde erst c>d ausgewertet und ggf. a>b nicht. Obelix X. schrieb: > Nur wenn a>b, dann wird c>d ausgewertet. Georg M. schrieb: > Was ist der Unterschied zwischen [schnipp] Logisch ist es das gleiche. Ob der gleiche Maschinencode dabei herauskommt, hängt vom Compiler und der Optimierungstufe ab. Variante 1 ist aber kompakter und IMHO auch leichter lesbar. Wie bereits geschrieben: in vielen Fällen wird der Compiler den gleichen Code erzeugen. Im Compiler Explorer kannst Du Dir das auch anzeigen lassen. Obelix X. schrieb: > Nur wenn a>b, dann wird c>d ausgewertet. Sorry. Natürlich völlig richtig. Genauso wie im if-Schachtelcode. Georg M. schrieb: > Was ist der Unterschied zwischen Was ist der Kern/Grund deiner Frage? Warum ich das Frage: Ein solche Frage hätte ich evtl. von einem Einsteiger erwartet. Nicht von jemandem mit bald 4000 Postings auf dem Buckel. Da steckt also wohl was anderes dahinter.... Wastl schrieb: > Ist die Abarbeitung ohne Klammerung nicht von rechts nach links? Nein.
Würde von rechts nach links ausgewertet, stürzte das mit einer Nullpointer-Exception ab. Tut es aber nicht, da eben von links nach rechts ausgewertet wird. Harald K. schrieb: > Tut es aber nicht, da eben von links nach rechts ausgewertet wird. Genau. Man sollte Assoziativität und Abarbeitungsreihenfolge nicht in einen Topf werfen: "Precedence and associativity are independent from order of evaluation." https://en.cppreference.com/w/c/language/operator_precedence https://en.cppreference.com/w/c/language/eval_order LG, Sebastian Harald K. schrieb: > Wastl schrieb: >> Ist die Abarbeitung ohne Klammerung nicht von rechts nach links? > > Nein. > >
> > Würde von rechts nach links ausgewertet, stürzte das mit einer > Nullpointer-Exception ab. > Tut es aber nicht, da eben von links nach rechts ausgewertet wird. Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end! Etwas ausprobieren ist keine valide Taktik in C, weil es sein kann, dass du dabei undefined behaviour nutzt. Der Compiler geht davon aus, dass der Programmierer weiß was er tut. Dein Code darf kein undefined behaviour enthalten und der Compiler ist frei, unter dieser Annahme beliebige Optimierungen durchzuführen. Es kann sein, dass das mit deinem aktuellen Compiler und den aktuellen Einstellungen funktioniert und der Code genau das macht, was du erwartest. Genau so gut kann das irgendwann in der Zukunft aber auch nicht mehr so sein. Dann hast du einen fiesen Fehler in gut abgehangenem, getestetem und seit Jahren zuverlässigem Code. (Das war nur als allgemeine Warnung gedacht, dein Beispiel ist ok. Ich gehe sogar davon aus, dass für genau diesen &&-Anwendungsfall die Compiler eine optimierte Implementierung haben.) Tilo R. schrieb: > (Das war nur als allgemeine Warnung gedacht, dein Beispiel ist ok. Und deshalb ist dein ganzes Post Unsinn. Es ist normal dass man Pointer auf NULL testet bevor man drauf zugreift. Und die Reihenfolge ist eben genau festgelegt und kein Zufall und kein undefined behaviour. :
Bearbeitet durch User
Cyblord -. schrieb: > Tilo R. schrieb: >> (Das war nur als allgemeine Warnung gedacht, dein Beispiel ist ok. > > Und deshalb ist dein ganzes Post Unsinn. sehe ich anders. > > Es ist normal dass man Pointer auf NULL testet bevor man drauf zugreift. Richtig, ich habe nichts gegenteiliges behauptet. > Und die Reihenfolge ist eben genau festgelegt und kein Zufall und kein > undefined behaviour. Richtig, ich habe nichts gegenteiliges behauptet. Tilo R. schrieb: > Etwas ausprobieren ist keine valide Taktik in C Das ist meine Kernaussage. Imho auch richtig, ich habe sie sogar begründet. 1. Klammereinsparung 2. Besser von außen sichtbar, außer man hat viel mit Lisp zu tun ;) Tilo R. schrieb: >> Etwas ausprobieren ist keine valide Taktik in C > Das ist meine Kernaussage. Imho auch richtig, ich habe sie sogar > begründet. Testen auf etwas ist kein "ausprobieren". Dein Post ist reine Klugscheißen zu einem Problem was es im zitierten Code nicht gibt. :
Bearbeitet durch User
Tilo R. schrieb: > Ich gehe sogar davon aus, dass für genau diesen &&-Anwendungsfall > die Compiler eine optimierte Implementierung haben. Das ist die "short circuit evaluation", die gibt es genauso beim logischen Oder.
Auch das stürzt nicht ab, weil die Auswertung des logischen Oder nach dem ersten zutreffenden Element (hier: !p) abgebrochen wird. https://de.wikipedia.org/wiki/Kurzschlussauswertung https://en.wikipedia.org/wiki/Short-circuit_evaluation Paar Anmerkungen zur Shortcut-Evaluation: Wenn der zweite Teilausdruch in a && b keine Seiteneffekte hat, dann darf der Compiler (bzw. der von ihm erzeugte Code) den Ausdruck auswerten, falls günstig. Beispiel:
wird mit avr-gcc zu:
Man kann also die Teilausdrücke nicht mehr bestimmten Instruktion(sfolg)en zuordnen. Nochn Hinweis zu C++: Shortcut Evaluation wird nicht auf überladene Operatoren && und || angewandt. :
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
|
|