RobertDebiannutzer hat geschrieben: 23.08.2018 21:15:54
Meillo hat geschrieben: 23.08.2018 17:44:00
... wobei manch ein C-Programmierer natuerlich ``if (!*name) {'' schreiben wuerde.
Ja, das würde ich auch versuchen, denn dann hätte man einen function-Aufruf weniger. Aber man hat mir gesagt, ich solle doch im Zweifelsfall lieber die Lesbarkeit als die Performance-Optimierung wählen...
Ich habe das ja gerade wegen der Lesbarkeit vorgeschlagen!
Die Lesbarkeit ist allerdings nur dann besser, wenn man das Idiom kennt und gewoehnt ist. Idiome sind ein wichtiges Hilfsmittel fuer gute Lesbarkeit: Man hat also Codestuecke, die immer gleich sind, so dass man sie gar nicht genau anschauen muss, sondern auf den ersten Blick weiss, was sie bedeuten. Ein typisches Idiom sind Zaehlschleifen in C, die man immer als ``for (i=0; i<num; i++) {'' schreiben sollte. Notfalls kann man auch noch ``for (i=1; i<=num; i++) {'' verwenden. Andere Faelle sollte man vermeiden. Wenn Code so geschrieben ist, dann muss ich mir keine Zaehlschleife mehr genau anschauen, weil ich auf den ersten Blick weiss, wie oft sie laufen wird.
Man entwickelt dann auch einen Blick dafuer, wenn sie ``komisch'' aussehen, d.h. also nicht so sind wie erwartet. Das sind aber Faelle, wo Kommentare sehr hilfreich sind: Immer dann wenn etwas nicht so ist wie man es erwarten wuerde. Codelesen hat viel mit Aufmerksamkeit zu tun. Man muss die Aufmerksamkeit des Codelesers an die relevanten Stellen lenken, weil er nur ein gewisses Mass an Aufmerksamkeit hat, das man moeglichst sinnvoll verteilen sollte. Das jedenfalls sind einige Meiner Gedanken zu gutem Code ...
Den Unterschied zwischen 0, NULL und ’\0’ habe ich jetzt übrigens glaube ich schon besser verstanden:
- 0 ist ein integer
- NULL ist ein pointer, d.h., dass NULL auf eine Speicher-Adresse zeigt, deren Wert 0 ist. Zugleich ist NULL als Makro des Compilers definiert.
- ’\0’ ist ein Zeichen, das nichts enthält. Also ein byte, dessen bits alle 0 sind.
Richtig so?
Ja.
0 war einfach.
'\0' ist ein `char', und enthaelt das Zeichen ASCII NUL, also das allererste (an nullter Position). Es ist korrekt, dass bei ihm alle Bits null sind.
NULL ist ein Pointer. Ein Pointer hat als Wert eine Speicheradresse. NULL hat als Wert die Adresse 0. An der Stelle sind kein Code und keine Daten zu finden. Bei virtueller Speicherverwaltung ist die nullte Page dem Prozess nicht zugeordnet. Wenn man den NULL-Pointer dereferenziert, dann erzeugt das einen Segfault. Darum sollte man auch ganz brav immer erst auf NULL pruefen, bevor man Rueckgabewerte dereferenziert.
Definiert ist NULL hier: /usr/include/linux/stddef.h
Frueher (bevor es void* gab), war NULL ein char*. Letztlich muss es halt ein Pointer sein, der sich in jeden anderen casten laesst.
So wie ich es verstehe, kann man 0 immer für ifs nutzen, denn NULL und ’\0‘ laufen auch auf den int 0 hinaus.
Ja, das wird dann automatisch gecastet. Dabei geht alles glatt weil alle drei Werte (in allen Implementierungen) jeweils nur Nullen in allen Bits haben.
Wenn du aber explizit vergleichst, solltest du moeglichst die richtigen Typen verwenden, weil das IMO Irritationen vermeidet. Gerade als Anfaenger ist es in C wichtig stets auf die Datentypen zu achten. Zumeist sind es, meiner Erfahrung nach, eher die Anfaenger, die ueberall 0 schreiben wollen (damit sie sich das Nachdenken sparen koennen), als dass die Profis sich damit ein paar Zeichen sparen wollen. Sich aber bei C das Nachdenken und das komplette Verstehen sparen zu wollen, holt einen sehr schnell ein! C ist ein scharfes Messer -- man sollte besser genau wissen was man damit tut!
Btw: Der obere und der untere Teil meiner Mail scheinen sich zu widersprechen. Teilweise tun sie das ... und zeigen damit, dass es stets um das Abwaegen verschiedener Ziele geht. Es gibt nur wenige einfache Antworten (wie, auch bei einzeiligen Bloecken immer geschweifte Klammern zu setzen
); fast immer geht es um das Verstehen der komplexen Zusammenhaenge und das Treffen begruendbarer und stimmiger Entscheidungen.