mikrocontroller.net

Forum: Compiler & IDEs WAS macht diese Zeile?


Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sebastian (Gast)
Datum:

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

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, da war jemand schneller.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 ;-)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man lernt nie aus !!!
Vielen Dank !!!
Noch eine Frage warum umstritten?

Gruß
Pier

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deine Atwort,
endschuldige bitte meine schlecht gestellte Frage !!

Gruß
Pier

irgendwie hast du mich trotzdem verstanden...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
  if( UseBackColor )
   draw_irgendwas( i, j, BACK_COLOR, k, l );
  else
   draw_irgendwas( i, j, FRONT_COLOR, k, l );

verwende ich ganz gerne
   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.
  draw_line( UseBackColor   ? BACK_COLOR     : FRONT_COLOR,
             UseLinePattern ? DASHED_LINE    : SOLID_LINE,
             UseEndPoints   ? POINTS_AS_DOTS : NO_POINTS );

versus
   if( UseBackColor )
     Color = BACK_COLOR;
   else
     Color = FRONT_COLOR;

   if( UseLinePattern )
     Pattern = DASHED_LINE;
   else
     Pattern = SOLID_LINE;

   if( UseEndPoints )
     EndPoints = POINTS_AS_DOTS;
   else
     EndPoints = NO_POINTS;

   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.

Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke nochmals für Eure erklärung!!!

Gruß
Pier

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

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

Das ist unschlagbar ;-)

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh das ist ja doppelt fies.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, true und false vertauscht lol

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist denn der Wert von ''?

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

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.