Didn't find your answer? Ask the community — no account required.
S
Stefan Wiest
Hallo Stefan,
Am 20.06.2013 10:53, schrieb Stefan: > kann mir jemand erklären, was folgende Konstruktion macht? > > Es geht insbesondere um das ?
Wenn TimingDelay gleich 0 ist, dann wird TimingDelay 0 zugewiesen. Ist es ungleich 0, wird 1 abgezogen.
formatting link
Grüße, Stefan
E
Edzard Egberts
Stefan schrieb:
Wenn die Bedingung vor dem Fragezeichen wahr ist, wird der Teil vor dem Doppelpunkt geliefert, ansonsten der nach dem Doppelpunkt. Wenn TimingDelay gleich Null ist, wird TimingDelay der Wert Null zugeordnet, ansonsten der Wert "TimingDelay-1".
Na ja, ich würde dann wohl eher schreiben:
if (TimingDelay) --TimingDelay;
S
Stefan
Am 20.06.2013 11:04, schrieb Edzard Egberts:
oder : if (TimingDelay) TimingDelay--;
;-)
Danke an euch beide für die Info.
Gruß
Stefan
E
Edzard Egberts
Stefan schrieb:
Nö, das war schon richtig so, weil die Operatoren unterschiedlichen Aufwand haben und Dein Code noch optimiert werden muss. Ganz deutlich wird das an diesem Beispiel:
"return --TimingDelay;"
vordekrementiert, kann man einfach übersetzen als:
Im "returnfall" ist also beides notwendig, wenn das Ergebnis des Operators aber nicht weiter verarbeitet wird, kann der Compiler Retval weglassen und "TimingDelay--" durch "--TimingDelay" ersetzen.
R
Roland Ertelt
Und so sprach Edzard Egberts:
Und sauber (Misra7LINT) formuliert wäre das:
if (TimingDelay==0) { TimingDelay=0; } else { TimingDelay--; }
Was der Kompiler dann draus optimiert steht auf einem anderen Blatt...
Roland
E
Edzard Egberts
Roland Ertelt schrieb:
Nein, auf diesem oben. :o)
Das kann ersatzlos gestrichen werden, da sich der Wert durch die Zuweisung nicht ändert.
Da der Rückgabewert nicht gebraucht wird (der Post-Operator ist der mit dem Rückgabewert) kann direkt der Pre-Operator angewandt werden. Meine Formulierung ist also schon optimiert, bevor die der Compiler zu sehen bekommt. Außerdem verständlicher.
Dass es alle so machen, bedeutet nicht unbedingt, dass man es nicht besser machen kann.
E
Edzard Egberts
Edzard Egberts schrieb:
Na ja, vorausgesetzt es ist kein Refresh, da würde der Code tatsächlich bei jedem Durchlauf einen Zugriff auf die Speicherstelle durchführen. Das würde der Compiler wohl kaum "wegoptimieren", das war zu kurz gesehen. :o(
R
Roland Ertelt
Und so sprach Edzard Egberts:
Nein kann es (bei safety critical applications) nicht. Dort darf es keinen impliziten Code geben. (So muss bei switch/case ebenfalls der default: Pfad explizit existieren, auch wenn er leer ist).
Unabhängig von den Festlegungen bei safety ist es einfach schlechter Stil, impliziten Code zu schreiben. (Fast so schlecht wie der Code aus dem OP) Er liest sich schlecht und andere werden unnütz belastet, wenn sie sich einarbeiten müssen.
Und wenn die Zuweisung nur dazu da ist, beim Debug einen breakpoint reinsetzen zu können...
Roland
G
Gernot Fink
Der Compiler darf die Zuweisung nicht wegoptimieren da das ganze Programm nur sinn macht wenn TimingDelay volatile definiert ist.
Die nach den bekannten vorgaben beste Verison dürfte also folgendes sein. if(TimingDelay)TimingDelay--;
MFG Gernot
H
Hergen Lehmann
Vorsicht - wenn TimingDelay keine normale Variable, sondern ein SFR ist, ist das nicht zwingend gleichbedeutend!
Hergen
F
Frank Buss
Kann ich mir nicht vorstellen. Bei switch-case schon, denn dort ist es sinnvoll, aber bei Konstrukten wie "if (a==0) a=0;" ist das zumindest für mich nur Unsinn. Und was ist denn genau impliziter Code? Muß man immer alle lokalen Variablen bei jedem "if" setzen? Oder gar alle globalen Variablen (von denen es ja besser nicht viele geben sollte) ?
Also wenn ich als C-Programmierer sowas lese:
if (TimingDelay==0) { TimingDelay=0; } else { TimingDelay--; }
dann muß ich länger darüber nachdenken, was der Code macht, da ich solchen redundanten Code nicht schreiben würde. Das hier:
if (TimingDelay) TimingDelay--;
ist viel einfach für mich verständlich, da es auch ein übliches C-Idiom ist.
Gute Debugger können Breakpoints mit Variablenprüfungen verbinden.
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss
M
Martin Gerdes
Edzard Egberts schrieb:
... und hätte damit ein Statement mit anderer Funktion (Rückwärtszähler läuft über die 0 hinaus, während er im Original bei 0 stehenbleibt)
M
Martin Gerdes
Martin Gerdes schrieb:
(Rückwärtszähler
stehenbleibt)
Hoppla! Mist gebaut! Es ist wohl schon spät. :(
E
Edzard Egberts
Gernot Fink schrieb:
SEUFZ!
if (TimingDelay) --TimingDelay;
Jetzt mal aus dem Stroutrup die Deklaration dieser Operatoren:
T& operator--(); // Präfix T operator--(int); // Postfix
Der Postfix-Operator liefert also eindeutig den schon genannten zusätzlichen Rückgabewert, während der Präfix-Operator eine Referenz auf den bearbeiteten Wert liefert, also keine zusätzliche Variable anlegen muss.
Ich verstehe nicht, was daran so schwer einzusehen ist. Das ist C++, kein BASIC, und die bessere Formulierung für oben genanntes Problem ist wirklich eindeutig.
M
Matthias Weingart
Edzard Egberts :
Und was passiert, wenn TimingDelay global definiert ist?
int TimingDelay;
void foo1(void) { TimingDelay=5; return --TimingDelay; } hier erwarte ich 4
a=foo1(); hier ist a=4 und TimingDelay=4 b=foo2(); hier erwarte ich b=5 und TimingDelay=4
Der post-operator dürfte ja eigentlich - der Logik nach - erst ausgeführt werden, wenn der Returnwert übergeben wurde. Naja wie auch schon in anderen Postings deutlich geworden ist, ist das Konzept der pre- und post-Operatoren relativ unverständlich. Man ist sich nicht wirklich sicher, was der Code tut
- ausser man geht mit dem Debugger drüber. Mir geht es mit regex ähnlich - auch wenn ich schon etliche regex-Ausdrücke gebastelt hab, fällt mir es unheimlich schwer das zu verstehen. Da ist ne simple pascal-ähnliche Syntax wirklich angenehmer. Vermutlich ist sowas nur was für Leute mit Inselbegabungen ;-).
M.
E
Edzard Egberts
Matthias Weingart schrieb:
Jedenfalls bis man so etwas selber geschrieben hat. Ich greife noch einmal die Operator-Deklarationen aus meinem anderen Posting auf, diesmal mit Implementierung: