Hallo Guten morgen kann mir jemand diese zeile erklären ( was macht ?
und : kann diesen Operand nicht in meinem CBuch finden)
crc = (crc >> 1) ^ ((crc & 1) ? 0xA001 : 0 );
Danke Gruß
Pier
crc wird um 1 bit nach rechts geschoben.
Falls eine 1 rausgeschoben wird, dann wird crc mit einer bestimmten
Maske (0xa001) ver-XOR-t.
Stefans Code macht aber was anderes. Es testet Bit0 des geschobenen
Wertes. Ausserdem wird crc nur ver-XODER-t, sondern anders gesetzt als
im Original. Also ignorieren den Post ;-)
Dann wirf dein C-Buch weg...
Der sogenannte ternäre Operator ist reichlich umstritten, aber gehört
nun einmal zur C-Syntax. ("ternär" bedeutet dabei eigentlich nur,
dass er drei Teile verbindet, aber es ist der einzige ternäre Operator
in der gesamten C-Syntax.)
Das ist eine Art if-Anweisung, die aber selbst ein Ausdruck ist.
Der Teilausdruck vor dem Fragezeichen bildet einen Wahrheitswert,
und abhängig von diesem Wahrheitswert ergibt sich der Wert des
gesamten Ausdrucks dann aus dem Teilausdruck zwischen dem Fragezeichen
und dem Doppelpunkt (falls der Steuerausdruck "true" war) oder vom
Doppelpunkt bis zum Ende.
Johann L. hat natürlich Recht!!! Das Falsche habe ich gelöscht, nicht
dass Pier S. das ernst nimmt.
Ich habe die Klammern falsch gelesen (und im if unpaarig gesetzt).
So jetzt aber:
if ( (crc & 1) != 0 )
crc = (crc >> 1) ^ 0xA001;
else
crc = (crc >> 1) ^ 0;
@Pier S. (bigpier)
>Noch eine Frage warum umstritten?
Was ist das für eine Frage? Versteht kein Mensch.
Wenn du wissen willst warum der ternäre Operator umstritten ist, tja
dann . . .
IMO ist es ein Hackerkonstrukt, welches den Code mal ganz fix
unleserlich macht und man sich damit schnell ins Knie schiessen kann.
Ein einfache IF Anweisung ist klar strukturiert und lesbar.
MFG
Falk
Falk Brunner wrote:
> IMO ist es ein Hackerkonstrukt, welches den Code mal ganz fix> unleserlich macht und man sich damit schnell ins Knie schiessen kann.
Ins Knie schießen? Eher nicht. Aber ja, der Code wird nur sehr
selten leserlicher dadurch. Ich habe aber auch schon Situationen
erlebt, wo die relative Kürze des ternären Operators die Leserlich-
keit verbessert hat. Muss man halt (wie immer bei solchen nicht-
technischen, rein stilistischen Regeln) von Fall zu Fall entscheiden.
Auch ein goto kann manchmal die Lesbarkeit verbessern, wenn man
bspw. damit endlos verschachtelte Konstrukte vermeiden kann.
Auf jeden Fall sollte man ihn aber, wenn er denn mal in einem Quellcode
auftaucht, lesen können.
Falk hat ja schon angeschnitten, warum man über diesen Operator streiten
kann.
Dazu kommt, dass hier etwas seltsames passiert.
Es wird eine Kontrollstruktur, nämlich die Fallunterscheidung, in Form
eines arithmetischen Ausdrucks zur Verfügung gestellt, die einen Wert
liefert. Da könnte man sich doch auch fragen: warum hat dann eigentlich
nicht auch eine Schleife einen Wert?
Das Hauptargument ist aber ähnlich wie beim berühmt, berüchtigten goto.
Im Prinzip bräuchte man ihn nicht. Wenn man ihn weise einsetzt, kann er
ein bestimmtes Problem vereinfachen und klarer sein aber oft legt man
sich damit selbst ein Ei.
IMHO ist der ternäre Operator ein Überbleibsel aus der Zeit, als
Optimierer noch nicht so leistungsfähig waren wie heute und man dem
Programmierer ein Mittel in die Hand geben wollte, dem Optimizer unter
die Arme zu greifen. Ich persönlich verwende den ternären Operator
eigentlich auch nur in Fällen, in denen eine einfache
Fallunterscheidung mit einfachen Resultaten in Funktionsaufrufen
gemacht werden muss. In diesen Fällen finde ich den ternären Operator
einfacher und auch übersichtlicher als Code Duplizierung
Also.
Anstelle von
ich find das tatsächlich einfacher zu lesen, vor allem wenn man sich
mittels geschickter Formatierung dann auch noch eine optische Hilfe
einbaut. Sind dann in einem Funktionsaufruf mehrere Argumente von dieser
Gestalt, dann kann man dadurch tatsächlich ein nicht zu unterschätzende
Vereinfachung im Lesefluss erreichen.
1
draw_line(UseBackColor?BACK_COLOR:FRONT_COLOR,
2
UseLinePattern?DASHED_LINE:SOLID_LINE,
3
UseEndPoints?POINTS_AS_DOTS:NO_POINTS);
versus
1
if(UseBackColor)
2
Color=BACK_COLOR;
3
else
4
Color=FRONT_COLOR;
5
6
if(UseLinePattern)
7
Pattern=DASHED_LINE;
8
else
9
Pattern=SOLID_LINE;
10
11
if(UseEndPoints)
12
EndPoints=POINTS_AS_DOTS;
13
else
14
EndPoints=NO_POINTS;
15
16
draw_line(Color,Pattern,EndPoints);
Sobald aber entweder der Vergleichsteil und/oder einer der Teilausdrücke
nur wenig komplizierter werden, gebe ich den ternären Operator zugunsten
eines dezidierten if auf.
Der ternäre Operator kann übrigens durchaus sehr praktisch sein, wenn
man sie in Initialisierungen von Arrays benutzt. Da geht nämlich kein
if/else, aber der ternäre Operator lässt sich dort sehr wohl verwenden.
Zugegeben, war bisher auch die einzige Stelle wo ich ihn für nützlich
befand :-)
(War die Erzeugung eines const Arrays im PROGMEM mit Tetris-Steinen. Per
Preprozessor hat man die Steine pseudo-grafisch mit einsen und nullen
beschrieben und im Array landete nachher eine Art Bitmaske bzw. eine
interpretierte Form der Steine als Offsets von den Kanten.)