WAS macht diese Zeile?

Moderator Persönliche Seite #1102714
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.
#1103044
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
Moderator Persönliche Seite #1103062
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.
#1103074
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.
Persönliche Seite #1103597
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.)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren