Forum: Mikrocontroller und Digitale Elektronik if condition schöner schreiben?


von Elias *. (green_phanta)


Lesenswert?

Hi Leute,

ich habe folgendes if-Statement:
1
if( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24 <= i && i <= 27){ // something }

1) Es funktioniert, aber ich wollte fragen ob es eine schönere Lösung 
dafür gibt?

2) Und wie sieht es mit der Effizienz aus? Brauchen diese ANDs und ORs 
viel Prozessorpower?

Danke!

: Bearbeitet durch User
von programmierer (Gast)


Lesenswert?

Ich würde es so lassen, ich finde es gut lesbar.
Alternativ kannst du einen Switch verwenden oder "else if" Anweisungen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Elias *. schrieb:
> Es funktioniert, aber ich wollte fragen ob es eine schönere Lösung
> dafür gibt?

 Was soll da ohne Klammern richtig funktionieren ?

programmierer schrieb:
> Ich würde es so lassen, ich finde es gut lesbar.

 Ja, sicher.
 Erkläre mir mal bitte,  was da womit gemacht wird ?

von Peter II (Gast)


Lesenswert?

Elias *. schrieb:
> 1) Es funktioniert, aber ich wollte fragen ob es eine schönere Lösung
> dafür gibt?

eventuell so
1
if ( i > 0 && < i 28 && ( i & 4 == 0 ) ) { }

: Bearbeitet durch Moderator
von der mechatroniker (Gast)


Lesenswert?

Wenn es einen Grund gibt, warum ausgerechnet die durch 4 teilbaren 
Zahlen ausgenommen sind, ist letzterer Vorschlag sicher der beste. Das 
hätte ich nämlich beim Lesen des Ursprungscodes nicht gleich erkannt.

von Elias *. (green_phanta)


Lesenswert?

Marc V. schrieb:
> Was soll da ohne Klammern richtig funktionieren ?

1
if( (0 <= i && i <= 3) || (8 <= i && i <= 11) || (16 <= i && i <= 19) || (24 <= i && i <= 27) ){ // something }

Ich hab's gerade aus dem Kopf geschrieben und die Klammern vergessen … 
es ging mir eher ums "Konzept". Aber klar ohne geht es natürlich nicht.

Aber hast du noch eine Idee das anders zu schreiben? Und Effizienz?

von Stefan F. (Gast)


Lesenswert?

Der folgende Ratschlag stammt von meiner Erfahrung mit Java, ist aber 
sicher ebenso 1:1 in C anwendbar:

Dass dein Ausdruck praktisch unlesbar ist, sollte offensichtlich sein. 
Lesbarer code ist für langfristig zu pflegende Projekte aber viel 
wichtiger, als kompakter Code. Zerlegen den Ausdruck in Teilausdrücke:
1
boolean userDarfMachen = (usersRole==3 || usersRole==2 && usersOption.contains(whatever))
2
boolean zeitErlaubt = (jetzt>=mindate && jetzt<=maxDate);
3
boolean systemIstBereit = (i>=3 && (j<<x || k==0));
4
5
if (userDarfMachen && zeitErlaubt && systemIstBereit )
6
{
7
   tuwas;
8
}

Zu deiner 2. Fragen: In der C Sprache sind Regeln festgelegt, nach denen 
der Compiler solche langen Ausdrücke optimieren darf. Diese Regeln 
lassen aber noch einige Details unbestimmt. Alle mir bekannten Compiler 
lassen auf der rechten Seite Teile weg, wenn das Ergebnis nach 
Betrachtung der linken Seite schon klar ist. Zum Beispiel:
1
a==3 && b==5

Wenn A nicht den Wert 3 hat, dann wird b gar nicht mehr geprüft. Man 
verwendet das oft, um Dereferenzierung von Null-Zeigern zu vermeiden. 
Ein Beispiel in Java:
1
if (user!=null && user.isAdmin()) {...}

The Methode user.isAdmin() wird nicht aufgrufen, wenn user null ist.

Bei meinem obigen Vorschlag mit den booleanschen Zwischenvariablen 
erhälst du besser lesbaren Code, weil die Teilaudrücke nun Namen 
bekommen haben. Allerdings kann der Compiler dann nicht mehr so viele 
Teilschritte weg lassen (verglichen mit allem in einer Zeile).

Aber wie gesagt ist gut lesbarer Code meistens wichtiger, als optimale 
Performance. Alternativ kann man die Teilausdrücke in Funktionsaufrufe 
verkapseln. Dann hat man auch sprechende Namen und der Compiler kann sie 
immer noch überspringen, wenn der linke Teil des Gesamt-Ausdruckes schon 
das Gesamtergebnis bestimmt:
1
boolean userDarfMachen(int userRole, optionen* usersOption)
2
{
3
    return (usersRole==3 || usersRole==2 && usersOption.contains(whatever));
4
}
5
6
boolean zeitErlaubt(datum jetzt)
7
{
8
    return (jetzt>=mindate && jetzt<=maxDate);
9
}
10
11
boolean systemIstBereit(void)
12
{
13
    return (i>=3 && (j<<x || k==0));
14
15
if (userDarfMachen(userRole,usersOption) && zeitErlaubt(jetzt) && systemIstBereit() )
16
{
17
   tuwas;
18
}

PS: Da sind jetzt sicher ein paar kleine syntaktische Fehler drin. Ich 
bitte um Entschuldigung dafür. Es ging mir nur darum, das Prinzip 
darzustellen.

von Paddy (Gast)


Lesenswert?

if (i & 0b11100100 == 0) ...

leitet zum gleichen funktion (ausgehende von UInt8 i). Ob dies eine 
schoenere loesung ist, ist abhaengig was die inhalt von i bedeutet. Hat 
es etwas mit separate bits zu tun (bit-masking) ? Ist es ein counter der 
nichts mit separaten bits zu tun hat ?

Um deine Fragen zu beantworten musz man wissen warum man diesen test 
machen woll.

Dann die Frage ob dieses viel prozessorpower benutzt :
Ist das wichtig ? Wenn nicht so wichtig, bevorzuge ich eine deutliche 
code ueber eine schnelle code. Abhangig von Kompiler wird deine code und 
mein beispiel wahrscheinlich dieselbe code generieren.

von Stefan F. (Gast)


Lesenswert?

> Brauchen diese ANDs und ORs viel Prozessorpower?

Nein, das sind so ziemlich die schnellsten und einfachsten Operationen, 
die der Mikrocontroller beherrscht. Zudem optimiert der Compiler schon 
einiges weg, wenn er kann. Und er kann das gut.

von Tommi (Gast)


Lesenswert?

Oder untereinander?
1
if( ( 0 <= i && i <=  3) || 
2
    ( 8 <= i && i <= 11) ||
3
    (16 <= i && i <= 19) || 
4
    (24 <= i && i <= 27) ){
5
  // something
6
}

von Toni M. (mondeo)


Lesenswert?

Hallo,

Marc V. schrieb:

>  Was soll da ohne Klammern richtig funktionieren ?

Wenn ich mich recht entsinne gibt es bei C Prioritäten die den Ablauf in 
einem längeren Ausdruck regeln. Die unterschiedlichen Operatoren werden 
nach sinkender Priorität ausgeführt. && hat dabei eine höhere Prio als 
||. Womit die && ausgeführt würden, bevor die || an der Reihe wären.

Oder liege ich da falsch?

Das es mit Klammern lesbarer wird ist keine Frage.

von Little B. (lil-b)


Lesenswert?

Marc V. schrieb:
> Elias *. schrieb:
>> Es funktioniert, aber ich wollte fragen ob es eine schönere Lösung
>> dafür gibt?
>
>  Was soll da ohne Klammern richtig funktionieren ?
>
> programmierer schrieb:
>> Ich würde es so lassen, ich finde es gut lesbar.
>
>  Ja, sicher.
>  Erkläre mir mal bitte,  was da womit gemacht wird ?

Das erste Beispiel ist nach C-Standard ausreichend.
C Operatoren haben Prioritäten, die im Standard festgelegt sind.
http://en.cppreference.com/w/c/language/operator_precedence

Wenns nicht funktionieren sollte, dann gibts mecker für den 
Compiler-Hersteller.

von Cyblord -. (cyblord)


Lesenswert?

Man schreibt so was schöner, in dem man abstrahiert:
1
if (valueCanDividedBy4(i)) {
2
}

Die Funktion selber kann dann zwar auch unschön aussehen, aber allein 
ihr Name verrät dann bereits was sie tut und im Hauptprogramm ist alles 
gut leserlich.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

ausrollen geht manchmal.
1
switch(i)
2
{
3
case 0:
4
case 1:
5
case 2:
6
case 3:
7
8
case 8:
9
case 9:
10
case 10:
11
case 11:
12
13
case 16:
14
case 17:
15
case 18:
16
case 19:
17
18
case 24:
19
case 25:
20
case 26:
21
case 27:
22
         doSomething(); 
23
         break;
24
}
Hier ist aber Peters Lösung besser.

Bei Deinem Code würde ich Klammern und anordnen:
1
if(  ( 0 <= i && i <=  3) 
2
   ||( 8 <= i && i <= 11)
3
   ||(16 <= i && i <= 19)
4
   ||(24 <= i && i <= 27)
5
   )
6
{
7
    doSomething();
8
}
Dann erkennt man die Gesetzt besser.

Mit Peters Erkenntnis ginge auch (falls dies der Aufgabe näher kommt)
1
switch(i>>2)
2
{
3
    case 0:
4
    case 2:
5
    case 4:
6
    case 6: doSomething();
7
}
8
9
10
oder einfacher (und am Schnellsten!)
11
12
if((i&(~27)==0) doSomething();

von Peter II (Gast)


Lesenswert?

Cyblord -. schrieb:
> Man schreibt so was schöner, in dem man abtrahiert:
> if (valueCanDividedBy4(i)) {
> }

man kann es aber auch klar übertreiben.
1
if ( a_groeser_b(a,b) && a_ist_gleich_5(a) && c_ungleich_null(c) )

von Cyblord -. (cyblord)


Lesenswert?

Peter II schrieb:
> Cyblord -. schrieb:
>> Man schreibt so was schöner, in dem man abtrahiert:
>> if (valueCanDividedBy4(i)) {
>> }
>
> man kann es aber auch klar übertreiben.
>
>
1
> if ( a_groeser_b(a,b) && a_ist_gleich_5(a) && c_ungleich_null(c) )
2
>

Kann man. Muss man aber nicht. Und mein Beispiel war in Ordnung, 
wohingegen deins Nonsense ist.
Da man an den Beispielen oben schön sieht, dass es eben NICHT mit einem 
Vergleich getan ist. Und am Ende kommen IMMER noch Bedingungen dazu, 
z.B. negative Zahlen usw.
Und das fängt man am übersichtlichsten mit einer Funktion ab.

: Bearbeitet durch User
von Johann L. (radiostar)


Lesenswert?

Elias *. schrieb:
> 1) Es funktioniert, aber ich wollte fragen ob es eine schönere Lösung
> dafür gibt?

- indem man's übersichtlicher aufschreibt:

if ((0 <= i && i <= 3) ||
    (8 <= i && i <= 11) ||
    (16 <= i && i <= 19) ||
    (24 <= i && i <= 27) )

wird doch gleich viel übersichtlicher, oder?

- oder indem man sich überlegt, welche Systematik dahinter liegt:

if ((i & 0xFFE7) < 4)

von Cyblord -. (cyblord)


Lesenswert?

> if((i&(~27)==0) doSomething();

Genau wegen sowas ist C verpönt. Es geht NICHT um die kürzest mögliche 
Schreibweise, sondern darum dem Leser schnell zu sagen, was der Code tut 
und WARUM. Und das sieht man hier eben nicht. Die Kürze alleine bringt 
keinerlei Informationen.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Elias *. schrieb:
> Aber hast du noch eine Idee das anders zu schreiben? Und Effizienz?

 Stefan U. hat dir schon eine Antwort geschickt, aber trotzdem...
 Erstens, sehen was überhaupt erreicht werden soll und was
 dementsprechend geprüft werden muss.
 Danach versuchen, es so kurz und so übersichtlich zu schreiben wie
 nur möglich.

 Was die Effizienz betrifft:
 If Abfragen sind die schnellsten und kürzesten, Compiler versucht
 alles mit If-Abfragen zu lösen.

Achim S. schrieb:
> switch(i>>2)


 switch wird immer zu If-Abfragen übersetzt, ist aber in der Regel
 viel übersichtlicher als die entsprechenden If-Abfragen.

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Toni M. schrieb:
> Die unterschiedlichen Operatoren werden
> nach sinkender Priorität ausgeführt. && hat dabei eine höhere Prio als
> ||. Womit die && ausgeführt würden, bevor die || an der Reihe wären.

Genau.

Und die Klammern nur deshalb, weil man sie nicht schreiben muß 
wegzulassen, ist kein guter Stil. Der Leser fragt sich dann: ist das ein 
ganz Schlauer oder hat er die Klammern vergessen? Die Schleife kann man 
beiden Seiten ersparen.

"if it was hard to write it doesn't need to be hard to read"

von Markus F. (mfro)


Lesenswert?

Marc V. schrieb:
> switch wird immer zu If-Abfragen übersetzt

Nö.

Wenn er will (und der Ansicht ist, daß es sich lohnt), macht der 
Compiler da auch mal eine Sprungtabelle draus.

von Toni M. (mondeo)


Lesenswert?

Markus F. schrieb:
> Toni M. schrieb:
>> Die unterschiedlichen Operatoren werden
>> nach sinkender Priorität ausgeführt. && hat dabei eine höhere Prio als
>> ||. Womit die && ausgeführt würden, bevor die || an der Reihe wären.
>
> Genau.
>
> Und die Klammern nur deshalb, weil man sie *nicht schreiben muß*
> wegzulassen, ist kein guter Stil.

Deshalb sagte ich ja auch, dass es außer Frage steht was lesbarer ist. 
Es ging nur darum das behauptet wurde, es würde ohne Klammern nicht 
funktionieren. Das ist aber falsch. Nicht mehr und nich weniger ;)

von A. S. (Gast)


Lesenswert?

Cyblord -. schrieb:
> Genau wegen sowas ist C verpönt. Es geht NICHT um die kürzest mögliche
> Schreibweise, sondern darum dem Leser schnell zu sagen, was der Code tut
> und WARUM. Und das sieht man hier eben nicht. Die Kürze alleine bringt
> keinerlei Informationen.

Ist ja richtig. Nur hier fehl am Platz. Auch ich habe mehrere Varianten 
beschrieben. Keine bisher vorgestellt ist sinnvoll, da letztendlich 
unleserlich.

Ich vermute gar, dass der Thread-Ersteller tatsächlich irgendein 
Register überwacht. Da sind dann Bitvergleiche die sinnvollere Wahl. 
Natürlich nicht mit 27 sondern 0x1b bzw. direkt 0xe4.
1
/* Tu was wenn keines der Status-bits 765__2__ gesetzt */
2
if((i&0xe4)==0) DoSomething();

von Cyblord -. (cyblord)


Lesenswert?

Achim S. schrieb:
> Cyblord -. schrieb:
>> Genau wegen sowas ist C verpönt. Es geht NICHT um die kürzest mögliche
>> Schreibweise, sondern darum dem Leser schnell zu sagen, was der Code tut
>> und WARUM. Und das sieht man hier eben nicht. Die Kürze alleine bringt
>> keinerlei Informationen.
>
> Ist ja richtig. Nur hier fehl am Platz. Auch ich habe mehrere Varianten
> beschrieben. Keine bisher vorgestellt ist sinnvoll, da letztendlich
> unleserlich.

Was war an meinem Beispiel denn nun unleserlich?

>
> Ich vermute gar, dass der Thread-Ersteller tatsächlich irgendein
> Register überwacht.

Nun ja, wir wissen nicht WARUM er das machen will, was er tut, darum ist 
es schwer einen guten Namen dafür zu finden. Aber WENN wir es wüssten, 
könnte man diese Funktionalität sehr gut kapseln.

Dem Hauptprogramm sollte es nämlich ziemlich egal sein, ob nun ein 
Register überwacht wird, oder sonst was. Es will eine Bedingung prüfen. 
WIE diese geprüft wird, will man dort nicht sehen.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Toni M. schrieb:
> Es ging nur darum das behauptet wurde, es würde ohne Klammern nicht
> funktionieren. Das ist aber falsch. Nicht mehr und nich weniger ;)

 Ohne Klammern funktioniert das nur zufällig und nur mit diesem
 Ausdruck.
 Ein Mensch kann ganz einfach nicht mehr als 2 Zustände miteinander
 vergleichen, das Resultat wird dann mit nächsten Ausdruck verglichen
 usw.
 Dabei muss aber auch die Priorität beachtet werden...

 Irgendwo weiter oben war ein Beispiel wie das Ganze viel
 übersichtlicher geschrieben werden kann, zumindest für normale
 Menschen. Ob ich etwas mit einem Blick prüfen kann, oder ob ich
 mehrere Minuten mit Finger darüber rätseln muss was der Author
 überhaupt prüfen will, macht schon einen Unterschied.

 Masochismus nennt man so etwas.

von programmierer (Gast)


Lesenswert?

Das war ja klar, dass eine solche Frage einen Glaubenskrieg auslöst.
An den TE: Wie du siehst, bevorzugt jeder etwas anderes.

Marc V. schrieb:
> Ja, sicher.
>  Erkläre mir mal bitte,  was da womit gemacht wird

Ernst gemeinte Frage?

von Peter II (Gast)


Lesenswert?

Marc V. schrieb:
> Ohne Klammern funktioniert das nur zufällig und nur mit diesem
>  Ausdruck.
>  Ein Mensch kann ganz einfach nicht mehr als 2 Zustände miteinander
>  vergleichen, das Resultat wird dann mit nächsten Ausdruck verglichen
>  usw.
>  Dabei muss aber auch die Priorität beachtet werden...

in der Schule haben wir schon alle gelernt wie man rechnen.

3 + 4 * 5

bekommt man auch ohne Klammern sehr gut hin, als Programmieren sollte 
man zumindest wissen wie ein Compiler rechnen und da sind die Klammern 
nicht notwendig. Das ist auch kein Zufall das es funktioniert.

von Cyblord -. (cyblord)


Lesenswert?

Peter II schrieb:
>
> in der Schule haben wir schon alle gelernt wie man rechnen.
>
> 3 + 4 * 5
>
> bekommt man auch ohne Klammern sehr gut hin, als Programmieren sollte
> man zumindest wissen wie ein Compiler rechnen und da sind die Klammern
> nicht notwendig. Das ist auch kein Zufall das es funktioniert.

Auch wenn man es weiß. Übersichtlich ist es ganz einfach nicht. In dem 
Moment wo ich mir schon überlegen muss, wie der Compiler rechnet, läuft 
bereits was falsch.

Aber ganz ehrlich, von übersichtlichem (=clean) Code scheinst du nicht 
die Bohne zu verstehen.

Und eine Einstellung a la "das weiß man doch", ist einfach nur arrogant. 
Da sieht man gleich, da will jemand mit seinem Code posen, anstatt ihn 
leserlich zu schreiben.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

programmierer schrieb:
> Ernst gemeinte Frage?

 Ja, aber bitte so, wie du diesen Ausdruck liest, also erst einmal
 nach Prioritäten suchen, dann einen Vergleich, wieder Prioritäten,
 Vergleichen, Prioritäten...

 Und wenn du dann ohne Bleistift und Papier immer noch das Resultat
 der letzten Operation behalten hast, werde ich dich für Nobelpreis
 vorschlagen.

von Peter II (Gast)


Lesenswert?

Cyblord -. schrieb:
> Aber ganz ehrlich, von übersichtlichem (=clean) Code scheinst du nicht
> die Bohne zu verstehen.
was war an meinen Beispiel nicht lesbar?

> Und eine Einstellung a la "das weiß man doch", ist einfach nur arrogant.
> Da sieht man gleich, da will jemand mit seinem Code posen, anstatt ihn
> leserlich zu schreiben.
ich habe oben sogar extra klammer geschrieben in meinen Beispiel. Und ja 
ich kann Code auch ohne klammern lesen.

von Cyblord -. (cyblord)


Lesenswert?

Peter II schrieb:
> Und ja
> ich kann Code auch ohne klammern lesen.

Genau DIESE frühkindliche Arroganz meine ich. Solltest du nicht alt 
genug sein um das langsam mal abzulegen?

>> Aber ganz ehrlich, von übersichtlichem (=clean) Code scheinst du nicht
>> die Bohne zu verstehen.
>was war an meinen Beispiel nicht lesbar?

q.e.d.

: Bearbeitet durch User
von Elias *. (green_phanta)


Lesenswert?

Holla die Waldfee, das war ja mal eine sehr ausführliche Debatte über 
ein IF Statement. :) Vielen Dank für die ganzen Antworten! Ihr habt mir 
sehr geholfen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter II schrieb:
> Und ja ich kann Code auch ohne klammern lesen.

 Sicher, ich und jeder andere auch.
 Kannst du es aber auch verstehen ?

 Wenn jemand portugiesische und swahili Texte lesen kann, bedeutet es
 noch lange nicht, dass...

von Peter II (Gast)


Lesenswert?

@Marc Vesely
@Cyblord ----

von euch beiden kam kein sinnvoller Lösung wie man es schöner/einfacher 
schreiben kann, aber Hauptsache versuche andere Fehler bei andere Leute 
zu finden - ist das nicht etwas albern?

von Cyblord -. (cyblord)


Lesenswert?

Peter II schrieb:

> von euch beiden kam kein sinnvoller Lösung wie man es schöner/einfacher
> schreiben kann, aber Hauptsache versuche andere Fehler bei andere Leute
> zu finden - ist das nicht etwas albern?

Ich habe eine sinnvolle Lösung gepostet. Und ich habe keinerlei Fehler 
bei dir gesucht. Was redest du für wirres Zeug? DU hast meine Lösung 
angegriffen du Vogel.

Schöner Code fängt nun mal früher an und geht deutlich weiter als sich 
zu überlegen ob man nun Klammern setzt oder Switch nutzt oder 
Zeilenumbrüche einfügt.

Aber wie gesagt, davon verstehst du nichts und das wirst du 
wahrscheinlich auch nicht mehr auf die Kette bekommen.

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Cyblord -. schrieb:
> Ich habe eine sinnvolle Lösung gepostet. Und ich habe keinerlei Fehler
> bei dir gesucht. Was redest du für wirres Zeug? DU hast meine Lösung
> angegriffen du Vogel.

du hast nur eine Funktion eingefügt, und nicht den Inhalt der Funktion 
gezeigt. Es gibt um den "Ausdruck" der vereinfach werden sollte. Einfach 
eine Funktion an der Stelle einfügen ist leider keine Lösung.

Nein fliegen kann ich leider nicht.

von Cyblord -. (cyblord)


Lesenswert?

Peter II schrieb:
> Cyblord -. schrieb:
>> Ich habe eine sinnvolle Lösung gepostet. Und ich habe keinerlei Fehler
>> bei dir gesucht. Was redest du für wirres Zeug? DU hast meine Lösung
>> angegriffen du Vogel.
>
> du hast nur eine Funktion eingefügt, und nicht den Inhalt der Funktion
> gezeigt. Es gibt um den "Ausdruck" der vereinfach werden sollte. Einfach
> eine Funktion an der Stelle einfügen ist leider keine Lösung.

Lass gut sein, ich kann akzeptieren dass das über deinen Verstand geht. 
Solltest du auch langsam mal.

von Peter II (Gast)


Lesenswert?

Cyblord -. schrieb:
> Lass gut sein, ich kann akzeptieren dass das über deinen Verstand geht.
> Solltest du auch langsam mal.

Kinderkarten, Vogel, Kette - du bist ja ein absoluter Fachmann. Dich 
sollte man bestimmt als großen Vorbild sehen.

von Mark B. (markbrandis)


Lesenswert?

Elias *. schrieb:
> Marc V. schrieb:
>> Was soll da ohne Klammern richtig funktionieren ?
>
>
>
1
> if( (0 <= i && i <= 3) || (8 <= i && i <= 11) || (16 <= i && i <= 19) || 
2
> (24 <= i && i <= 27) ){ // something }
3
>
>
> Ich hab's gerade aus dem Kopf geschrieben und die Klammern vergessen …
> es ging mir eher ums "Konzept". Aber klar ohne geht es natürlich nicht.
>
> Aber hast du noch eine Idee das anders zu schreiben? Und Effizienz?

Es ist ein Irrtum, dass man Code in erster Linie so schreiben sollte, 
dass er möglichst effizient ist.

In erster Linie schreibt man Code so, dass er:
-das richtige Ergebnis liefert
-lesbar und wartbar ist

Das Optimieren überlässt man lieber dem Compiler. Der kann es im 
Zweifelsfall auch besser.

Natürlich sollte man sinnvolle Algorithmen verwenden. Wenn man das tut, 
ist Optimierung auf der Ebene "wie-kodiere-ich-das-am-besten-von-Hand" 
in sehr vielen Fällen komplett unnötig.

von Mark B. (markbrandis)


Lesenswert?

Johann L. schrieb:
> - indem man's übersichtlicher aufschreibt:
>
> if ((0 <= i && i <= 3) ||
>     (8 <= i && i <= 11) ||
>     (16 <= i && i <= 19) ||
>     (24 <= i && i <= 27) )
>
> wird doch gleich viel übersichtlicher, oder?
>
> - oder indem man sich überlegt, welche Systematik dahinter liegt:
>
> if ((i & 0xFFE7) < 4)

Wer solchen Code schreibt, gehört verhauen. ;-)

von NurEinWort (Gast)


Lesenswert?

if( ( ( i & 0x07 ) <= 3 ) && ( ( i & 0xF8 ) <= 24  ) ) { /* Zeug */ }

von NurEinWort (Gast)


Lesenswert?

P.S. oder wenn man es wirklich kurz will wäre es if( ! ( i & 0xE7 ) ) 
und nicht if( ( i & 0xE7 ) < 4 ). klugscheiss

Aber die ausgeschriebene Variante mit ordentlicher Klammerung und 
Zeilenumbruch wäre meine favorisierte.

von Peter D. (peda)


Lesenswert?

Der GCC erlaubt auch:
1
switch(i){
2
  case  0 ...  3:
3
  case  8 ... 11:
4
  case 16 ... 19:
5
  case 24 ... 27:
6
         doSomething(); 
7
         break;
8
}

Paddy schrieb:
> if (i & 0b11100100 == 0) ...

Diese Lösung ist natürlich am besten lesbar.
Sie sagt auf einen Blick, welche Bits 0 sein müssen und welche egal 
sind.
Wenn Bitmuster auszuwerten sind, sind die Bitbefehle (&,|) zu 
bevorzugen.

von Cyblord -. (cyblord)


Lesenswert?

NurEinWort schrieb:
> P.S. oder wenn man es wirklich kurz will wäre es if( ! ( i & 0xE7 ) )
> und nicht if( ( i & 0xE7 ) < 4 ). *klugscheiss*

Es wurde gar NIE nach kurz gefragt.

von Jan K. (jan_k)


Lesenswert?

Finde die Originalversion verständlich, man kann den Ausdruck doch an 
den '&&' auftrennen und jemand, der in Mathe schonmal die 
Intervallschreibweise gesehen hat, versteht auch schneller als mit jeder 
Bitoperation, was hier gemeint ist?!
Lesbarer ist es mit Zeilenumbruch und von mir aus auch noch mit 
Klammern.

Geht es hier wirklich um gesetzte Bits? Dann sieht die Sache ggf. anders 
aus.

Aber ein "(i & 0xFFE7) < 4" finde ich persönlich deutlich schwieriger.

von Mark B. (markbrandis)


Lesenswert?

Peter D. schrieb:
> Paddy schrieb:
>> if (i & 0b11100100 == 0) ...
>
> Diese Lösung ist natürlich am besten lesbar.
> Sie sagt auf einen Blick, welche Bits 0 sein müssen und welche egal
> sind.

Aber sie sagt nichts darüber aus, warum gerade DIESE Bits zu prüfen sind 
und nicht irgendwelche anderen.

Im Endeffekt ist das auch eine "Magic Number", und von daher ist es 
keine wirklich gute Lösung.

von Peter D. (peda)


Lesenswert?

Mark B. schrieb:
> Aber sie sagt nichts darüber aus, warum gerade DIESE Bits zu prüfen sind
> und nicht irgendwelche anderen.

Das ist nicht wichtig. Wichtig ist allein die Tatsache, daß es um 
Bitmasken geht.
Dieses Konzept mit Maskieren und Vergleichen findet man z.B oft bei der 
Adressierung von seriellen Schnittstellen wieder (CAN-ID, RS-485, I2C 
usw.).
Die Maskierung sagt z.B. aus, welchen Priorität die Adressen haben oder 
ob sie sich überlappen oder ausschließen.
Mit magischen Dezimalvergleichen ist sowas völlig unübersichtlich.

von Cyblord -. (cyblord)


Lesenswert?

Peter D. schrieb:
> Mark B. schrieb:
>> Aber sie sagt nichts darüber aus, warum gerade DIESE Bits zu prüfen sind
>> und nicht irgendwelche anderen.
>
> Das ist nicht wichtig. Wichtig ist allein die Tatsache, daß es um
> Bitmasken geht.

Aha und wenn die gewünschte Informationen nicht mehr über die Bits 
reinkommen, sondern z.B. über einen UART und darum ganz anders aussieht? 
Dann schreiben wir das ganze um, weil es dann ja nicht mehr um Bitmasken 
geht?

Darum abstrahieren. Wie dann die abstrahierte Funktion, die Information 
bekommt oder herleitet ist dann sekundär und das kann auch immer wieder 
geändert werden.

Wichtig ist dem Leser aber eben gerade NICHT dass es um Bits geht, 
sondern WAS wird eigentlich hier überprüft? Das will ich doch wissen 
wenn ich das lese. Und nicht, aha hier wird geguckt ob Bit 2 oder Bit 5 
gesetzt ist.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Peter D. schrieb:
> Mark B. schrieb:
>> Aber sie sagt nichts darüber aus, warum gerade DIESE Bits zu prüfen sind
>> und nicht irgendwelche anderen.
>
> Das ist nicht wichtig.

Selbstverständlich ist das wichtig. In einem Code Review kriegst Du 
sowas gleich um die Ohren gehauren. Und womit? Mit Recht!

Meinetwegen kann man es ja als 0b11100100 schreiben, wenn aus dem 
Funktionsnamen oder aus einem Kommentar ersichtlich ist, was da gerade 
geprüft wird bzw. warum gerade diese Bits.

Die Erfahrung zeigt: Nach einer Weile weiß man es sonst selbst nicht 
mehr ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Paddy schrieb:
> if (i & 0b11100100 == 0) ...

Fast so hätte ich es auch gemacht, aber nur dann, wenn es wirklich kein
Zufall ist, dass die im Originalausdruck vorkommenden Konstanten diesem
einfachen System gehorchen.

Allerdings fehlen die Klammern um i & 0b11100100 (== bindet stärker als
&).

Um vom verwendeten Integer-Typ (8 Bit, 16 Bit usw.) unabhängig zu sein,
würde man vielleicht besser

1
if((i & ~0b11011) == 0)

oder

1
if((i & ~0x1b) == 0)

oder je nach persönlichem Geschmack auch

1
if(!(i & ~0x1b))

schreiben.

Edit: Natürlich mit einem kurzen Kommentar, woher die Konstante 0b11011
bzw. 0x1b kommt.

: Bearbeitet durch Moderator
von S. R. (svenska)


Lesenswert?

Cyblord -. schrieb:
> Aha und wenn die gewünschte Informationen nicht mehr über die Bits
> reinkommen, sondern z.B. über einen UART und darum ganz anders aussieht?

Ob das Byte mit magischen Bits drin nun in einem Register steht oder in 
einem per UART übertragenem Puffer, ist relativ egal. Das sollte sogar 
dir klar sein.

> Dann schreiben wir das ganze um, weil es dann ja nicht mehr um Bitmasken
> geht?

Wenn sich die Struktur ändert, ist dein Ansatz mit IstTeilbarDurchVier() 
genauso hinfällig. Sollte es tatsächlich um Bitmasken gegangen sein, war 
er schon vorher b'scheuert.

Da der TO aber den Hintergrund nicht angegeben hat, bleibt die der 
Aufgabenstellung angemessenste Methode ohnehin versteckt.

von Peter D. (peda)


Lesenswert?

Cyblord -. schrieb:
> Aha und wenn die gewünschte Informationen nicht mehr über die Bits
> reinkommen, sondern z.B. über einen UART und darum ganz anders aussieht?

Was soll da anders aussehen?
Die Bits kommen seriell rein und haben eine von ihrer Position abhängige 
Bedeutung. Daher ist es besser lesbar, wenn man ihre Position klar 
erkennen kann.

Schau Dir einfach mal an, wie das beim CAN-Bus mit der ID-Auswertung 
funktioniert. Da hast Du je MOB ein CANIDT-Register und ein 
CANIDM-Register.
Mit dem CAN Identifier Mask Register gibt man an, welche Bits verglichen 
werden sollen und das CAN Identifier Tag Register enthält dann den zu 
vergleichenden Wert. Und da käme wirklich absolut niemand auf die Idee, 
diese beiden Register mit kryptischen Dezimalzahlen zu befüllen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Elias *. schrieb:
> 2) Und wie sieht es mit der Effizienz aus? Brauchen diese ANDs und ORs
> viel Prozessorpower?

Das hängt vom verwendeten Compiler ab. Der AVR-GCC 6.3.0 liegt mit
seinem Ergebnis schon sehr nahe am Optimum:

1
  andi    r24, 0xE7
2
  cpi     r24, 0x04
3
  brcc    ...

Er halt also das dahintersteckende System erkannt.

Paddys Lösung ist allerdings noch einen Taktzyklus schneller:

1
  andi    r24, 0xE4
2
  brne    ...

von Peter II (Gast)


Lesenswert?

Yalu X. schrieb:
> Das hängt vom verwendeten Compiler ab. Der AVR-GCC 6.3.0 liegt mit
> seinem Ergebnis schon sehr nahe am Optimum:
>
>   andi    r24, 0xE7
>   cpi     r24, 0x04
>   brcc    ...
>
> Er halt also das dahintersteckende System erkannt.

Respekt, das hätte ich ihm gar nicht zugetraut.
(du als Input das Original von Elias genommen?)

von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Paddys Lösung ist allerdings noch einen Taktzyklus schneller:
>
>
>
1
>   andi    r24, 0xE4
2
>   brne    ...
3
>

Für nicht verbrauchte Rechenzeit bekommt man kein Geld zurück. ;-)

von Cyblord -. (cyblord)


Lesenswert?

S. R. schrieb:
> Ob das Byte mit magischen Bits drin nun in einem Register steht oder in
> einem per UART übertragenem Puffer, ist relativ egal. Das sollte sogar
> dir klar sein.

Sagen wir mal, es werden Taster abgefragt, vorher direkt per Port 
(Bitmaske) jetzt per UART in einem ganz anderen Format.

> Wenn sich die Struktur ändert, ist dein Ansatz mit IstTeilbarDurchVier()
> genauso hinfällig. Sollte es tatsächlich um Bitmasken gegangen sein, war
> er schon vorher b'scheuert.

Richtig, weil IstTeilbarDurchVier() ein Beispiel war, weil wir ja nicht 
wissen WAS wirklich abgefragt werden soll. Aus dem Eingangsbeispiel 
hätte aber ja die Prüfung einer Zahl auf Teilbarkeit eine Möglichkeit 
sein können.

Wenn wir beim Tasterbeispiel bleiben, müsste es lediglich lauten: 
IsButtonPressed(int buttonNr). Oder besser noch: isStartButtonPressed();

Und das ganze dahinter wird dann eben über Bitmasken, UART-Bytes, I2C 
Kommandos, egal was, realisiert.


> Da der TO aber den Hintergrund nicht angegeben hat, bleibt die der
> Aufgabenstellung angemessenste Methode ohnehin versteckt.
Ja ich weiß. Aber wenn man obigen Ansatz verfolgt, wird die 
Fragestellung des TE auf einmal immer weniger relevant weil das 
Konstrukt im Hauptprogramm gar nicht auftaucht sondern irgendwo in einer 
austauschbaren Funktion schlummert. Und auf jeden Fall auch nur einmal 
und nicht vielleicht 5 mal im Code verteilt. Und darum geht es mir.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Cyblord -. schrieb:
> Sagen wir mal, es werden Taster abgefragt, vorher direkt per Port
> (Bitmaske) jetzt per UART in einem ganz anderen Format.

Dann ändert sich die Struktur und du musst den Code ohnehin anpassen. 
Also ist diese Annahme im gegebenen Kontext reichlich bescheuert, und 
ich bin mir sicher, dass du das absichtlich tust.

Du diskutierst High-Level-Funktionen. Die wiederum nutzen 
Low-Level-Funktionen, um die es hier geht. Sicher ist ein 
isStartButtonPressed() sinnvoll, aber irgendwo bleibt es eine Maske.

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

S. R. schrieb:
> Dann ändert sich die Struktur und du musst den Code ohnehin anpassen.
> Also ist diese Annahme im gegebenen Kontext reichlich bescheuert, und
> ich bin mir sicher, dass du das absichtlich tust.

Nein ich muss EINE Funktion anpassen bzw. alle Tasterfunktionen.
Das Hauptprogramm bleibt völlig unbeeindruckt. DAS ist der Unterschied. 
Ein Riesenunterschied. Und daran ist auch nichts bescheuert. Das 
Beispiel ist gar nicht so realitätsfremd.


> Du diskutierst High-Level-Funktionen.
Nein ich diskutiere ein Konzept.

von programmierer (Gast)


Lesenswert?

Marc V. schrieb:
> wie du diesen Ausdruck liest, also erst einmal
>  nach Prioritäten suchen, dann einen Vergleich, wieder Prioritäten,
>  Vergleichen, Prioritäten...

Mit der Syntax habe ich mich wenig befasst, da er nicht mal schreibt was 
für eine Sprache er verwendet.

Trotzdem, (zumindest für mich) offensichtlich gibt es drei "oder" 
Verküpfungen.

Bei

0<=I<=3 ODER
8<=I<=11 ODER
16<=I<=19 ODER
24<=I<=27

Soll die Bedingung wahr sein, ansonsten nicht.

von Roland F. (rhf)


Lesenswert?

Hallo,

@ Cyblord

> Wichtig ist dem Leser aber eben gerade NICHT dass es um Bits geht,
> sondern WAS wird eigentlich hier überprüft? Das will ich doch wissen
> wenn ich das lese. Und nicht, aha hier wird geguckt ob Bit 2 oder Bit 5
> gesetzt ist.

@ Mark B. schrieb:

> Die Erfahrung zeigt: Nach einer Weile weiß man es sonst selbst nicht
> mehr ;-)

Nachdem jetzt jeder Experte seine Meinung kundgetan hat, hier mal ein 
Vorschlag von mir als schlechtem Hobbyprogrammierer:
In jeder mir bekannten Programmiersprache gibt es die Möglichkeit 
Kommentare einzufügen, die es ermöglichen (!! Achtung jetzt kommt es !!) 
zu erklären was der produzierte Quellcode eigentlich tun soll.
Man könnte zum Beispiel obige Codezeile auskommentieren und dann die 
effizientere Lösung verwenden, mit dem Kommentar als Hinweis das beide 
Codestücke die gleiche Funktion besitzen.

rhf

von Joachim B. (jar)


Lesenswert?

Johann L. schrieb:
> if ((0 <= i && i <= 3) ||
>     (8 <= i && i <= 11) ||
>     (16 <= i && i <= 19) ||
>     (24 <= i && i <= 27) )
>
> wird doch gleich viel übersichtlicher, oder?

nur frage ich mich ob das nicht schneller ist

statt if zu verodern:

if((0 <= i && i <= 3)
Bedingung erfüllt muss nicht zum else Zweig

else if(8 <= i && i <= 11)
Bedingung erfüllt muss nicht zum else Zweig

else if(16 <= i && i <= 19)
Bedingung erfüllt muss nicht zum else Zweig

usw.

von Peter II (Gast)


Lesenswert?

Joachim B. schrieb:
> nur frage ich mich ob das nicht schneller ist
>
> statt if zu verodern:
>
> if((0 <= i && i <= 3)
> Bedingung erfüllt muss nicht zum else Zweig

short evaluation ist in C schon lange definiert.

von Bitwurschtler (Gast)


Lesenswert?

Elias *. schrieb:

> 1) Es funktioniert, aber ich wollte fragen ob es eine schönere Lösung
> dafür gibt?

Klar, mit Kommentaren verstehts auch die Grandma
1
/*     range 0 .. 3   or  range 8 .. 11    or  range 16 .. 19    or  range 24 .. 27 */
2
if ( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24 <= i && i <= 27){ // something }

von Cyblord -. (cyblord)


Lesenswert?

Roland F. schrieb:
> Kommentare einzufügen, die es ermöglichen (!! Achtung jetzt kommt es !!)
> zu erklären was der produzierte Quellcode eigentlich tun soll.
> Man könnte zum Beispiel obige Codezeile auskommentieren und dann die
> effizientere Lösung verwenden, mit dem Kommentar als Hinweis das beide
> Codestücke die gleiche Funktion besitzen.

"Kommentare sind gut, lesbarer Code ist besser."

Warum erst verschwurbelten Code schreiben den man hinterher mit 
Kommentaren erläutern muss, anstatt gut lesbaren Code zu schreiben der 
nur minimal kommentiert werden muss?

Das Problem mit Kommentaren ist, dass sie dazu neigen zu veralten. Man 
Kommentiert schön, irgendwann ändert man was im Code und hat natürlich 
keinen Zeit den Kommentar nachzuziehen. Dann steht da irgendwas im Code 
was nicht aktuell ist.

von Joachim B. (jar)


Lesenswert?

Peter II schrieb:
> short evaluation ist in C schon lange definiert.

mag sein, mich überrascht der optimierende -o3 gcc in der Arduino IDE 
immer wieder, wenn ich denke ich schreibe es besser und kürzer kommt 
u.U. längerer Code raus.

Deswegen teste ich immer mehrere Möglichkeiten, mal mit Bits die ich 
setze und zurücksetze und mit dem Oszi, um die kürzeste Zeit zu finden, 
mal mit Codegröße um den kürzesten Code zu finden.

Hardcorefreaks kenne natürlich jede Laufzeit und machen das aus dem Kopf 
oder in ASM.

von Cyblord -. (cyblord)


Lesenswert?

Joachim B. schrieb:
> Deswegen teste ich immer mehrere Möglichkeiten, mal mit Bits die ich
> setze und zurücksetze und mit dem Oszi, um die kürzeste Zeit zu finden,
> mal mit Codegröße um den kürzesten Code zu finden.
>
> Hardcorefreaks kenne natürlich jede Laufzeit und machen das aus dem Kopf
> oder in ASM.

Warum überhaupt derart "Hardcore" Optimieren? Eigentlich sollte das 
nicht die Regel sein, sondern nur in speziellen Ausnahmefällen nötig 
werden.

von Bitwurschtler (Gast)


Lesenswert?

Cyblord -. schrieb:
> "Kommentare sind gut, lesbarer Code ist besser."

Das Problem mit lesbaren Code ist, das nur Coder den lesen können. Gute 
Kommentare versteht auch der Service/Vertrieb/PM/etc. also jeder der die 
Spreache versteht in der der Kommantar verfasst wurde.

Lesbarer Code erhöht also die "Geheimnisskrämerei" unter der 
Programmieren und erschwert die Verifikation/Test durch 
Nicht-Programmierer.


Lesbarer Code ist nicht selten nur eine Ausrede um sich vor der 
Dokumentation/Kommentierung zu drücken.

von Cyblord -. (cyblord)


Lesenswert?

Bitwurschtler schrieb:
> Cyblord -. schrieb:
>> "Kommentare sind gut, lesbarer Code ist besser."
>
> Das Problem mit lesbaren Code ist, das nur Coder den lesen können. Gute
> Kommentare versteht auch der Service/Vertrieb/PM/etc. also jeder der die
> Spreache versteht in der der Kommantar verfasst wurde.

Der Service/Vertrieb/PM schaut in den Code? Wo soll das sein? Völliger 
Humbug.

> Lesbarer Code erhöht also die "Geheimnisskrämerei" unter der
> Programmieren und erschwert die Verifikation/Test durch
> Nicht-Programmierer.
Bitte? Code durch Nicht-Programmierer verifizieren lassen? Anhand der 
Kommentare? Was rauchst du eigentlich für ein Kraut?

> Lesbarer Code ist nicht selten nur eine Ausrede um sich vor der
> Dokumentation/Kommentierung zu drücken.
Klaro.

von Bitwurschtler (Gast)


Lesenswert?

Also bei uns passiert es schon das der Vertreinb/Service schon mal 
nachfragt ob das Gerät selbst prüft welche Eingaben

Cyblord -. schrieb:
>> Lesbarer Code ist nicht selten nur eine Ausrede um sich vor der
>> Dokumentation/Kommentierung zu drücken.
> Klaro.

Das meine ich Ernst, muss dich ja nicht angesprochen fühlen.
Aber meisten ist es so, das Softwerker die Verständlichkeit ihres Codes 
masslos überschätzen und Nachwuchs-Programmierer die den Alt-code 
weiterpflegen sollen nur auslachen wenn die hofflich um Erklärungen 
bitten.
Genialität ist selbsterklärend -- jajaja.
Job security by code obfuscation - ich doch nicht ?!?

von Joachim B. (jar)


Lesenswert?

Bitwurschtler schrieb:
> Lesbarer Code ist nicht selten nur eine Ausrede um sich vor der
> Dokumentation/Kommentierung zu drücken.

oder eben schnell abzuliefern, wie sagte ein Chef mal, manchmal muss man 
dem Entwickler auch das Produkt aus der Hand reissen.

Ich arbeite ja nach top down, erst das grobe umschliessende Gerippe, 
dann die Feinausarbeitung und Kommentare oder lesbar erst wenn ich weiss 
das es funktioniert.

Ich verschwende möglichst keine Zeit für Lesbarkeit und Kommentare wenn 
ich nicht weiss ob diese Routine überlebt.

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Bitwurschtler schrieb:
> Elias *. schrieb:
>
>> 1) Es funktioniert, aber ich wollte fragen ob es eine schönere Lösung
>> dafür gibt?
>
> Klar, mit Kommentaren verstehts auch die Grandma
>
1
> /*     range 0 .. 3   or  range 8 .. 11    or  range 16 .. 19    or 
2
> range 24 .. 27 */
3
> if ( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24 
4
> <= i && i <= 27){ // something }
5
>

Dann kannst Du den Code auch gleich so schreiben, daß man ihn ohne 
Kommentar versteht:
1
static inline int in_range(int value, int low, int high)
2
{
3
    return (low <= value && value <= high);
4
}
5
6
...
7
    if (in_range(i, 0, 3) ||
8
        in_range(i, 8, 11) ||
9
        in_range(i, 16, 19) ||
10
        in_range(i, 24, 27))
11
    {
12
        ...
13
    }

Das unterbricht den Lesefluss nicht und wenn Du das Ding das nächste Mal 
brauchst, ist es schon da.

: Bearbeitet durch User
von Roland F. (rhf)


Lesenswert?

> Warum erst verschwurbelten Code schreiben den man hinterher mit
> Kommentaren erläutern muss, anstatt gut lesbaren Code zu schreiben der
> nur minimal kommentiert werden muss?

Ich hatte vor einiger Zeit ein fast gleiches Problem wie Elias. Die mit 
Abstand am besten zu verstehen de Version wäre eine Kette von 16, 
ineinander verschachtelten IF-Abfragen gewesen. Das gefiel mir nicht und 
habe eine Lösung gefunden, die mit einer einzigen Zeile auskommt.
Hätte ich auf den Vorteil der deutlich effizienteren und Speicher 
sparenden Version verzichten sollen nur um eine bessere Lesbarkeit des 
Quellcodes zu erreichen?
Ich habe das Problem der schwereren Verständlichkeit meiner Lösung 
dadurch gelöst, das ich einfach die Funktion in einem Kommentar 
dokumentiert habe.

> Das Problem mit Kommentaren ist, dass sie dazu neigen zu veralten. Man
> Kommentiert schön, irgendwann ändert man was im Code und hat natürlich
> keinen Zeit den Kommentar nachzuziehen.

Ich finde das Kommentieren zum Programmieren dazu gehört.

rhf

von Axel L. (axel_5)


Lesenswert?

Bitwurschtler schrieb:
> Also bei uns passiert es schon das der Vertreinb/Service schon mal
> nachfragt ob das Gerät selbst prüft welche Eingaben
>
> Cyblord -. schrieb:
>>> Lesbarer Code ist nicht selten nur eine Ausrede um sich vor der
>>> Dokumentation/Kommentierung zu drücken.
>> Klaro.
>
> Das meine ich Ernst, muss dich ja nicht angesprochen fühlen.
> Aber meisten ist es so, das Softwerker die Verständlichkeit ihres Codes
> masslos überschätzen und Nachwuchs-Programmierer die den Alt-code
> weiterpflegen sollen nur auslachen wenn die hofflich um Erklärungen
> bitten.
> Genialität ist selbsterklärend -- jajaja.
> Job security by code obfuscation - ich doch nicht ?!?

Ja, vor allem, wenn in dem genialen Code Fehler sind und der 
Nachwuchsprogrammierer dann anhand des fehlerhaften Codes rausfinden 
darf, was denn der geniale Programmierer wohl geschrieben haben würde, 
wenn er wirklich genial und fehlerfrei programmiert hätte.

Das sind dann die Programme, die von Grund auf neu geschrieben werden 
müssen.

Gruss
Axel

von Stefan F. (Gast)


Lesenswert?

Wenn man allerdings einen von Natur aus Kommentierfaulen Programmierer 
dazu zwingt, mehr zu kommentieren, kommt nicht selten sowas dabei 
heraus:
1
// Hier wird i auf Null gesetzt.
2
i=0;
3
4
5
// Perform required step 7 on the data and return the result.
6
void* step7(char* data)
7
{
8
    ....
9
}

Sowas habe ich ich schon ich Echt erlebt, ist gar nicht lange her. Der 
Kollege wurde kurze Zeit später entlassen - unter anderem deswegen.

von nicht"Gast" (Gast)


Lesenswert?

Bitwurschtler schrieb:
> Klar, mit Kommentaren verstehts auch die Grandma
> /*     range 0 .. 3   or  range 8 .. 11    or  range 16 .. 19    or
> range 24 .. 27 */
> if ( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
> <= i && i <= 27){ // something }

Na Super, das steht doch schon da. Der Kommentar wiederholt einfach nur 
den Code. Das kann man sich sparen. Da schreibst du jedes mal alles 
doppelt.

Bitwurschtler schrieb:
> Also bei uns passiert es schon das der Vertreinb/Service schon mal
> nachfragt ob das Gerät selbst prüft welche Eingaben

Hä? dieser Satz ist nicht vollständig^^. Du schreibst ja aber selber, 
dass der Vertrieb nachfragt. Heißt, er schaut auch nicht in den Code.

Roland F. schrieb:
> hier mal ein
> Vorschlag von mir als schlechtem Hobbyprogrammierer:

^^

Es ist eigentlich ganz einfach. Wenn man die Bedingung in eine Funktion 
kapselt kann man folgendes machen..... SIE TESTEN.

Ich kann meine Funktion durch einen Unittest schieben und mich 
vergewissern, dass sie auch immer das gewünschte Ergebnis liefert. Das 
kann ich nicht machen, wenn die Bedingung im If steht.

Roland F. schrieb:
> Ich finde das Kommentieren zum Programmieren dazu gehört.

Ja, aber nicht jedem Klecks, der sich nämlich ändern kann und dann muss 
jede menge Prosa umgeschrieben werden. Das lässt man dann einfach mal 
sein, wärend man an seinem Code arbeitet und dann hat man es vergessen. 
Dann lieber eine Funktion umbenennen. Jede moderne IDE liefert die 
benötigten Refactoring Tools um einfach Variablen/Funktionen etc. 
umbenennen zu können  und zwar jenseits von einfachem find/replace.

Roland F. schrieb:
> Ich hatte vor einiger Zeit ein fast gleiches Problem wie Elias. Die mit
> Abstand am besten zu verstehen de Version wäre eine Kette von 16,
> ineinander verschachtelten IF-Abfragen gewesen. Das gefiel mir nicht und
> habe eine Lösung gefunden, die mit einer einzigen Zeile auskommt.
> Hätte ich auf den Vorteil der deutlich effizienteren und Speicher
> sparenden Version verzichten sollen nur um eine bessere Lesbarkeit des
> Quellcodes zu erreichen?
> Ich habe das Problem der schwereren Verständlichkeit meiner Lösung
> dadurch gelöst, das ich einfach die Funktion in einem Kommentar
> dokumentiert habe.

Pack das in eine Funktion, gebe ihr einen beschreibenden Namen. Nur mal 
so zum Test. Du wirst sehen, die Lesbarkeit wird sich noch mal um 
einiges steigern. Um zu verstehen was Code macht, muss man immer zu erst 
verstehen, was passiert und nicht wie es passiert.


Bitwurschtler schrieb:
> Das meine ich Ernst, muss dich ja nicht angesprochen fühlen.
> Aber meisten ist es so, das Softwerker die Verständlichkeit ihres Codes
> masslos überschätzen und Nachwuchs-Programmierer die den Alt-code
> weiterpflegen sollen nur auslachen wenn die hofflich um Erklärungen
> bitten.

Öhm, also, da weiß man gar nicht, wie man gegen so viel Blödsinn 
argumentieren soll. Der ordentliche Code ist also doch so unordentlich, 
dass keiner ihn versteht........... keine Worte.

Natürlich macht das keiner Perfekt. Das ist einfach das wesentliche Leid 
des Berufes. Man kann sich aber Mühe geben und zu sagen, da ein anderer 
das evtl. doch nicht lesen kann, lass ich es gleich ganz sein und mach 
alles total durcheinander und wie es mir grad in den Sinn kommt klingt 
irgend wie falsch.

Bitwurschtler schrieb:
> Das Problem mit lesbaren Code ist, das nur Coder den lesen können. Gute
> Kommentare versteht auch der Service/Vertrieb/PM/etc. also jeder der die
> Spreache versteht in der der Kommantar verfasst wurde.

Gewöhnlich lesen vor allem Coder den Code. Ich bin mir sicher, dass für 
den geneigten Betrachter ein:
1
      if (istTeilbarDurchVier(derWert))
2
      {
3
          machwas();   
4
      }

für den Laien lesbarer ist als
1
    if( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24 <= i && i <= 27){
2
    // prüfe ob wert durch 4 teilbar ist
3
    machwas();
4
}

Axel L. schrieb:
> Ja, vor allem, wenn in dem genialen Code Fehler sind und der
> Nachwuchsprogrammierer dann anhand des fehlerhaften Codes rausfinden
> darf, was denn der geniale Programmierer wohl geschrieben haben würde,
> wenn er wirklich genial und fehlerfrei programmiert hätte.

bla bla bla. Meistens sind es dann doch eher die Anfänger und 
Jungspunde, die sich überschätzen und "genialen" Code erzeugen. Schnell 
dahin geschludert, nicht Wartbar, nicht Testbar und voll mit 
Seiteneffekten.

So, fertsch. Ihr könnt es jetzt Zerreißen^^

PS: Rechtschreibfehler dienen der Auflockerung des geschriebenen und 
sollten in Separaten Antworten, die nichts mit dem Thema zu tun haben 
ausführlichst diskutiert werden.

von nicht"Gast" (Gast)


Lesenswert?

Ach gerade in einem anderen Thread gefunden^^
Beitrag "Projekt mit genauer Sekunde - Abweichung"

Sry Alex
1
void ClearDisplay()
2
/** Used for dimming: This function set all display used port pins to input **/
3
{
4
    DDRB &= ~PortMask.B;
5
    DDRC &= ~PortMask.C;
6
    DDRD &= ~PortMask.D;
7
    LED_IR_DDR &= ~(1<<LED_IR);
8
    LED_IL_DDR &= ~(1<<LED_IL);
9
}
10
11
void ShowDisplay()
12
/** Used for dimming: This function set all display used port pins to input **/
13
{
14
    DDRB |= PortMask.B;
15
    DDRC |= PortMask.C;
16
    DDRD |= PortMask.D;
17
    LED_IR_DDR |= (1<<LED_IR);
18
    LED_IL_DDR |= (1<<LED_IL);
19
}
Kommentare sind echt wichtig. Sie sollten nur nicht per copy/paste 
gemacht werden und so gar nichts mit der Funktion zu tun haben.

Auch die erste ISR
1
ISR(TIMER1_COMPA_vect)
2
{
3
    static uint8_t ct0 = 0xFF, ct1 = 0xFF, rpt;
4
    uint8_t i;
5
6
    i = button_state ^ ~BUTTON_PIN;                       // key changed ?
7
    ct0 = ~( ct0 & i );                             // reset or count ct0
8
    ct1 = ct0 ^ (ct1 & i);                          // reset or count ct1
9
    i &= ct0 & ct1;                                 // count until roll over ?
10
    button_state ^= i;                                 // then toggle debounced state
11
    button_press |= button_state & i;                     // 0->1: key press detect
12
13
    if( (button_state & REPEAT_MASK) == 0 )            // check repeat function
14
        rpt = REPEAT_START;                          // start delay
15
16
    if( --rpt == 0 )
17
    {
18
        rpt = REPEAT_NEXT;                            // repeat delay
19
        button_rpt |= button_state & REPEAT_MASK;
20
    }
21
22
    if(rest) OCR1A = reload;        // compare DEBOUNCE - 1 times
23
24
    if( --prescaler == 0 )
25
    {
26
        prescaler = (uint8_t)DEBOUNCE;
27
        Tick++;               // exact one second over
28
        if(rest) OCR1A = reload + rest; // compare once per second
29
    }
30
}

Trotz Kommentaren und Jahrelanger C Programmierung fällt es mir sehr 
schwer zu verstehen, was hier passieren soll. Stellt euch mal vor es 
würde so da stehen.
1
ISR(TIMER1_COMPA_vect)
2
{
3
     int ButtonState = getDebouncedButtonState();
4
     
5
     if (ButtonState)
6
     {
7
          wasAuchImmerDerCodeSoll(); // ich gebe zu es fällt mir echt schwer den Code nachzuvollziehen. Mag die Uhrzeit sein oder der Code oder beides
8
     }
9
}

Ist das nicht viel lesbarer? Un genau so ist es mit dem Kopf des If 
auch.

von A. S. (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Pack das in eine Funktion, gebe ihr einen beschreibenden Namen. Nur mal
> so zum Test. Du wirst sehen, die Lesbarkeit wird sich noch mal

Das wäre in Rolands Fall (wie auch beim TO) einfach nur Müll nach 
Vorschrift.

a) eine eigene Funktion senkt zwar McCabe und Co, bringt aber ein 
zusätzliches Token mit zusätzlichem Kontext.
b) der Name der Funktion veraltet genauso schnell wie ein Kommentar
c) der gewählte Name (sowohl von Dir als auch von Cyblord) hat doch 
nichts aber auch wirklich nichts mit der der Aufgabe des TO zu tun.

nicht"Gast" schrieb:
> if (istTeilbarDurchVier(derWert))

Dessen Funktion schaute, ob eines der Bits eines Integers gesetzt war, 
wobei Bit 0,1,2 und 4 ignoriert wurden. "Vier" weil 4 Bits ignoriert 
wurden? "Vier", weil das erste getestete Bit zufällig 4 repräsentiert?

Der Aufwand wird einfach größer zu erkennen, dass "TeilbarDurchVier" 
einfach falsch ist.

d) (und das ist das schlimmste,) dieser Müll nach Vorschrift gaukelt Dir 
hübsche Statistiken vor und verschleiert, dass die eigentliche Aufgabe 
(Bitauswertung) überhaupt nicht erkannt und verstanden wurde. Damit 
wärest Du überhaupt nicht mehr in der Lage, sinnvolle Testfälle *zu 
überblicken*. Bits x,y im Register Z... Ok, das sollte man umsetzen 
können. Aber 16 Dezimalzahlen sind OK, alle anderen nicht ... und ein 
Tippfehler macht aus <=11 dann <11 und Du willst das sofort sehen? Das 
übernimmst Du doch genauso in Deine Testcases und erfüllst jede Prüfung 
bis zur Serienauslieferung.

von Tommi (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Ich bin mir sicher, dass für
> den geneigten Betrachter ein:
>
1
>       if (istTeilbarDurchVier(derWert))
2
>
>
> für den Laien lesbarer ist als
>
>
1
>     if( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 
2
> 24 <= i && i <= 27){
3
>
Hier hast du jetzt die Funktion bereits irrefuehrend benannt. Der Wert 4 
waere teilbar durch 4, ist aber ausgeschlossen. Der Wert 8 ist auch 
teilbar durch 4 und liegt im Bereich.
Und das ist genau das Problem, wenn man selbst noch einzelne Codezeilen 
in Funktionen verpackt: Man vergibt statistisch gesehen falsche Namen. 
Durch die Kapselung sieht man dann nicht mehr, was das Programm 
tatsaechlich macht.
Hilft das jetzt der Lesbarkeit?
Man weiss auch nicht, ob in der Funktion nicht noch an den Daten 
manipuliert wird, d.h. man muss, um den Code zu verstehen doch wieder in 
die Funktion schauen.
Klar, bei Wiederverwendung kann die Funktion gerechtfertigt sein...

von Tommi (Gast)


Lesenswert?

Achim war schneller...

von C. A. Rotwang (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Bitwurschtler schrieb:

>> /*     range 0 .. 3   or  range 8 .. 11    or  range 16 .. 19    or
>> range 24 .. 27 */
>> if ( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
>> <= i && i <= 27){ // something }
>
> Na Super, das steht doch schon da. Der Kommentar wiederholt einfach nur
> den Code. Das kann man sich sparen. Da schreibst du jedes mal alles
> doppelt.

Du hast nicht verstanden worum es bei Quelltextkommentieren geht und wo 
das Problem mit lesbaren Code besteht. Wie schon gesagt wurde:

> Das Problem mit lesbaren Code ist, das nur Coder den lesen können.

Kommentare im Quellcode sind eben nicht dazu da um den Code (wie ein 
Sportreporter) zu kommentieren.

Sondern um einen der in etwa weis Was (Funktion des Programms) 
programmiert wird aber nicht Wie (Programmiersprache assembler,C, 
Java;Betriebssystem: API, HAL;) zu erklären was hier gemacht werden 
soll.

Also ein Sportreporter würde so schreiben:
"Genial wie Littbarski von den Geißböcken kurz vor dem Pfiff des 
Schiries die Kugel per Innenriest in der linken Ecke versenkt"

Ein guter Programmierer dagegen:
"Der FC Köln gewinnt das Spiel"

 In dem lesenswerten Buch "Weniger schlecht programmieren" (ISBN: 
978-3-89721-567-2 )das dem Thema Kommentare ein ganzes Kapitel widmet 
steht dazu (S.62):
"Es bewährt sich beim Lesen von .. Kommentaren ... nicht davon 
auszugehen, dass diese Kommentare in irgendeinem sinnvollen Verhältniss 
zu Code stehen." Ein guter Kommentar zeichnet sich meiner meinung nach 
u.a dadurch aus, das er 1:1 in einem C wie in einem Assembler-Quelltext 
stehen könnte.

Der Text wiederholt also nicht den Code; sondern er übermittelt den 
Gedanken hinter den Code an einen (C-)Nichtprogrammier.  Und es ist 
nicht davon auszugehen das jeder Leser weiss das '||' dem logische Oder 
entspricht.

In dem erwähnten Buch liest sich das dann so:
" Er (Beispiel für schlecht kommentierten Code) ist unverständlich, weil 
der Autor keinerlei Mitgefühlfür den Leser zeigt. ... Er ist 
unverständlich, weil er den Leser im Dunkeln darüber lässt, was die Idee 
hinter diesem Code ist, warum er überhaupt nötig ist - er gibt dem Leser 
keinen Kontext."
Das Stichwort ist "Kontext" - also der Kommentar muss für sich allein 
das Programm erklären, der Code selber ist für diese Erklärung völlig 
unnötig und ungeeignet.

von Peter D. (peda)


Lesenswert?

C. A. Rotwang schrieb:
> Das Stichwort ist "Kontext" - also der Kommentar muss für sich allein
> das Programm erklären, der Code selber ist für diese Erklärung völlig
> unnötig und ungeeignet.

Der Code kann das oft schon erklären, wenn man ihn denn läßt.
Wenn man aber mit kryptischen Vergleichen von Dezimalzahlen verschleiern 
will, daß hier nur bestimmte Bits getestet und bestimmte Bits maskiert 
werden sollen, dann muß man das wenigstens auch im Kommentar 
hinschreiben.
Man könnte in diesem Fall aber auch den verständlichen Code als 
Kommentar hinschreiben:
1
// to realize this function: if (i & 0b11100100 == 0) ...

von A. S. (Gast)


Lesenswert?

C. A. Rotwang schrieb:
> Du hast nicht verstanden worum es bei Quelltextkommentieren geht

Ich vermute (hoffe), du hast den Autor nicht verstanden. Kommentare 
dürfen nur in Ausnahmefällen die Programmiersprache übersetzen.(z.b. ein 
dirty Trick für kritische Performance in 10.000 Zeilen)

Für schlechtere Programmierer (also immer ;-) programmiert man 
konservativ, hier z.b. Klammern, sinnvolle Namen.

Der Kommentar beschreibt das Warum.hier z.b. dass diese Magic Numbers 
vom TO die bitoperationen für bit 0,1,3 und 4 obfuscieren sollen.

von nicht"Gast" (Gast)


Lesenswert?

Achim S. schrieb:
> c) der gewählte Name (sowohl von Dir als auch von Cyblord) hat doch
> nichts aber auch wirklich nichts mit der der Aufgabe des TO zu tun.

Korrekt. Da habe ich mich verleiten lassen. Ich den Thread mal 
durchgeschaut. Der TO hat aber auch so gar nichts erwähnt, was er jetzt 
genau prüft. Auch die Behauptung dass Bits geprüft werden ist nur von 
anderen.
Solange keiner weiß, was genau mit der Abfrage bezweckt werden soll, 
kann ich auch keinen qualifizierten Namen vergeben.

Ergo-> Sieh den Namen als Beispiel.

C. A. Rotwang schrieb:
> Du hast nicht verstanden worum es bei Quelltextkommentieren geht und wo
> das Problem mit lesbaren Code besteht. Wie schon gesagt wurde:

Es klingt zwar so, als würdest du mir widersprechen. Das war aber ein 
Beispiel für einen schlechten kommentar. Von daher bin ich bei dir.

C. A. Rotwang schrieb:
> In dem lesenswerten Buch "Weniger schlecht programmieren" (ISBN:
> 978-3-89721-567-2 )das dem Thema Kommentare ein ganzes Kapitel widmet
> steht dazu (S.62):

Hab ich gelesen. Sehr schönes Buch :)
Dort wird auch ausführlich die besprochen, wie man Sachen benennen 
sollte und das es nicht trivial ist.

Grüße

von Cyblord -. (cyblord)


Lesenswert?

Wenn wir gerade bei Literatur sind, empfehle ich wärmstens

Clean Code: A Handbook of Agile Software Craftsmanship
Robert C. Martin
978-0132350884

von Axel L. (axel_5)


Lesenswert?

Peter D. schrieb:
> C. A. Rotwang schrieb:
>> Das Stichwort ist "Kontext" - also der Kommentar muss für sich allein
>> das Programm erklären, der Code selber ist für diese Erklärung völlig
>> unnötig und ungeeignet.
>
> Der Code kann das oft schon erklären, wenn man ihn denn läßt.
> Wenn man aber mit kryptischen Vergleichen von Dezimalzahlen verschleiern
> will, daß hier nur bestimmte Bits getestet und bestimmte Bits maskiert
> werden sollen, dann muß man das wenigstens auch im Kommentar
> hinschreiben.
> Man könnte in diesem Fall aber auch den verständlichen Code als
> Kommentar hinschreiben:
>
1
> // to realize this function: if (i & 0b11100100 == 0) ...
2
>

Das ändert aber alles nichts daran, dass der Code komplett 
unverständlich ist, sobald da ein Fehler drin ist.

Dann sollte der Kommentar im ungünstigsten Fall wenigstens erläutern, 
was der Code denn hätte machen sollen.

Sonst kann man den nach ein paar Monaten nur noch wegschmeissen, weil 
weder der Autor und schpon gar nicht ein Anderer den Hauch eine Chance 
hat, den Fehler zu finden.

Gruss
Axel

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Achim S. schrieb:
> Für schlechtere Programmierer (also immer ;-) programmiert man
> konservativ, hier z.b. Klammern, sinnvolle Namen.

 Klammern in solchen Ausdrücken gehören immer dazu. Die paar
 Sekunden die es länger dauert, zahlen sich bei der Fehlersuche
 schon aus.
 Und nur Morons müssen sich selber durch unlesbaren Code ständig
 beweisen, dass sie programmieren können.

 Abgesehen davon, dass kürzest geschriebener Ausdruck nicht immer zu
 kürzestem Code auch compiliert wird.

von Cyblord -. (cyblord)


Lesenswert?

> // to realize this function: if (i & 0b11100100 == 0) ...


Aber ich muss schon sagen, die Idee einen schwer lesbaren Code zu 
programmieren und mit einem vermeintlich besser lesbaren Code zu 
kommentieren ist mir wirklich noch nicht untergekommen. Das ist jetzt 
mal was neues. So programmiert man sicher auf dem Narrenschiff.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Achim S. schrieb:
> Der Kommentar beschreibt das Warum.hier z.b. dass diese Magic Numbers
> vom TO die bitoperationen für bit 0,1,3 und 4 obfuscieren sollen.

Sehr schön gesagt.
Ich vermute mal, das war aber nicht absichtlich. Anfänger tun sich oft 
schwer mit logischen Operationen, obwohl diese für die hardwarenahe 
Programmierung essentiell sind. Einzelne Bits haben immer eine große 
Bedeutung, ob es nun Konfigurationsbits sind oder Portpins.

Da hilft nur, sich die Verschleierung schleunigst abzugewöhnen und immer 
die passenden logischen Operatoren hinzuschreiben. Das ermöglicht auch 
später noch durch den Quelltext überhaupt durchzusehen.

Es schreibt ja auch niemand:
1
  switch( PINB ){
2
    case   0 ...  63:
3
    case 128 ... 191: led_on(); break;
4
    case  64 ... 127:
5
    case 192 ... 255: led_off(); break;
6
  }
sondern:
1
  if( PINB & 1<<6 )
2
    led_off();
3
  else 
4
    led_on();

von Cyblord -. (cyblord)


Lesenswert?

Peter D. schrieb:

> sondern:
>
1
>   if( PINB & 1<<6 )
2
>     led_off();
3
>   else
4
>     led_on();
5
>

Und hier Frage ich mich nun warum die LED an gehen soll, wenn Bit 6 in 
PINB nicht gesetzt ist. Warum nicht Bit 7, oder Bit 5?

Das KANN man natürlich mit einem Kommentar erschlagen z.B.
// Start Taster hängt an PB6 (Bit 6 in PINB)

Oder man schreibt einfach:
1
  if( button_pressed() )
2
    led_off();
3
  else
4
    led_on();

Denn für die LEDs hast du ja auch sprechende Funktionen gewählt (war das 
jetzt Zufall?) und schreibst NICHT PORTB |= (1<<3);
Warum also bei der Bedingung mit Bits wurschteln, bei der Aktion aber 
Funktionen aufrufen.
Kosistent ist das nicht.

: Bearbeitet durch User
von Bitwurschtler (Gast)


Lesenswert?

Cyblord -. schrieb:
> "Kommentare sind gut, lesbarer Code ist besser."
>
> Warum erst verschwurbelten Code schreiben den man hinterher mit
> Kommentaren erläutern muss, anstatt gut lesbaren Code zu schreiben der
> nur minimal kommentiert werden muss?

Also wenn du die Formulierung umkehrst, macht es mehr Sinn

"Lesbarer Code ist gut, Kommentare sind besser"

Aber richtig wird dieser Ratschlag erst wenn Du dich vom "entweder oder" 
trennst. Ich empfehle folgende Vorgehensweise:

1. Beginne die Programmdatei mit einem Kommentar was der Code machen 
soll und wozu er da ist.
2. Codiere effizent und verwende lesbaren Code.
3. wenn "Effizienz und Lesbarkeit unvereinbar sind dann
 a) wenn du dich für effizientere Variante entscheidest, dann dann 
Platziere dort ggf einen Kommentar der das erklärt. Dieser Kommentar 
kann auch den Code in lesbarer Form verwenden, wobei eine 
umgangsprachlicher Formulierung wohl besser ist
 b) wenn du dich für die lesbarer Variante entscheidest, dann platziere 
ggf einen Kommentar das man hier Effizienz gewinnen kann. Das 
erleichtert dann die Optimierung wenn es doch auf Effizient ankommt.

Jetzt im Nachhineien betrachtet ist mein Kommentarvorschlag wohl nicht 
optimal, nächster Vorschlag:
1
/*     Check for subranges 0 .. 3 , 8 .. 11 , 16 .. 19 or 24 .. 27 */
2
if ( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24 <= i && i <= 27){ // something
Obwohl sich der nicht groß von ersten Vorschlag unterscheidet. Viele 
verschiedenen Kommentare sind eben bei einer Zeile Beispielcode eh nicht 
möglich.

Bei lesbaren Code kommt man ziemlich schnell an die Grenzen was man 
überhaupt an Codekonstrukten einsetzen kann. Für manchen Programmiere 
sind Pointer schon verschwurbelt und Arrays die bessere Wahl. Die 
Nutzung von Bitsetz-befehlen beim AVR verlangt eine IMHO verschwurbelte 
Schreibweise mit geshiftetetn bits. 
http://www.mikrocontroller.net/articles/Bitmanipulation#Standard_C_2
Statt zu grübeln ob dann vielleicht doch die langsamer Variante mit OR 
mit Literal wählt, weil die besser verstanden werden könnte sollte man 
doch in jedem Fall einen Kommentar spendieren welches bit nun gesetzt 
wird und was es bewirkt.

Und auch auf den beliebten  und optimal übersetzten
schleifenindexdecrement
1
if (index--)  {

sollte man nicht lange überlegen und auf die besser verständliche 
Variante:
1
index = index - 1;
2
if (index != 0)  {
verzichten, weil die Gefahr besteht das der Compiler das in 
uneffizienten Code umsetzt. Beste Verständlichkeit wird durch gut 
formuliert Kommentare geschaffen, nicht durch Code-Formatierung oder 
Syntaxvarianten.

Gute Kommentare sind nicht ersetzbar, auch nicht durch vermeidlich 
besser lesbaren Code.

von Cyblord -. (cyblord)


Lesenswert?

Bitwurschtler schrieb:

> Jetzt im Nachhineien betrachtet ist mein Kommentarvorschlag wohl nicht
> optimal, nächster Vorschlag:
>
>
1
> /*     Check for subranges 0 .. 3 , 8 .. 11 , 16 .. 19 or 24 .. 27 */
2
> if ( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24 
3
> <= i && i <= 27){ // something
4
>

Jemand der DAS für gut kommentierten Code hält, sollte aufhören anderen 
Tipps geben zu wollen.

von Bitwurschtler (Gast)


Lesenswert?

Cyblord -. schrieb:
> Jemand der DAS für gut kommentierten Code hält, sollte aufhören anderen
> Tipps geben zu wollen.

Was ist dein Vorschlag?

von Peter D. (peda)


Lesenswert?

Cyblord -. schrieb:
> Warum also bei der Bedingung mit Bits wurschteln,

Ganz einfach, weil ich das Prinzip der logischen Operationen 
verdeutlichen wollte.
In der Praxis nehme ich natürlich auch vorher definierte Macros.

von Cyblord -. (cyblord)


Lesenswert?

Bitwurschtler schrieb:
> Cyblord -. schrieb:
>> Jemand der DAS für gut kommentierten Code hält, sollte aufhören anderen
>> Tipps geben zu wollen.
>
> Was ist dein Vorschlag?

Ich rede hier schon genug und gebe genug Beispiele. Das da ist definitiv 
durch und wurde viel weiter oben schon behandelt. Auch von mir.

Auch deine Ausführungen zu lesbare Code vs. Effizienz sind hanebüchen, 
weil man dank guten Compilern derartige Überlegungen nur noch sehr sehr 
selten anstellen muss. Effizienz auf dieser Low-Level Ebene ist nicht 
mehr oft notwendig.
Wirkliche Effizienz kommt dann wieder bei Datentypen oder Algorithmen 
zum Tragen (HashMaps vs. Listen, Bäume, Sortieren, IO Zugriffe, Caching 
usw.). Und da steht Effizienz in keinem Widerspruch zu sauberem Code.

von Peter II (Gast)


Lesenswert?

Cyblord -. schrieb:
>> Was ist dein Vorschlag?
>
> Ich rede hier schon genug und gebe genug Beispiele.

nein hast nicht. du hast kein Beispiel gegeben wie es lesbar ist und die 
gleiche Funktionalität vorhanden ist.

von Cyblord -. (cyblord)


Lesenswert?

> Ganz einfach, weil ich das Prinzip der logischen Operationen
> verdeutlichen wollte.

Das verdeutlichen von Prinzipien führt selten zu gutem Code. Du bist 
eben der Meinung weil man hardwarenah programmeiert ist das Konzept der 
Bitmasken derart präsent dass man es überall in den Code streuen kann. 
Aber ich sage, ob hw-nah oder nicht, das spielt keine Rolle, solche 
Masken wild in den Code zu bauen, führt zu schwer leserlichem und schwer 
wartbarem Code.


> nein hast nicht. du hast kein Beispiel gegeben wie es lesbar ist und die
> gleiche Funktionalität vorhanden ist.
Peter, das meinst du nur weil du meinen Ausführungen intellektuell nicht 
folgen kannst.

: Bearbeitet durch User
von Bitwurschtler (Gast)


Lesenswert?

Cyblord -. schrieb:
> Bitwurschtler schrieb:
>> Cyblord -. schrieb:
>>> Jemand der DAS für gut kommentierten Code hält, sollte aufhören anderen
>>> Tipps geben zu wollen.
>>
>> Was ist dein Vorschlag?
>
> Ich rede hier schon genug und gebe genug Beispiele. Das da ist definitiv
> durch und wurde viel weiter oben schon behandelt. Auch von mir.

Dann schreib diese deiner Meinung nach richtige  Zeile bitte hier für 
mich hin, ich finde sie in den oberen Bildschirmmetern nicht. ein Link 
auf den entsprechden deiner Beiträge waäre genaus hilfreich.

> Auch deine Ausführungen zu lesbare Code vs. Effizienz sind hanebüchen,
> weil man dank guten Compilern derartige Überlegungen nur noch sehr sehr
> selten anstellen muss.

Wer sich auf seinen Compiler verlassen muss, der ist verlassen. Wer 
garantiert dir das der Code nicht durch einen andern Compiler übersetzt 
wird oder mit anderen Optimierungsoptionen? Willst du im Quelltext immer 
vermerken für welchen Compiler das snippet gedacht ist.

Nochmals, ich glaube nicht das ein Compiler immer den Konflikt zwischen 
Lesbarkeit und Effizienz auflösen kann. Er muss es auch nicht, wenn sich 
von dem Konzept "Lesbaren Code um jeden Preis und durch 
Kommentarvermeidung" löst.

von Peter II (Gast)


Lesenswert?

Cyblord -. schrieb:
>> nein hast nicht. du hast kein Beispiel gegeben wie es lesbar ist und die
>> gleiche Funktionalität vorhanden ist.
> Peter, das meinst du nur weil du meinen Ausführungen intellektuell nicht
> folgen kannst.

mein Compiler kann dir auch nicht folgen
1
test.c:4:6: warning: implicit declaration of function 'valueCanDividedBy4'

von Cyblord -. (cyblord)


Lesenswert?

Bitwurschtler schrieb:

> Wer sich auf seinen Compiler verlassen muss, der ist verlassen. Wer
> garantiert dir das der Code nicht durch einen andern Compiler übersetzt
> wird oder mit anderen Optimierungsoptionen? Willst du im Quelltext immer
> vermerken für welchen Compiler das snippet gedacht ist.

Dann musst du Assembler verwenden und darfst gar nicht kompilieren. 
Natürlich muss man sich auf den Compiler verlassen. Natürlich gibt es 
andere Compiler und sogar ganz andere Architekturen für die ein Programm 
vielleicht kompiliert wird.
Will man die absolute Effizienz muss man sich auf ein Zielsystem 
festlegen und ASM programmieren. Anderes geht es nicht.

> Nochmals, ich glaube nicht das ein Compiler immer den Konflikt zwischen
> Lesbarkeit und Effizienz auflösen kann. Er muss es auch nicht, wenn sich
> von dem Konzept "Lesbaren Code um jeden Preis und durch
> Kommentarvermeidung" löst.

Manuelle Optimierung von Syntax hinsichtlich Effizienz ist das 
schlimmste was man heutzutage so machen kann. Weil es die Effizienz in 
99% der Fälle nicht steigert, dafür die Fehleranfälligkeit drastisch 
erhöht.

@Peter:
Willst du nicht woanders spielen? Ich kann dich leider nicht ernst 
nehmen. Erst den Coder-Proll und dann den Clown raushängen lassen. Na 
danke.
Willst du nicht wenigstens mal eine Minute nachdenken über das was ich 
dazu geschrieben habe?

: Bearbeitet durch User
von Bitwurschtler (Gast)


Lesenswert?

Cyblord -. schrieb:
> Manuelle Optimierung von Syntax hinsichtlich Effizienz ist das
> schlimmste was man heutzutage so machen kann. Weil es die Effizienz in
> 99% der Fälle nicht steigert, dafür die Fehleranfälligkeit drastisch
> erhöht.

Reine Schutzbehauptung deinerseits, dazu unbelegt, nicht mal ein 
einziges Beispiel hast Du angeführt.

> Will man die absolute Effizienz muss man sich auf ein Zielsystem
> festlegen und ASM programmieren. Anderes geht es nicht.

Doch, es geht anders. Beispiel Artikel Bitmanipulation AVR, oben 
verlinkt. Das erfordert aber "verschwurbelten" C-Code damit der 
C-Compiler erkennt das er den Bitset befehl verwenden kann. Was kein 
Problem ist wenn man nicht sklavisch "lesbaren Code" schreiben will.

von Axel L. (axel_5)


Lesenswert?

Cyblord -. schrieb:
> Bitwurschtler schrieb:
>
>> Jetzt im Nachhineien betrachtet ist mein Kommentarvorschlag wohl nicht
>> optimal, nächster Vorschlag:
>>
>>
1
>> /*     Check for subranges 0 .. 3 , 8 .. 11 , 16 .. 19 or 24 .. 27 */
2
>> if ( 0 <= i && i <= 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
3
>> <= i && i <= 27){ // something
4
>>
>
> Jemand der DAS für gut kommentierten Code hält, sollte aufhören anderen
> Tipps geben zu wollen.

Wieso, das ist super.

Denn damit würde der folgende Fehler:
1
/*     Check for subranges 0 .. 3 , 8 .. 11 , 16 .. 19 or 24 .. 27 */
2
if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
3
<= i && i <= 27){ // something

zumindest eine Chance haben, im Review gefunden zu werden.

Gruss
Axel

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Cyblord -. schrieb:
> Das verdeutlichen von Prinzipien führt selten zu gutem Code.

Es führt aber zu verstehbarem Code.
Es ist nicht die Aufgabe des Compilers, zu erkennen, ob hinter 
kryptischen Vielfachvergleichen einfach nur eine Bitoperation steht, 
sondern die Aufgabe des Programmierers.
Und wenn dem so ist, dann hat er es gefälligst auch so hinzuschreiben.
Sonst wird der Code völlig chaotisch und unverstehbar.
Code muß nicht nur mathematisch richtig sein, sondern er muß auch 
sinnvoll erscheinen.

Natürlich kann man mit kryptischen Vielfachvergleichen auch ohne 
Bitoperationen feststellen, ob z.B. beim ATmega8 im TIFR-Register die 
Bits TOV0, TOV1 oder TOV2 gesetzt sind. Nur wird Dir dann jeder 
ernsthafte Programmierer nen Vogel zeigen.

von nicht"Gast" (Gast)


Lesenswert?

Axel L. schrieb:
> Denn damit würde der folgende Fehler:/*     Check for subranges 0 .. 3 ,
> 8 .. 11 , 16 .. 19 or 24 .. 27 */
> if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
> <= i && i <= 27){ // something
>
> zumindest eine Chance haben, im Review gefunden zu werden.

Ja klar. Frage, was ist denn jetzt richtig. Der Code oder der Kommentar?

Solche Fehler sollten bei Unit Tests auffallen, nicht bei Reviews.

von Axel L. (axel_5)


Lesenswert?

nicht"Gast" schrieb:
> Axel L. schrieb:
>> Denn damit würde der folgende Fehler:/*     Check for subranges 0 .. 3 ,
>> 8 .. 11 , 16 .. 19 or 24 .. 27 */
>> if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
>> <= i && i <= 27){ // something
>>
>> zumindest eine Chance haben, im Review gefunden zu werden.
>
> Ja klar. Frage, was ist denn jetzt richtig. Der Code oder der Kommentar?
>
> Solche Fehler sollten bei Unit Tests auffallen, nicht bei Reviews.

Ist egal, entscheidend ist, dass da jemand drüber sieht, und eines von 
beidem korrigiert.

Und Tests sind immer schön, aber meine Erfahrung ist, dass man im Review 
regelmässig noch was findet, was im Test nicht aufgefallen ist. Im 
Beispiel oben wäre es fast schon Zufall, wenn ausgerechnet die 3 
getestet würde.

Natürlich nur, wenn die Kommentare was taugen, ansonsten kämpft sich 
keiner durch den Code und versucht zu verstehen, was da gemeint ist. Es 
ist sogar noch schlimmer, denn fehlerhafter Code ist schwerer zu 
verstehen, und dann ist die Neigung, den Tests zu vertrauen, statt die 
Ursache für das Unverständnis zu finden, noch grösser.

Gruss
Axel

von Masl (Gast)


Lesenswert?

Die Frage wurde klar formuliert:

Elias *. schrieb:
> 1) Es funktioniert, aber ich wollte fragen ob es eine schönere Lösung
> dafür gibt?

Wie man also auf solche Antworten kommt:
Johann L. schrieb:
> if ((i & 0xFFE7) < 4)

verstehe ich nicht wirklich.
Dir gings doch nur darum hier irgendwie den Haxx0r raushängen zu lassen?

von Peter D. (peda)


Lesenswert?

Masl schrieb:
> Wie man also auf solche Antworten kommt:
> Johann L. schrieb:
>> if ((i & 0xFFE7) < 4)
>
> verstehe ich nicht wirklich.

Ich schon.
Das ist einfach nur ein erster Versuch gewesen, weil ja die eigentliche 
Aufgabe (Bitmaske) verschleiert wurde.

von Mark B. (markbrandis)


Lesenswert?

Peter D. schrieb:
> Ich schon.
> Das ist einfach nur ein erster Versuch gewesen, weil ja die eigentliche
> Aufgabe (Bitmaske) verschleiert wurde.

Niemand kennt die eigentliche Aufgabe mit Sicherheit, außer dem 
Themenersteller. Und der war nicht so clever sie uns zu nennen.

von Bitwurschtler (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Axel L. schrieb:
>> Denn damit würde der folgende Fehler:/*     Check for subranges 0 .. 3 ,
>> 8 .. 11 , 16 .. 19 or 24 .. 27 */
>> if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
>> <= i && i <= 27){ // something
>>
>> zumindest eine Chance haben, im Review gefunden zu werden.
>
> Ja klar. Frage, was ist denn jetzt richtig. Der Code oder der Kommentar?

Das entscheidet die Spec, die muss man lesen.

> Solche Fehler sollten bei Unit Tests auffallen, nicht bei Reviews.

Und wen der fehler beim Unittest auffällt muss man immer noch die 
verantwortlichen Codezeile finden -> also ab in den Review.

Oder baut man neuerdings Error-Correction-Layers über schlecht 
dokumentierten Code? Oder wirft den Code weg und schreibt es from the 
scratch und hoffentlich mit geeigneten Kommentaren neu?

von Mark B. (markbrandis)


Lesenswert?

Bitwurschtler schrieb:
> nicht"Gast" schrieb:
>> Axel L. schrieb:
>>> Denn damit würde der folgende Fehler:/*     Check for subranges 0 .. 3 ,
>>> 8 .. 11 , 16 .. 19 or 24 .. 27 */
>>> if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
>>> <= i && i <= 27){ // something
>>>
>>> zumindest eine Chance haben, im Review gefunden zu werden.
>>
>> Ja klar. Frage, was ist denn jetzt richtig. Der Code oder der Kommentar?
>
> Das entscheidet die Spec, die muss man lesen.

Im Prinzip ja. Dann gibt es noch den schönen Fall, dass die 
Spezifikation falsch ist. Immer wieder toll :-)

von Bitwurschtler (Gast)


Lesenswert?

Mark B. schrieb:
> Im Prinzip ja. Dann gibt es noch den schönen Fall, dass die
> Spezifikation falsch ist. Immer wieder toll :-)

Wenn die Spec falsch ist dürfte aber der Unittest nicht meckern, weil 
der doch auch seine Referenzwerte aus der Spec zieht.

Da macht es sich gut wenn die die die Spec geschrieben hat, auch den 
Code oder wenigstens die Kommentare darin lesen und verstehen kann. Dann 
fällt vielleicht der Groschen das

von Yalu X. (yalu) (Moderator)


Lesenswert?

Mark B. schrieb:
> Niemand kennt die eigentliche Aufgabe mit Sicherheit, außer dem
> Themenersteller.

Ich bin ja mit dir nicht immer einer Meinung, aber hier hast du absolut
recht :)

Deswegen frage ich mich gerade, warum die Leute hier über gute und
schlechte Kommentare zur Codezeile des TE diskutieren. Da der tiefere
Sinn bzw. die dahintersteckende Absicht dieser Codezeile nicht bekannt
sind, kann jeder ausgedachte Kommentar (egal wie er aussieht) nur die
Codezeile als solche in anderen Worten beschreiben. Solche Kommentare
sind aber – das wurde ja bereits zurecht festgestellt – völlig
überflüssig.

Ihr solltet den TE bitten, Sinn und Zweck seiner Codezeile in möglichst
kurzen Worten zu beschreiben. Seine Antwort wäre dann ein guter Kandidat
für einen Kommentar über der Zeile.

von avr (Gast)


Lesenswert?

Masl schrieb:
> verstehe ich nicht wirklich.
> Dir gings doch nur darum hier irgendwie den Haxx0r raushängen zu lassen?

Wenn ein Gefühl für die binäre Darstellung hat und weiß, dass Vergleiche 
und Modulo-Operationen mit 2er-Potenzen nichts anderes als 
Bit-Maskierungen sind, lässt sich der Code recht schnell umformen:
1
if(i % 8 < 4 && i < 32)
In Bitmasken:
%8  :  7
<4  : ~3
<32 : ~31

7 & ~3 | ~31  = 0b11100100 = 0xE4 // Hatten wir hier schon mehrfach
7 | ~31       = 0b11100111 = 0xE7 // Johanns Lösung, ohne <4

von nicht"Gast" (Gast)


Lesenswert?

Bitwurschtler schrieb:
> Und wen der fehler beim Unittest auffällt muss man immer noch die
> verantwortlichen Codezeile finden -> also ab in den Review.

Selbst das ist viel einfacher, weil der Unittest direkt die Funktion 
testet, welche die Entscheidung über if or not if fällt.

Wenn ich umfangreiche Bedingunen im if Kopf drin habe, kann ich dir gar 
nicht isoliert testen sondern immer nur im Kontext übergeordneten 
Funktion. Wenn dann der Unittest kracht, darf ich einen noch viel 
größeren Bereich nach Fehlern absuchen.

Aber du wirst jetzt sicher behaupten, dass ist viel einfacher.

von Bitwurschtler (Gast)


Lesenswert?

Yalu X. schrieb:
> Solche Kommentare
> sind aber – das wurde ja bereits zurecht festgestellt – völlig
> überflüssig.

Dem hab ich widersprochen und ich bleib dabei, für C-Programmierer mag 
das überflüssig sein, aber nicht für alle anderen wie 
Requirements-Autor, Programmierer andere Programiersprachen, Tester, PM, 
Uni-Frischlinge, ...

Und es beschreibt keinesfalls den einzelnen Code nur mit anderen Worten 
sondern beschreibt was die Funktion des Codes ist, nämlich Teilbereiche 
abchecken.

Wegen dem genannten Mangel an Information ist nunmal der Kommentar 
reichlich unbefriedigend aber immer noch der best mögliche. Besser 
jedenfall ls die Versuche mit Verteilen der einzelnen Terme auf mehrere 
eile Lesnarkeit zu verbessern.

Aber das ist meine Meinung, muss man nicht teilen - bleibt mehr für mich 
;-)

von nicht"Gast" (Gast)


Lesenswert?

Yalu X. schrieb:
> Ihr solltet den TE bitten, Sinn und Zweck seiner Codezeile in möglichst
> kurzen Worten zu beschreiben. Seine Antwort wäre dann ein guter Kandidat
> für einen Kommentar über der Zeile.

Oder für einen Funktionsnamen^^
SCNR

von Bitwurschtler (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Aber du wirst jetzt sicher behaupten, dass ist viel einfacher.

Nein.

von nicht"Gast" (Gast)


Lesenswert?

Axel L. schrieb:
> Und Tests sind immer schön, aber meine Erfahrung ist, dass man im Review
> regelmässig noch was findet, was im Test nicht aufgefallen ist. Im
> Beispiel oben wäre es fast schon Zufall, wenn ausgerechnet die 3
> getestet würde.

Also Test falsch

Mark B. schrieb:
> Im Prinzip ja. Dann gibt es noch den schönen Fall, dass die
> Spezifikation falsch ist. Immer wieder toll :-)

Also Spec falsch

Axel L. schrieb:
> /*     Check for subranges 0 .. 3 , 8 .. 11 , 16 .. 19 or 24 .. 27 */
> if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
> <= i && i <= 27){ // something

Also Code falsch

Axel L. schrieb:
> Denn damit würde der folgende Fehler:/*     Check for subranges 0 .. 3 ,
> 8 .. 11 , 16 .. 19 or 24 .. 27 */
> if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
> <= i && i <= 27){ // something

Oder Kommentar falsch.

https://de.wikipedia.org/wiki/Zirkelbezug

Auch eine Art der Diskussion, wenn einem keine echten Argumente mehr 
einfallen.

von Bitwurschtler (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Auch eine Art der Diskussion, wenn einem keine echten Argumente mehr
> einfallen.

Hier liegt aber kein Zirkelbezug vor.

von Axel L. (axel_5)


Lesenswert?

nicht"Gast" schrieb:
> Axel L. schrieb:
>> Und Tests sind immer schön, aber meine Erfahrung ist, dass man im Review
>> regelmässig noch was findet, was im Test nicht aufgefallen ist. Im
>> Beispiel oben wäre es fast schon Zufall, wenn ausgerechnet die 3
>> getestet würde.
>
> Also Test falsch
>
> Mark B. schrieb:
>> Im Prinzip ja. Dann gibt es noch den schönen Fall, dass die
>> Spezifikation falsch ist. Immer wieder toll :-)
>
> Also Spec falsch
>
> Axel L. schrieb:
>> /*     Check for subranges 0 .. 3 , 8 .. 11 , 16 .. 19 or 24 .. 27 */
>> if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
>> <= i && i <= 27){ // something
>
> Also Code falsch
>
> Axel L. schrieb:
>> Denn damit würde der folgende Fehler:/*     Check for subranges 0 .. 3 ,
>> 8 .. 11 , 16 .. 19 or 24 .. 27 */
>> if ( 0 <= i && i < 3 || 8 <= i && i <= 11 || 16 <= i && i <= 19 || 24
>> <= i && i <= 27){ // something
>
> Oder Kommentar falsch.
>
> https://de.wikipedia.org/wiki/Zirkelbezug
>
> Auch eine Art der Diskussion, wenn einem keine echten Argumente mehr
> einfallen.

In dem Moment, wo Software fehlerfrei wäre, hättest Du recht.

Dummerweise ist sie das nicht. Weder Specs noch Code sind fehlerfrei. 
Tests testen nie 100%.

Man sollte daher jede Gelegenheit nutzen, um solche Fehler zu vermeiden 
oder zu finden, vernünftige Kommentare sind eine Möglichkeit.

Gruss
Axel

von nicht"Gast" (Gast)


Lesenswert?

Axel L. schrieb:
> In dem Moment, wo Software fehlerfrei wäre, hättest Du recht.
>
> Dummerweise ist sie das nicht. Weder Specs noch Code sind fehlerfrei.
> Tests testen nie 100%.
>
> Man sollte daher jede Gelegenheit nutzen, um solche Fehler zu vermeiden
> oder zu finden, vernünftige Kommentare sind eine Möglichkeit.

Ist mir ja bewusst, ich wollte nur aufzeigen, dass sich die Diskussion 
hier im Kreis dreht. Die Argumente werden ja benutzt um überlange 
Operationen und sinnlose Kommentare in if Köpfen zu rechtfertigen :)

von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Ihr solltet den TE bitten, Sinn und Zweck seiner Codezeile in möglichst
> kurzen Worten zu beschreiben.

Warum wir? Das kannst Du doch genau so gut tun.

Man könnte sogar mit einigem Recht meinen, dass es hierzu einen Passus 
unter "Wichtige Regeln - erst lesen, dann posten!" geben sollte.

Zum Beispiel:
"Poste nicht irgendeinen Code, sondern beschreibe was der Sinn dahinter 
ist. Also welche konkrete Aufgabe damit gelöst werden soll."

Aber dafür sind nicht wir zuständig, sondern der Betreiber.

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Wofür brauchen wir den TE eigentlich noch, wenn man ohne ihn viel besser 
über Dinge streiten kann, die er gar nicht wissen wollte? ;)

von Stefan (Gast)


Lesenswert?

"den TE bitten, Sinn und Zweck seiner Codezeile in möglichst
kurzen Worten zu beschreiben"

Wozu?!?! Er fragt nach schöneren Möglichkeiten und nun werden 
verschiedene gesammelt und besprochen, zweck erfüllt.
Wenn es das nicht wäre, hätte er sicher was gesagt!

von Stefan (Gast)


Lesenswert?

"Wofür brauchen wir den TE eigentlich noch, wenn man ohne ihn viel 
besser
über Dinge streiten kann, "

LOL genauso das trifft es in diesem Forum auf den Punkt..eigentliche 
Fragen sind sowieso nutzlos was hier alles zerredet und mit Gegenfragen 
zerfleddert wird :-)
Man braucht sich nur den Spaß machen was in den Raum werfen und kann 
dann den PC abschalten..
Das Forum ist garantiert die nächsten 3-4 Tage damit beschäftigt sich um 
irgendwas völlig belangloses zu zoffen, die eigentlich Frage aber 
unbeantwortet zu lassen :-)
Ich lieb das hier zu beobachten :-)
Und die MODs machen fleissig mit anstatt und werfen Wörter wie Troll 
dazu, die eigentlich in jedem zweiten Thrwad vorkommen :-)

von Mark B. (markbrandis)


Lesenswert?

Stefan schrieb:
> "den TE bitten, Sinn und Zweck seiner Codezeile in möglichst
> kurzen Worten zu beschreiben"
>
> Wozu?!?! Er fragt nach schöneren Möglichkeiten und nun werden
> verschiedene gesammelt und besprochen, zweck erfüllt.
> Wenn es das nicht wäre, hätte er sicher was gesagt!

Du gehst anscheinend davon aus, dass jeder der eine Frage stellt auch 
die richtige Frage stellt. Dem ist aber nicht so.

Programmieren ist kein reiner Selbstzweck. Es soll etwas Bestimmtes 
getan werden: Das ist das WAS. Die konkrete Umsetzung in Code ist das 
WIE.

Ohne das WAS kann ein sinnvolles WIE nicht existieren, es kann sich 
nicht in einem Vakuum befinden.

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

wenn er sieht das er damit nicht zum Ziel kommt würde er es sicher 
selbst sagen....

von Mark B. (markbrandis)


Lesenswert?

Stefan schrieb:
> wenn er sieht das er damit nicht zum Ziel kommt würde er es sicher
> selbst sagen....

Was ist das Ziel? Wissen wir es? Weiß er es? :-)

von Stefan (Gast)


Lesenswert?

das ist das Problem...ALLE wissen immer alles besser als der der die 
Frage gestellt hat..deshalb führt es hier auch nie zu was....da er sich 
nicht mehr meldet ist das Thema wohl durch oder er es hat nicht zum Ziel 
geführt...genug der Diskussion..zurück zum Thema!

von Yalu X. (yalu) (Moderator)


Lesenswert?

Mark B. schrieb:
> Yalu X. schrieb:
>> Ihr solltet den TE bitten, Sinn und Zweck seiner Codezeile in möglichst
>> kurzen Worten zu beschreiben.
>
> Warum wir? Das kannst Du doch genau so gut tun.

Das betrifft doch nur die, die krampfhaft irgenwelche tollen Kommentare
über die Codezeile schreiben wollen. Danach war aber weder gefragt, noch
halte ich die Zeile für so kryptisch, dass sie unbedingt nach einem
Kommentar verlangt.

Stefan schrieb:
> Wozu?!?! Er fragt nach schöneren Möglichkeiten und nun werden
> verschiedene gesammelt und besprochen, zweck erfüllt.

So ist es.

Ich finde es überhaupt nicht schlimm, wenn nach Beantwortung der
eigentlichen Frage noch über angrenzende Themen weiterdiskutiert wird.
Nur fehlt bei der Diskussion um die Kommentare hier leider die
Diskussionsgrundlage, was ich in meinem letzten Beitrag einfach mal zu
bedenken geben wollte.

von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Das betrifft doch nur die, die krampfhaft irgenwelche tollen Kommentare
> über die Codezeile schreiben wollen.

Nein. Du irrst Dich.

> Danach war aber weder gefragt

Du gehst von der falschen Annahme aus, dass immer nur exakt die Frage zu 
beantworten ist, die wortwörtlich gestellt wurde. Dem ist aber nicht so.

Ein fähiger Entwickler sollte wissen, dass man oft genug die Prämissen 
hinterfragen muss und nicht alles für bare Münze nehmen darf.

von Schorsch X. (bastelschorsch)


Lesenswert?

if (i & 0b11100100 == 0) ... (Paddy)

scheint mir die schnellste und eleganteste Lösung zu sein...mit 
beliebigen 1ern obendran.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Yalu X. schrieb:
> Nur fehlt bei der Diskussion um die Kommentare hier leider die
> Diskussionsgrundlage,

Zur Klärung des "Warum" ist ein sinnvoller Kommentar hier nicht 
möglich. Die Kontroverse(n) ist/sind jedoch m.E. allgemeiner Art.

a) soll ein Kommentar die Umsetzung in C erklären? (*)
b) ist excessive Kapselung sinnvoll
c) darf ein Programmierer denken (hier Bitoperationen erkennen statt 
magischer Wertebereiche). Bis hin zu: Darf er nachfragen, woher solche 
komischen Wertebereiche kommen?

*) ich hatte mal in einem Buch bezüglich Kommentare sinngemäß:
1
   /**************
2
   *  i = i + 1  *
3
   **************/
4
   
5
   i=i+1;
mit der Anmerkung: Lachen Sie nicht, bis sie es codiert sehen.

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.