Forum: Mikrocontroller und Digitale Elektronik If Abfrage in C - Frage zu Verkürzung


von Nob (Gast)


Lesenswert?

Guten Nachmittag miteinander,
normalerweise programmiere ich meine AVRs in ASM. Irgendwo habe ich dann 
mal gelesen in C sei das alles viel bequemer. Bevor ich einen 
Programmiersprachenkrieg anzettel komme ich nun zu meiner Frage.
Es geht um folgenden Ausschnitt im GCC Tutorial hier auf der Seite:
1
i = PINA;
2
i = i & 0x01;
3
if ( i != 0 ) {test1();} 
4
5
if ( ( PINA & 0x01 ) != 0 ) { test1(); } // verkürzt 
6
7
if ( PINA & 0x01 ) { test1(); } // nochmals verkürzt

Also bei der ersten Variante der Verkürzung verzichtet man einfach auf 
die Variable i und checkt einfach ob das Byte <0 ist. Richtig?

Die zweite Variante verstehe ich jetzt nicht ganz.
PINA wird mit 0x01 geundet (Also logisch und genommen? Gemacht? Wie auch 
immer)
Woher weiß der uC jetzt in welchem Fall die Funktion ausgeführt werden 
soll? Immerhin steht nirgends, dass das Byte komplett 0 sein soll.

von JH (Gast)


Lesenswert?

Eine If-Anweisung wird in C dann ausgeführt, wenn die Bedingung nicht 
null ist. Die zweite Verkürzung wird also nur dann ausgeführt, wenn das 
maskierte Bit den Wert 1 hat.

von W.S. (Gast)


Lesenswert?

Das Problem dabei ist der völlig unmathematische Entwurf von C. C kennt 
keine boolean Variablen und somit muß eine Verfügung  im Stile eines 
Ordre de Mufti her: Null ist false und alles ungleich Null ist true, 
Basta.

Deine beiden Ausdrücke sind in ihrer Wirkung gleich. Der erste, 
ausdrückliche ist eigentlich der mathematisch korrekte, aber du wirst in 
deinem Leben massenweise auch den zweiten finden, weil der ein paar 
Zeichen weniger hat. Eingeschworene C-Leute mögen sowas bevorzugt, 
genauso wie sie auch den Fragezeichenoperator einem If..Else Konstrukt 
vorziehen. Nachdem der Compiler das alles durch seine Mangel geleiert 
hat, kommt in beiden Fällen der gleiche Code heraus. Die Version mit dem 
? ist bloß kryptischer und unleserlicher, weswegen sie bei vielen 
C-Programmierern den Vorzug hat.

Klaro?

W.S.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> Das Problem dabei ist der völlig unmathematische Entwurf von C.
Er ist aber sehr maschinennah:
1
if ( (PINA & 0x01) != 0 ) { test1(); } // verkürzt
ich muss nicht ein Register (PINA) mit 1 ver-unden und dann hinterher 
nochmal mit 0 vergleichen. Der Schon nach der Berechnung des Ausdrucks 
PINA&1 stehen die Flags im Prozessor richtig und können ausgewertet 
werden. Ein zusätzlicher Vergleich auf "ungleich Null" ist unnötig.

W.S. schrieb:
> Die Version mit dem ? ist bloß kryptischer und unleserlicher
Verilog kann das auch. Ich hätte da den Beitrag 
Beitrag "Re: Entscheidungsoperation IF/else oder ?" mit dem Link auf den 
Fragezeichenoperator...  ;-)

von Kai S. (zigzeg)


Lesenswert?

Was ich hier einmal betonen möchte ist, dass in der Compiler hier in 
allen drei Fällen vermutlich den selben Code generieren würde (und 
Ausnahmen bestätigen die Regel).
Das bedeutet dass man in C den Code ruhig so schreiben kann, wie es am 
besten lesbar ist.
So würde z.B. wenn es die Architektur unterstützt z.B. ein 
Bittest-Befehl erzeugt werden (weiss nun nicht, ob ein AVR so was hat), 
wenn dieser Vorteile gegenüber einem "AND" Befehl hat.

(Randbedingungen:
1. der Optimizer muss aktiv sein (z.B. -O2)
2. Die Inhalt der Variable "i" wird später nicht für andere Dinge 
verwendet)

ZigZeg

von Nob (Gast)


Lesenswert?

Achso ist das also. Seltsam wenn man nur ASM gewohnt ist. Da wirkt C 
viel groß schrittiger. Mal gucken wie ich damit zurecht komme.

Danke euch allen!

von W.S. (Gast)


Lesenswert?

Lothar Miller schrieb:
> Er ist aber sehr maschinennah:if ( (PINA & 0x01) != 0 ) { test1(); } //
> verkürzt
> ich muss nicht ein Register (PINA) mit 1 ver-unden und dann hinterher
> nochmal mit 0 vergleichen. Der Schon nach der Berechnung des Ausdrucks
> PINA&1 stehen die Flags im Prozessor richtig und können ausgewertet
> werden. Ein zusätzlicher Vergleich auf "ungleich Null" ist unnötig.

Nee, mein Lieber.
Du schreibst eben wie ein C-Programmierer, was einem mathematisch 
denkenden Zeitgenossen als schlichter Unsinn erscheint, weil man dazu 
eben die vielen "Ordres de Mufti" beachten muß, um den Hintersinn zu 
erfassen.

Ob auf einer konkreten Maschine das verunden einer Variablen mit einer 
Konstanten tatsächlich irgendwelche Flags setzt oder nicht, kann man 
allein im Manual zu der betreffenden Architektur nachlesen. In ganz 
vielen Fällen ist das so, aber aus mathematischer Sicht kommt als 
Ergebnis NUR eine Zahl heraus, die der Operation entspricht - und die 
muß man, wenn man ein logisches Ergebnis haben will, eben anschließend 
einem Vergleich unterziehen.


Und nochwas: C ist nicht "aber sehr maschinennah". Vergleiche doch mal 
die Ausdrucksmöglichkeiten von C mit der Hardware in einem kleinen 
PIC16. Dort findest du ausdrückliche Befehle zum Arbeiten mit einzelnen 
Bits. Man könnte dort schreiben

if (PortA.4) DoSomething();

( in Assembler
  BTFSC PortA,4
  CALL  DoSomeThing
)
wenn das in C so vorgesehen wäre. Ist es aber nicht. Stattdessen braucht 
man ellenlange Headerdateien, um mittels Präprozessor etwas 
vergleichbares hinzukriegen. Aber Präprozessor-Akrobatik ist was anderes 
als die Syntax von C.


W.S.

von Kai S. (zigzeg)


Lesenswert?

W.S. schrieb:
> wenn das in C so vorgesehen wäre. Ist es aber nicht. Stattdessen braucht
> man ellenlange Headerdateien, um mittels Präprozessor etwas
> vergleichbares hinzukriegen. Aber Präprozessor-Akrobatik ist was anderes
> als die Syntax von C.

naja, die Header braucht es in erster Linie, damit ich statt "Bit 4" 
einen symbolischen Namen nehmen kann. Wenn ich "Bit 4" meine sage ich in 
C einfach
1
if (PORTA & (1<<4))

ZigZeg

von Dieselwolf (Gast)


Lesenswert?

Nob schrieb:
>Irgendwo habe ich dann mal gelesen in C sei das alles viel bequemer.

Du beherrscht ASM? Dann bleibe dabei -warum willst Du Dir so eine
Gaukelsprache wie C beibringen?

von Kai S. (zigzeg)


Lesenswert?

Dieselwolf schrieb:
> Nob schrieb:
>>Irgendwo habe ich dann mal gelesen in C sei das alles viel bequemer.
>
> Du beherrscht ASM? Dann bleibe dabei -warum willst Du Dir so eine
> Gaukelsprache wie C beibringen?

Stimmt, über den Tellerrand zu schauen ist auch wirklich völliger 
Unsinn. Schuster bleib bei Deinen Leisten!

ZigZeg

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Kai S. schrieb:
> Schuster bleib bei Deinen Leisten!

Deine_m_. Der Leisten.

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


Lesenswert?

W.S. schrieb:
> Ob auf einer konkreten Maschine das verunden einer Variablen mit einer
> Konstanten tatsächlich irgendwelche Flags setzt oder nicht, kann man
> allein im Manual zu der betreffenden Architektur nachlesen.

Kennst du eine, bei der das nicht der Fall wäre?

C ist in erster Linie so entworfen worden, dass es die Fähigkeiten
der PDP-11-CPU bestmöglich in eine Sprache abbilden konnte, die mehr
abstrahiert als Assembler, ohne dass man dabei zwangsweise die
Effektivität einbüßen muss.  Das sieht man an den Bitoperationen
hier (zum Vergleich: Pascal als Lehrsprache hat sowas nicht¹), aber
auch an Konstrukten wie *cp++.  Hätte man derartige Konstrukte nicht
irgendwie in eine höhere Programmiersprache rübergerettet, wären die
Betriebssysteme weiter aufwändig (und fehleranfällig) in Assembler
gehackt worden.

Andererseits dürfte C natürlich heutzutage den umgekehrten Effekt auf
viele CPUs haben: man entwirft sie so, dass sich C möglichst effektiv
drauf implementieren lässt.  Das ist für den AVR dokumentiert, und
die Cortexe haben ja ebenfalls als Entwurfsziel, dass man sie komplett
ohne (expliziten) Assemblercode programmieren kann.

Sich darüber zu streiten, ob das nun gut ist oder nicht, ist ziemlich
müßig.

¹) Bevor die Programmiersprachenglaubenskrieger jetzt alle auffahren:
ja, aktuelle Pascal-Dialekte haben sowas.  Das Wirthsche Pascal, etwa
zur gleichen Zeit wie C entstanden, nur mit einem völlig anderen
Fokus (Lehrsprache vs. Betriebssystemimplementierung) hatte es jedoch
nicht.

: Bearbeitet durch Moderator
von Nob (Gast)


Lesenswert?

Also ich verwende ASM. Ich denke das kann man nicht mit beherrschen 
gleichsetzen wobei ich halbwegs gut klar komme.
C wirkt wesentlich kompakter wobei ich ab Beispiel der If Abfrage soeben 
festgestellt habe, dass dies auf kosten der Verständlichkeit passiert.

von (prx) A. K. (prx)


Lesenswert?

Lothar Miller schrieb:
> Schon nach der Berechnung des Ausdrucks
> PINA&1 stehen die Flags im Prozessor richtig und können ausgewertet
> werden.

Wenn es Flags gibt. Bei MIPS (wie PIC32) gibt es sie nicht...

> Ein zusätzlicher Vergleich auf "ungleich Null" ist unnötig.

...weshalb ein bedingter Sprungbefehl zwei Register vergleicht und 
abhängig davon springt.

von Kai S. (zigzeg)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Kai S. schrieb:
>> Schuster bleib bei Deinen Leisten!
>
> Deine_m_. Der Leisten.

Natürlich "der" Leisten. Aber ein Schuster mit nur einem Leisten wird 
wohl kein erfolgreicher Schuster sein.
Als Sprichwort wird aber wohl beides verwendet - interessant!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> W.S. schrieb:
>> Ob auf einer konkreten Maschine das verunden einer Variablen mit einer
>> Konstanten tatsächlich irgendwelche Flags setzt oder nicht, kann man
>> allein im Manual zu der betreffenden Architektur nachlesen.
>
> Kennst du eine, bei der das nicht der Fall wäre?

Mal abgesehen davon, dass es ziemlich schnurz ist, die eine Maschine 
genau verundet:  Ja, es gibt auch Machinen, bei der ein AND keine 
Flags setzt; etwa auf Maschinen, die (effektiv) kein PSW haben.  Ein 
Beispiel ist Infineon TriCore.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> ...weshalb ein bedingter Sprungbefehl zwei Register vergleicht und
> abhängig davon springt.
Das weiß der Compiler und fügt diesen Vergleich dann eigenhändig ein.

W.S. schrieb:
> Man könnte dort schreiben
> if (PortA.4) DoSomething();
Solche prozessorabängigen Erweiterungen gabs schon für den 8051. Und der 
Lohn? Bei einem Prozessor- oder nur Compilerwechsel viel Handarbeit.

> ( in Assembler
>   BTFSC PortA,4
>   CALL  DoSomeThing
> )
> wenn das in C so vorgesehen wäre. Ist es aber nicht.
Ein brauchbarer C-Compiler macht aber genau das aus dem "Maskencode".

Welche Sprache ist deiner Meinung nach geeigneter und/oder orthogonaler?

von (prx) A. K. (prx)


Lesenswert?

Jörg Wunsch schrieb:
> Kennst du eine, bei der das nicht der Fall wäre?

Klassische Statusregister mit Flags sind mitnichten selbstverständlich. 
Weil Flags singuläre Ressourcen sind, die im Highend-Bereich erheblichen 
Aufwand mit sich bringen.

Neben MIPS war da beispielsweise DEC Alpha eine Architektur ohne Flags. 
PowerPC wiederum hat statt dessen einen separaten Satz von 8 Registern 
für Status-Resultate, bei Intel IA64 sind es noch ein paar mehr. HPs PA 
übersprang den Folgebefehl anhängig vom Resultat eines Vergleichs.

Die x86 Implementierungen treiben grossen Aufwand, um trotz klassischem 
Statusregister nicht dauernd über die eigenen Füsse zu stolpern, dennoch 
entstehen nicht selten unerwünschte und bremsende Abhängigkeiten.

In der Anfangsphase der 8-Bit Mikroprozessoren gab es welche, die 
allenfalls ein Carry-Flag hatten, aber bei Null- oder Vorzeichentests im 
Sprung direkt den Akku überprüften (RCA 1802, NS SC/MP).

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

W.S. schrieb:
> Die Version mit dem
> ? ist bloß kryptischer und unleserlicher, weswegen sie bei vielen
> C-Programmierern den Vorzug hat.

Du wirst keinen Programmierer finden, der völlig auf "if" verzichtet.
Ein guter Programmierer setzt immer jeweils den Operator ein, der für 
die konkrete Aufgabe am besten ist.

Der "?" Operator liefert im Gegensatz zum "if" einen Wert zurück. Das 
kann mit "if" dann wirklich sehr umständlich und kompliziert werden und 
auch der erzeugte Code wird größer und langsamer.

Sind dagegen nur verschiedene Anweisungen auszuführen, wird man dafür 
kaum den "?" Operator benutzen.

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


Lesenswert?

Peter Dannegger schrieb:
>> ? ist bloß kryptischer und unleserlicher, weswegen sie bei vielen
>> C-Programmierern den Vorzug hat.
>
> Du wirst keinen Programmierer finden, der völlig auf "if" verzichtet.

Dafür sehr viele, die den ternären Operator meiden wie der Teufel das
Weihwasser und nur benutzen, wenn es gar nicht anders geht.  Aber das
passt halt nicht in W. S.' Weltbild.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> Die Version mit dem
> ? ist bloß kryptischer und unleserlicher, weswegen sie bei vielen
> C-Programmierern den Vorzug hat.

Im Gegenteil: Die (richtige) Anwendung des ?-Operators fördert die 
Lesbarkeit von C-Programmen. Man kann in C manches kurz und knackig 
formulieren, wofür man in anderen Sprachen eine ganze Litanei 
runtersabbeln muss.

Natürlich kann man in C sehr kryptisch programmieren. Das ist aber 
nicht unbedingt das Ziel des gemeinen C-Programmierers.

Du ratterst hier daher lediglich Vorurteile runter, die man schon in den 
70er Jahren gehört hat, als in Deutschland noch kaum jemand C überhaupt 
kannte. Wie Du am Erfolg von C erkennen kannst (immerhin werden 
mittlerweile damit ganze Betriebssysteme geschrieben), bist Du mit 
Deinen Argumenten irgendwo hinter irgendeinem Planeten auf diesem 
Sonnensystem stehengeblieben.

Was wäre denn für Dich die ideale Programmiersprache?

Hier hast Du eine klitzekleine Auswahl (Vorsicht, Humor nützlich!):

  http://web.archive.org/web/20130930062739/http://helloworldsite.he.funpic.de/hello.htm

von Mark B. (markbrandis)


Lesenswert?

Kai S. schrieb:
> Das bedeutet dass man in C den Code ruhig so schreiben kann, wie es am
> besten lesbar ist.

Dein Wort in Gottes Ohr. So mancher C-Programmierer ist der Meinung, er 
müsste kryptischen Scheiß zusammenschreiben, obwohl er gerade gar nicht 
am IOCCC teilnimmt.

von Dieselwolf (Gast)


Lesenswert?

Frank M. schrieb:
>Wie Du am Erfolg von C erkennen kannst (immerhin werden
>mittlerweile damit ganze Betriebssysteme geschrieben), bist Du mit
>Deinen Argumenten irgendwo hinter irgendeinem Planeten auf diesem
>Sonnensystem stehengeblieben.

Woher kommt denn der "Erfolg"?
Dadurch, daß an den Lehreinrichtungen nichts Anderes unterrichtet 
wird?

Es ist nicht immer das Bessere, das sich durchsetzt.

von Borislav B. (boris_b)


Lesenswert?

Klammern sind für Noobs!
1
if (PINA & 0x01) test1(); // voll krass verkürzt, alter


Bzgl. des ?-Operators:
Ich schreibe (und lese) jedenfalls lieber
1
return isRunning ? GetNextValue() : sDefaultValue;

als
1
if(isRunning)
2
{
3
 return GetNextValue();
4
}
5
else
6
{
7
 return sDefaultValue;
8
}

: Bearbeitet durch User
von Di P. (drpepper) Benutzerseite


Lesenswert?

1
PINA&0x01?a():b();

Der Rückgabetyp von a() und b() muss gleich sein

von Dieselwolf (Gast)


Lesenswert?

Boris schrieb:
>Ich schreibe (und lese) jedenfalls lieber....

Bis Du den Quelltext nach 3-4 Jahren mal wieder in die Hand bekommst
und Änderungen durchführen sollst.
Dann kommt der Moment, wor Du denkst: "Ach hätte ich das doch
übersichtlich geschrieben!"

Die Zeit, die Du da eingespart hattest, gibst Du dann doppelt drauf.

von Karl H. (kbuchegg)


Lesenswert?

Dieselwolf schrieb:
> Boris schrieb:
>>Ich schreibe (und lese) jedenfalls lieber....
>
> Bis Du den Quelltext nach 3-4 Jahren mal wieder in die Hand bekommst

Gerade dann ist das schneller, einfacher und übersichtlicher.
Der ternäre Operator ist ein Operator wie jeder andere auch. Kein Grund 
ihn nicht einzusetzen wo er Sinn macht und einem das Leben leichter 
machen kann.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Di Pi schrieb:
> Der Rückgabetyp von a() und b() muss gleich sein

Es gelten auch da die üblichen Regeln für Operatoren.

von Dieselwolf (Gast)


Lesenswert?

Karl-Heinz behauptete:
>Gerade dann ist das schneller, einfacher und übersichtlicher.

Siehst Du: Für Dich ist die eine Variante übersichtlicher, für einen
Anderen die Andere.

Ich bin aus dem Holz: Quelltexte so ausführlich und eindeutig, wie es
die Syntax der Sprache, die man benutzen muß zulässt.

Wenn man die Wahl hat: Eine Sprache benutzen, die man selbst am 
Vernünftigsten hält.

von Karl H. (kbuchegg)


Lesenswert?

Dieselwolf schrieb:
> Karl-Heinz behauptete:
>>Gerade dann ist das schneller, einfacher und übersichtlicher.
>
> Siehst Du: Für Dich ist die eine Variante übersichtlicher, für einen
> Anderen die Andere.

Was findest du übersichtlicher
1
  if( a ) {
2
    if( b )
3
      func( 1, 2 );
4
    else
5
      func( 1, 4 );
6
  }
7
  else {
8
    if( b )
9
      func( 3, 2 );
10
    else
11
      func( 3, 4 );
12
  }

Die Absicht ist klar:
Wenn a gegeben ist, dann soll die Funktion mit einem Wert von 1 als 
erstem Paramater aufgerufen werden, ansonsten mit einem Wert von 3
Wenn b wahr ist, dann soll die Funktion mit einem Wert von 2 als erstem 
Paramater aufgerufen werden, ansonsten mit einem Wert von 4.

Obiges lässt sich mit dem ternären Operator schreiben als
1
  func( a ? 1 : 3,
2
        b ? 2 : 4
3
       );
und drückt kurz und präzise genau das gewünschte aus. Und zwar ohne das 
man alle möglichen Fallunterscheidungen ausformulieren muss.
Nimm noch eine dritte Bedingung mit dazu und du ertrinkst in if-s und 
else.

Man kann das natürlich schreiben als
1
    if( a )
2
      arg1 = 1;
3
    else
4
      arg1 = 3;
5
6
    if( b )
7
      arg2 = 2;
8
    else
9
      arg2 = 4;
10
11
    func( arg1, arg2 );
und hat damit 2 temporäre Variablen, die eigentlich keiner braucht. An 
die Einfachheit und Übersichtlichkeit, die durch die Verwendung des 
ternären Operators entsteht, kommt aber auch diese Variante nicht ran.

Mir kommt das eher vor, wie auf gut österreichisch:
Wozu braucht man das? Das habn wir noch nie so gemacht. Da könnt ja 
jeder kommen!

Der ternäre Operator ist ein Operator wie jeder andere auch. Er hat 
seine Bedeutung. In manchen Fällen erleichtert er das Leben. In manchen 
Fällen ist er nicht angebracht. Ja, man kann sich damit auch in den Fuss 
schiessen. Aber nur weil man sich damit einen Finger abtrennen kann, ist 
eine Kreissäge noch lange kein verteufelungswürdiges Werkzeug. Auf jeden 
Fall ist allerdings ein Taschenmesser kein Ersatz dafür, nur weil es 
damit schwerer ist, sich die Hand abzutrennen.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Boris P. schrieb:
> Ich schreibe (und lese) jedenfalls lieber
> [...]
> als
>
>
1
> if(isRunning)
2
> {
3
>  return GetNextValue();
4
> }
5
> else
6
> {
7
>  return sDefaultValue;
8
> }
9
>

Das else ist überflüssig:
1
if(isRunning)
2
{
3
  return GetNextValue();
4
}
5
return sDefaultValue;

;-)

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


Lesenswert?

Frank M. schrieb:
> Das else ist überflüssig:

Die geschweiften Klammern nach dem if ebenfalls. ;-)

von Walter Tarpan (Gast)


Lesenswert?

Frank M. schrieb:
> Das else ist überflüssig:
> if(isRunning)
> {
>   return GetNextValue();
> }
> return sDefaultValue;
>
> ;-)

Ob das dann besser lesbar ist...








...aber ich muß zugeben, mir ist auch gerade langweilig genug, daß ich 
darüber diskutieren würde.

von Borislav B. (boris_b)


Lesenswert?

Frank M. schrieb:
> Das else ist überflüssig:

Für den Compiler ja. Für meine Argumentation nicht ;-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Walter Tarpan schrieb:
> Frank M. schrieb:
>> Das else ist überflüssig:
>> if(isRunning)
>> {
>>   return GetNextValue();
>> }
>> return sDefaultValue;
>>
>> ;-)
>
> Ob das dann besser lesbar ist...

Finde ich schon. Am Ende einer non-Void-Funktion sollte immer ein return 
stehen. Dem wird meine Variante eher gerecht ;-)

Aber man könnte herrlich darüber streiten, ob mehrere Ausgänge innerhalb 
einer Funktion überhaupt sinnvoll sind.

> ...aber ich muß zugeben, mir ist auch gerade langweilig genug, daß ich
> darüber diskutieren würde.

Geht mir genauso ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Es ist meist ein Vorteil und selten ein Nachteil, wenn man doppelt
vorkommende Code-Passagen meidet. Für lange Passagen gilt das sowieso,
oft aber auch für kurze. Mit dem ternären Operator lässt sich doppelter
Code in vielen Fällen vermeiden.

Beispiel 1 (ohne ternären Operator, nur zur Motivation):

Schlecht:
1
  array[n+i] = array[n+i] * 2;

Gut:
1
  array[n+i] *= 2;

Denn hier sieht man sofort, dass die Quelle und das Ziel dasselbe
Array-Element ist.


Beispiel 2:

Schlecht:
1
  if(bedingung)
2
  {
3
    array[n+i] = x;
4
  }
5
  else
6
  {
7
    array[n+i] = y;
8
  }

Gut:
1
  array[n+i] = bedingung ? x : y;

Denn hier sieht man sofort, dass dem Array-Element (und nur diesem) auf
jeden Fall ein Wert zugeweisen wird. Nur die Quelle ist von der
Bedingung abhängig, nicht aber das Ziel. Deswegen sollte dieses
außerhalb des bedingt ausgeführten Codes stehen.


Bspiel 3:

Schlecht:
1
  if(bedingung)
2
  {
3
    return x;
4
  }
5
  else
6
  {
7
    return y;
8
  }

Gut:
1
  return bedingung ? x : y;

Denn hier sieht man sofort, dass die Funktion an dieser Stelle endet,
ohne Wenn und Aber. Lediglich der Rückgabewert ist an eine Bedingung
geknüpft, nicht aber die Tatsache, dass die Funktion an diese Stelle zum
Aufrufer zurückkehrt. Deswegen sollte das return außerhalb des bedingt
ausgeführten Codes stehen.

Neben der Verbesserung der Lesbarkeit und des logischen Aufbaus eines
Programms gibt es aber auch Fälle, wo der ternäre Operator sogar
zwingend erforderlich ist oder nur sehr umständlich durch andere
Konstrukte ersetzbar ist. Dazu gehört bspw. die bedingte Intialisierung
von Variablen.

Weil er so nützlich ist, gibt es ihn (teilweise mit anderer Syntax) in
den meisten gängigen Programmierprachen:

  http://en.wikipedia.org/wiki/%3F:

Einfach zu sagen "Will ich nicht, brauch ich nicht, deswegen sofort in
den Müll damit" ist deswegen ein wenig zu kurz gedacht :)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Danke für die schöne Zusammenfassung :)

von W.S. (Gast)


Lesenswert?

Lothar Miller schrieb:
> Ein brauchbarer C-Compiler macht aber genau das aus dem "Maskencode".

Ein guter XYZ-Compiler ist mittlerweile so schlau (genauer: seine 
Verfasser waren so schlau), daß er die hinter einer Formulierung 
steckende Absicht des Schreibers erkennt und nach Abwägung der 
Möglichkeiten der Zielhardware sich den dafür optimalen Maschinencode 
zusammenbastelt. Man sehe sich mal an, was z.B. der Keil aus einem 
C-Quellcode macht, wenn man ihn nur ordentlich optimieren läßt. Es ist 
wirklich erstaunlich.



Dieselwolf schrieb:
> Wenn man die Wahl hat: Eine Sprache benutzen, die man selbst am
> Vernünftigsten hält.

Nachtrag meinerseits: ..sofern diese Sprache für die Zielplattform 
verfügbar ist. Sonst muß man notgedrungen in irgendeinen sauren Apfel 
beißen.


Karl Heinz schrieb:
> Was findest du übersichtlicher
>   if( a ) {
>     if( b )
>       func( 1, 2 );
>     else
>       func( 1, 4 );
>   }
>   else {
>     if( b )
>       func( 3, 2 );
>     else
>       func( 3, 4 );
>   }

Zu allererst fände ich es übersichtlicher, die zugrundeliegenden Blöcke 
erkennen zu können, ohne erst nach den öffnenden Klammern suchen zu 
müssen. Schreibst du etwa immer so?

Als nächstes fände ich es übersichtlicher, sich echte Gedanken über den 
geschriebenen Code zu machen, bevor man ihn in die Tasten haut. 
Üblicherweise bauschen temporäre Variablen weniger auf als eine 
Breitseite von Funktionsaufrufen und überflüssige Klammern.

etwa so:
   if (a)
   { if (b) func(1, 2); else func(1, 4);
   }
   else
   { if (b) func(3, 2); else func(3, 4);
   }

oder etwa so:
int tmpa, tmpb;
tmpa = 3; if (a) tmpa = 1;
tmpb = 4; if (b) tmpb = 2;
func(tmpa, tmpb);

Nochmal dasselbe, diesmal von unserem Programmier-Begeisterten:
Yalu X. schrieb:
> Schlecht:
>   if(bedingung)
>   {
>     array[n+i] = x;
>   }
>   else
>   {
>     array[n+i] = y;
>   }
>
> Gut:
>   array[n+i] = bedingung ? x : y;

und noch besser:

int tmp;
tmp = y;
if (bedingung) tmp = y; //Kommentar, warum
array[beliebig komplizierte Berechnung] = tmp;

Im Grunde geht es nur um wirklich überflüssige Dinge in C. Der ? 
Operator ist de facto überflüssig und trägt nur zur Unleserlichkeit bei, 
genauso wie der Komma-Operator. Sowas wie 'typedef' übrigens auch - oder 
hat jemand dazu eine wirklich stichhaltige Begründung für 'typedef'?


W.S.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> Sowas wie 'typedef' übrigens auch - oder
> hat jemand dazu eine wirklich stichhaltige Begründung für 'typedef'?

Man merkt, daß Du mit C nicht arbeitest, sondern es aus recht 
praxisferner Sicht kritisierst. Offensichtlich hast Du noch nie etwas 
mit Funktionspointern zu tun gehabt.

Deine Definition von "lesbarkeit" weicht auch stark von meiner ab.

Den C-Stil von Karl Heinz finde ich nun auch nicht besonders schön (für 
mich gehören zusammengehörige geschweifte Klammern in die gleiche 
Spalte, und nach öffnenden und vor schließenden runden Klammern gehört 
kein Whitespace, vor öffnende dann, wenn es sich nicht um einen 
Funktionsaufruf handelt) -- aber das sind rein kosmetische Differenzen, 
die sich bei C-Anwendern mit Erfahrung individuell einspielen und 
anpassen. Was die grundliegenden Ansichten zu C betrifft, sehen wir die 
Dinge recht ähnlich.

Ich verdiene mir meinen Lebensunterhalt seit bald 25 Jahren mit C, und 
ich habe schon ziemlich viel fremden C-Code gesehen, insofern bilde ich 
mir ein, ein gewisses Gefühl für Lesbarkeit von C-Code zu haben.

Unnötige Zwischenvariablen, mehrere Anweisungen in einer Zeile etc. sind 
das genaue Gegenteil von lesbarem Code. Code, der so formatiert ist, wie 
Deiner, landet bei mir automatisch in einem "Beautifier", um eine 
lesbare und halbwegs verbreiteten Konventionen übliche Formatierung zu 
erhalten.

von Karl H. (kbuchegg)


Lesenswert?

W.S. schrieb:

> Zu allererst fände ich es übersichtlicher, die zugrundeliegenden Blöcke
> erkennen zu können, ohne erst nach den öffnenden Klammern suchen zu
> müssen. Schreibst du etwa immer so?

Ist eine reine Konventionssache.
Wenn mein Arbeitgeber die Klammern in einer neuen Zeile will, kriegt er 
sich auch dort. Wenn ich für mich schreibe, ist das je nach Projekt 
unterschiedlich. Lange Jahre hab ich die öffnende Klammer ans Zeilenende 
geschrieben, dann wieder ein paar Jahre in eine neue Zeile. Letzten 
Endes macht es für mich wenig Unterschied. Die schliessende Klammer 
steht in der Spalte auf jeden Fall unter der 'Anweisung' in der die 
öffnende steht. Ob da jetzt die öffnende Klammer alleine steht, oder ob 
die in dieser Zeile am Zeilenende steht, ist mit persönlich mitlerweile 
egal. Ich finde in beiden Formatierungen optisch die jeweils öffnende 
Klammer recht zuverlässig - das hat sich längst automatisiert ohne dass 
ich groß darüber nachdenken muss.
Viel wichtiger ist die konsistente Einrückung.

> etwa so:
>    if (a)
>    { if (b) func(1, 2); else func(1, 4);
>    }
>    else
>    { if (b) func(3, 2); else func(3, 4);
>    }

Wer mir allerdings so etwas als 'guten Stil' unterjubeln will, den nehm 
ich nicht mehr ernst. Sorry.


Dein einziges Argument gegen den ?: Operator ist: Ein ? in einem Code 
kommt mir seltsam vor, daher verteufle ich das erst mal.

: Bearbeitet durch User
von Dumdi D. (dumdidum)


Lesenswert?

W.S. schrieb:
> und noch besser:
>
> int tmp;
> tmp = y;
> if (bedingung) tmp = y; //Kommentar, warum
> array[beliebig komplizierte Berechnung] = tmp;

Finde ich nicht. Wie man sieht schleichen sich da auch leicht Fehler 
ein. (In der dritten Zeile meintest Du vermutlich 'x' statt 'y')
Habe ich aber erst beim 2ten lesen gesehen, es ist halt unübersichtlich.

von (prx) A. K. (prx)


Lesenswert?

W.S. schrieb:
> Sowas wie 'typedef' übrigens auch - oder
> hat jemand dazu eine wirklich stichhaltige Begründung für 'typedef'?

Wie willst du sowas wie int16_t definieren, wenn du keine Typedefs hast? 
#define ist zwar im Prinzip möglich, aber ich stimme mit Stroustrup 
dahingehend überein, dass man den Präprozessor so sparsam wie möglich 
verwenden sollte. Dieser Mischmasch aus zwei sehr unterschiedlichen 
Sprachen (Präprozessor / C[++]) ist nicht sauber und hinsichtlich 
Namescopes grad in grossen Projekten recht problematisch.

Unglücklich bin ich über typedef nur, was die syntaktische Seite angeht. 
In die Grammatik passen sie nicht sauber hinein. Aber das wurde 
letztlich schon mit der Erfindung von C verbockt, wo typedefs erst 
nachträglich hinzugefügt wurden.

: Bearbeitet durch User
von foo (Gast)


Lesenswert?

Tja, jeder wie er will.
Bei meinen Funktionen gibt es genau einen Returnpfad.
1
uint8 foo(void)
2
{
3
    uint8 r;
4
5
    if(bedingung)
6
    {
7
        r = 1u;
8
    }
9
    else
10
    {
11
        r = 2u;
12
    }
13
14
    return(r);
15
}

von Der Experte (Gast)


Lesenswert?

W.S. schrieb:
> oder
> hat jemand dazu eine wirklich stichhaltige Begründung für 'typedef'?
Java hat's ja auch nicht!
Duck und weg

von Mark 99 (Gast)


Lesenswert?

foo schrieb:
> Tja, jeder wie er will.
> Bei meinen Funktionen gibt es genau einen Returnpfad.
> uint8 foo(void)
> {
>     uint8 r;
>
>     if(bedingung)
>     {
>         r = 1u;
>     }
>     else
>     {
>         r = 2u;
>     }
>
>     return(r);
> }

Ja, kann man zur Religion erheben. Man kann sich auch auf den Standpunkt 
stellen, dass man erst Predicates teste (ganz modernes Zeug ...), bevor 
es im eigentliche Code ohne Beiwerk zur Sache geht.
1
uint8_t bla(int i) {
2
    // Check predecates - see function documentation for contract
3
    if(i < 0 || i > MAGIC_MAX) {
4
        return BLA_OUT_OF_RANGE;
5
    }
6
7
    if(condition != COND0 || condition == COND_STRANGE) {
8
        return BLA_COND_IN_WRONG_STATE;
9
    }
10
11
12
    //
13
    // Perform the required bla() magic
14
    //
15
    return condition ? BLA1 : BLA2;

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


Lesenswert?

foo schrieb:
> Bei meinen Funktionen gibt es genau einen Returnpfad.

Besonders bei größeren Funktionen mit vielen Bedingungen kann das
schnell ein ausgesprochen unübersichtliches Geschachtel werden.

von Mark B. (markbrandis)


Lesenswert?

foo schrieb:
> Tja, jeder wie er will.
> Bei meinen Funktionen gibt es genau einen Returnpfad.
>
>
1
> uint8 foo(void)
2
> {
3
>     uint8 r;
4
> 
5
>     if(bedingung)
6
>     {
7
>         r = 1u;
8
>     }
9
>     else
10
>     {
11
>         r = 2u;
12
>     }
13
> 
14
>     return(r);
15
> }

Noch besser, weil kürzer:

1
uint8 foo(void)
2
{
3
    uint8 r = 2u;
4
5
    if(bedingung)
6
    {
7
        r = 1u;
8
    }
9
10
    return (r);
11
}


Jörg Wunsch schrieb:
> Besonders bei größeren Funktionen mit vielen Bedingungen kann das
> schnell ein ausgesprochen unübersichtliches Geschachtel werden.

Korrekt. Bei kleineren Funktionen à la get_value() kann man es aber 
schon sehr gut so machen.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Mark Brandis schrieb:
> Korrekt. Bei kleineren Funktionen à la get_value() kann man es aber
> schon sehr gut so machen.

Also genau da, wo es sich nicht lohnt. ;-)

von Mark B. (markbrandis)


Lesenswert?

A. K. schrieb:
> Also genau da, wo es sich nicht lohnt. ;-)

Was soll sich da nicht lohnen? Obiges Beispiel ist extrem gut lesbar. 
Und wartbar. Und der MISRA Checker freut sich. Und überhaupt. :-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mark Brandis schrieb:
> Noch besser, weil kürzer:
>
>
>
1
> uint8 foo(void)
2
> {
3
>     uint8 r = 2u;
4
> 
5
>     if(bedingung)
6
>     {
7
>         r = 1u;
8
>     }
9
> 
10
>     return (r);
11
> }
12
>

Suboptimal. Wenn bedingung gegeben ist, werden überflüssigerweise 2 
Zuweisungen gemacht.

(Vielleicht ist der gcc so schlau, dass er in dem obigen 
Trivial-Beispiel die 2u-Zuweisung intern in ein "else" packt. Aber davon 
würde ich nicht unbedingt ausgehen)

von Robert K. (murdok)


Lesenswert?

MISRA C 2004:

14.7 (req): A function shall have a single point of exit at the end of 
the function.

Wenn man für die Industrie nach gewissen Prozessen und zur Erreichung 
einer festgelegten SW-Qualität fertigt bleibt oft nicht viel 
'Wahlmöglichkeit' ;-)

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Mark Brandis schrieb:
> Was soll sich da nicht lohnen? Obiges Beispiel ist extrem gut lesbar.
> Und wartbar. Und der MISRA Checker freut sich. Und überhaupt. :-)

Bei einer solchen Zwergfunktion wie oben ist es für Verständnis und 
Überblick ziemlich irrelevant. Das lohnt erst wirklich bei grösseren 
Funktionen, bei denen man sich sonst stunden/tagelang wundert, weshalb 
der Aufräumcode am Schluss der Funktion manchmal ignoriert wird.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Robert K. schrieb:
> MISRA C 2004:
>
> 14.7 (req): A function shall have a single point of exit at the end of
> the function.

Ich muss da Jörg schon Recht geben. Wenn man das bei größeren Funktionen 
ohne wenn und aber durchhalten will, dann muss man manchmal ziemliche 
Verrenkungen machen. Man schleppt dann den Return-Code durch alle 
möglichen Fallunterscheidungen (evtl. über mehrere Ebenen) mit.

Ein vorzeitiges bedingtes return kann da schon mal Klarheit im Code 
schaffen. Danach kanns nämlich meist unbedingt (d.h. auf höchster Ebene 
in der Funktion) weitergehen.

von Cyblord -. (cyblord)


Lesenswert?

Frank M. schrieb:
> Robert K. schrieb:
>> MISRA C 2004:
>>
>> 14.7 (req): A function shall have a single point of exit at the end of
>> the function.
>
> Ich muss da Jörg schon Recht geben. Wenn man das bei größeren Funktionen
> ohne wenn und aber durchhalten will, dann muss man manchmal ziemliche
> Verrenkungen machen. Man schleppt dann den Return-Code durch alle
> möglichen Fallunterscheidungen (evtl. über mehrere Ebenen) mit.

Dann sind vielleicht die Funktionen auch einfach zu groß. Wer eine 
riesige Funktion hat, macht meist schon was falsch.

von Michael (Gast)


Lesenswert?

Frank M. schrieb:
> Suboptimal. Wenn bedingung gegeben ist, werden überflüssigerweise 2
> Zuweisungen gemacht.

Tragisch. Das sind schon wieder Nanosekunden, die verloren gehen.

Und der gcc ist natürlich - wie so ziemlich jeder Compiler der letzten 
zwanzig Jahre - clever genug, das zu optimieren.

von (prx) A. K. (prx)


Lesenswert?

Frank M. schrieb:
> Ein vorzeitiges bedingtes return kann da schon mal Klarheit im Code
> schaffen. Danach kanns nämlich meist unbedingt (d.h. auf höchster Ebene
> in der Funktion) weitergehen.

Wobei man dann mit C++ besser dran ist. Weil man Aufräumcode in 
Destruktoren lokaler Daten verfrachten kann, statt sie an jenes Ende der 
Funktion zu packen, das beim vorzeitigen C-return links liegen gelassen 
wird.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Michael schrieb:
> Und der gcc ist natürlich - wie so ziemlich jeder Compiler der letzten
> zwanzig Jahre - clever genug, das zu optimieren.

Die Welt besteht nicht nur aus gcc.

Du hast leider keine Ahnung, wie (teilweise absichtlich!) dumm manche 
Compiler wirklich sind. Schau Dir den XC8 PIC-Compiler an. Der streut 
nicht nur überflüssige Befehle in den erzeugten Code, sondern übersetzt 
Divisionen und Modula-Operationen mit Zweierpotenzen nicht als Schiebe- 
bzw. Maskierungsbefehle, sondern fängt tatsächlich an, echte 
int16-Divisionen draus zu machen. Da wird man ja regelrecht gezwungen, 
dass man den Code cryptischer formuliert, damit dem Compiler auf die 
Sprünge geholfen werden kann.

(Aufgefallen bei der Portierung von IRSND (dem Pendant von IRMP) auf 
PIC XC8)

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Wobei man dann mit C++ besser dran ist. Weil man Aufräumcode in
> Destruktoren lokaler Daten verfrachten kann, statt sie an jenes Ende der
> Funktion zu packen, das beim vorzeitigen C-return links liegen gelassen
> wird.

Da hast Du allerdings recht. Bei einem vorzeitigen return kann man schon 
mal vergessen, irgendwas wieder wegzuräumen. Und wenn man es 
tatsächlichn machen muss, dann stehts doppelt in der Funktion. Ist 
unschön und erhöht den Pflegeaufwand, stimmt.

von (prx) A. K. (prx)


Lesenswert?

Ausschliesslich für kleine Mikrocontroller bestimmte Compiler sind bei 
Optimierung nicht annähernd auf dem Standard von GCC. Einerseits weil 
hinter GCC 3 Jahrzehnte Optimierung für Highend-Maschinen stecken. 
Andererseits weil zu viel unerwartete Optimierung im Kundenkreis 
unerwünscht ist.

Auch unter den Kennern der Freiheitsgrade von C sieht es beispielsweise 
nicht jeder gerne, wenn die teure Division, die er eigens vor der 
Interrupt-Sperre in den Code einstreute, vom GCC seelenruhig dorthin 
verschoben wird, wo der Quotient benötigt wird. Genau mitten in die 
gesperrte Zeit hinein.

: Bearbeitet durch User
von Michael (Gast)


Lesenswert?

Frank M. schrieb:
> Du hast leider keine Ahnung, wie (teilweise absichtlich!) dumm manche
> Compiler wirklich sind.

Und die eine Zuweisung bringt dich jetzt um?

Vor allem immer und überall. So daß du die Nanosekunde nicht nur an der 
einen so hochkritischen Stelle einsparen willst, sondern auch in dem 
Programmteil, der sich gerade langweilt, bis der Benutzer mal wieder was 
eingegeben hat?

von (prx) A. K. (prx)


Lesenswert?

Frank M. schrieb:
> Da hast Du allerdings recht. Bei einem vorzeitigen return kann man schon
> mal vergessen, irgendwas wieder wegzuräumen. Und wenn man es
> tatsächlichn machen muss, dann stehts doppelt in der Funktion. Ist
> unschön und erhöht den Pflegeaufwand, stimmt.

Da ich mich nicht mit MISRA rumschlagen muss bin ich in solchen Fällen 
auch so frei, ab und an mal ein goto unterzubringen. Nämlich von 
Mittendrin zum  Aufräumschwanz der Funktion. Und da dort ein Label steht 
sollte dann auch der dümmste merken, dass irgendwo ein goto sein könnte.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Michael schrieb:
> Frank M. schrieb:
>> Du hast leider keine Ahnung, wie (teilweise absichtlich!) dumm manche
>> Compiler wirklich sind.
>
> Und die eine Zuweisung bringt dich jetzt um?

Nein, das hat konkret mit der einen Zuweisung nichts zu tun. Aber mit 
der Einstellung des Programmierers zum Compiler.

Viele PC-Programme werden von Version zu Version immer langsamer. Warum? 
Weil die Programmierer immer undisziplinierter werden: "Das macht schon 
der Compiler". Oder: "Wer heute keine 4GB im PC hat, ist halt draußen!".

> Vor allem immer und überall. So daß du die Nanosekunde nicht nur an der
> einen so hochkritischen Stelle einsparen willst, sondern auch in dem
> Programmteil, der sich gerade langweilt, bis der Benutzer mal wieder was
> eingegeben hat?

Es geht nicht um eine Nanosekunde, sondern um zigtausend mal 1 
Nanosekunde.

von (prx) A. K. (prx)


Lesenswert?

Frank M. schrieb:
> Viele PC-Programme werden von Version zu Version immer langsamer. Warum?
> Weil die Programmierer immer undisziplinierter werden:

Nö. Nicht auf der Ebene. Nicht solcher Kleinscheiss mördert die 
Performance, sondern hinzu kommende Funktionalität, die ihren Preis hat. 
Die Performance geht dann im Vorfeld verloren, bei Leuten, die die 
Kosten nicht rechtzeitig abschätzen können.

Wenn du im Profiling den Hotspot deines Programms gefunden hast, oder 
ihn sowieso schon kennst, dann kannst du dich sehr konkret diesem 
Bisschen Code widmen. Deshalb das ganze Programm auf die Nanosekunde zu 
tunen, zu Lasten der Wartbarkeit, ist nicht ratsam.

Frank M. schrieb:
> Es geht nicht um eine Nanosekunde, sondern um zigtausend mal 1
> Nanosekunde.

Also einige zig Mikrosekunden. Grosse Sache! ;-)

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Frank M. schrieb:
>> Viele PC-Programme werden von Version zu Version immer langsamer. Warum?
>> Weil die Programmierer immer undisziplinierter werden:
>
> Nö. Nicht auf der Ebene. Nicht solcher Kleinscheiss mördert die
> Performance, sondern hinzu kommende Funktionalität, die ihren Preis hat.

Okay, ich will mich ja auch nicht an dem "Kleinscheiss" aufhängen. Auch 
wenn Kleinvieh u.U. auch Mist macht ;-)

> Die Performance geht dann im Vorfeld verloren, bei Leuten, die die
> Kosten nicht rechtzeitig abschätzen können.

Ja, wahrscheinlich hast Du mit dieser Einschätzung recht.

von Michael (Gast)


Lesenswert?

Frank M. schrieb:
> Es geht nicht um eine Nanosekunde, sondern um zigtausend mal 1
> Nanosekunde.

Und das ändert was?

von foo (Gast)


Lesenswert?

Frank M. schrieb:
> Viele PC-Programme werden von Version zu Version immer langsamer. Warum?
> Weil die Programmierer immer undisziplinierter werden: "Das macht schon
> der Compiler". Oder: "Wer heute keine 4GB im PC hat, ist halt draußen!".

Nein, das liegt vor allem an den verwendeten Algorithmen und 
Softwarearchitekturen, an dem verwenden von Libs wo keiner weiß was die 
tun usw..

von Random .. (thorstendb) Benutzerseite


Lesenswert?

:-)
1
led_out(1 << (ledCnt = ++ledCnt<8 ? ledCnt : 0));  // feed the running light

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Michael schrieb:
> Und das ändert was?

Nichts.

Warum soll ich mich mit Dir über Nanosekunden unterhalten, wenn schon 
ein NOP auf einem mit 8MHz getakteten ATMega ein Vielfaches davon 
braucht?

Daher für mich hier EOD - Höflich ausgedrückt.

: Bearbeitet durch Moderator
von Michael (Gast)


Lesenswert?

Du hast also wirklich keine Argumente. Dann mach doch lieber 
End-of-Forumsteilnahme draus.

von Cyblord -. (cyblord)


Lesenswert?

Frank M. schrieb:

> Daher für mich hier EOD

"End of days" mit dem Gouvernator in der Hauptrolle? Handwerklich gut 
gemachter Actionfilm, lebt hauptsächlich vom Hauptdarsteller mit etwas 
eingestreutem Mystery. Einige Lücken in der Handlung aber das ist normal 
in dem Genre. Guter Durchschnitt.
Aber hey wir sind hier doch nicht im Cineasten Forum.

von Mark B. (markbrandis)


Lesenswert?

Random ... schrieb:
> :-)
1
led_out(1 << (ledCnt = ++ledCnt<8 ? ledCnt : 0));  // feed the running light

Fällt durch jedes Code Review sofort durch ;-)

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Mark Brandis schrieb:
> Fällt durch jedes Code Review sofort durch ;-)

Ja, wegen der fehlenden Leerzeichen vor und nach dem "<"-Operator. :-)

von Cyblord -. (cyblord)


Lesenswert?


von Yalu X. (yalu) (Moderator)


Lesenswert?

Jörg Wunsch schrieb:
> Mark Brandis schrieb:
>> Fällt durch jedes Code Review sofort durch ;-)
>
> Ja, wegen der fehlenden Leerzeichen vor und nach dem "<"-Operator. :-)

Und vor allem, weil "running light" die völlig falsche englische
Übersetzung von "Lauflicht" (was hier wohl gemeint war) ist ;-)

von Random .. (thorstendb) Benutzerseite


Lesenswert?


: Bearbeitet durch User
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.