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!
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 ?
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.
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?
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:
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:
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.
> 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.
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.
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.
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.
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.>>
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.
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)
> 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.
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.
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"
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.
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 ;)
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 */
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.
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.
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?
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.
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.
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.
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.
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.
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.
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...
@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?
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.
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.
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.
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.
>> 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.
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. ;-)
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.
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.
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.
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.
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.
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.
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.
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 ;-)
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.
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.
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.
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:
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?)
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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 ?!?
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.
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
staticinlineintin_range(intvalue,intlow,inthigh)
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.
> 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
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
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:
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.
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
intButtonState=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.
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.
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...
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.
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) ...
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.
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
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
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.
> // 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.
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:
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.
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 */
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.
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.
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.
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.
> 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.
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.
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'
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?
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.
>>/* 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
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.
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.
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
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?
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.
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.
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?
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 :-)
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
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.
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
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.
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
;-)
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
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.
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
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 :)
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.
"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!
"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 :-)
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.
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!
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.
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.
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.