Forum: Compiler & IDEs WAS macht diese Zeile?


von Pier S. (bigpier)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

Das sieht nach einer vereinfachten If-Bedingung aus, mit dem 
Fragezeichen und Doppelpunkt.

von Sebastian (Gast)


Lesenswert?

Oh, da war jemand schneller.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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 ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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;

von Pier S. (bigpier)


Lesenswert?

Man lernt nie aus !!!
Vielen Dank !!!
Noch eine Frage warum umstritten?

Gruß
Pier

von Falk B. (falk)


Lesenswert?

@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

von Pier S. (bigpier)


Lesenswert?

Danke für deine Atwort,
endschuldige bitte meine schlecht gestellte Frage !!

Gruß
Pier

irgendwie hast du mich trotzdem verstanden...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
1
  if( UseBackColor )
2
   draw_irgendwas( i, j, BACK_COLOR, k, l );
3
  else
4
   draw_irgendwas( i, j, FRONT_COLOR, k, l );

verwende ich ganz gerne
1
   draw_irgendwas( i, j, UseBackColor ? BACK_COLOR : FRONT_COLOR, k, l );

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.

von Pier S. (bigpier)


Lesenswert?

Danke nochmals für Eure erklärung!!!

Gruß
Pier

von Simon K. (simon) Benutzerseite


Lesenswert?

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.)

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

1
printf("Array 'x' beinhaltet %d Wert%c.\n", cnt, (cnt > 1) ? '' : 'e');

Das ist unschlagbar ;-)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Oh das ist ja doppelt fies.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Stimmt, true und false vertauscht lol

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Was ist denn der Wert von ''?

Wenn das 0 ist geht das nicht immer, zB nicht mit sprintf.

Dann müsste das her:
1
printf ("Array 'x' beinhaltet %d Wert%s.\n", cnt, (cnt == 1) ? "" : "e");

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.