Ein Kommentar ist Text, den der Compiler wegwirft. Er existiert rein für die Leute, die den Code später lesen, und eine davon bist meist du selbst. C bietet zwei Formen, und zu wissen, wann welche das richtige Werkzeug ist, dauert ungefähr zwei Minuten.
Die zwei Formen
Führe es aus: Die Ausgabe ist eine Zeile. Beide Kommentare wurden gelöscht, bevor der Compiler das Programm überhaupt las - sie kosten zur Laufzeit nichts und fügen der ausführbaren Datei nichts hinzu.
// läuft bis zum Ende der physischen Zeile. Nichts kann in dieser Zeile darauf folgen, das hier funktioniert also nicht so, wie es aussieht:
int x = 5; // setze x auf fünf int y = 6; /* y wird nie deklariert */
/* ... */ endet beim ersten */, wo auch immer das steht. Es kann mitten in einer Zeile beginnen und enden, was gelegentlich nützlich ist:
int total = price /* vor Steuern */ + shipping;
Warum es zwei Stile gibt
/* */ ist ursprüngliches C, von 1972. // kam von C++ und wurde erst mit C99 offiziell zu C hinzugefügt. Diese Geschichte erklärt etwas, das dir beim Lesen älteren Codes auffallen wird: Bibliotheken, die auf C89 portierbar sein sollten, verwenden /* */ auch für einzeilige Kommentare, weil // auf den alten Werkzeugketten, die sie noch unterstützten, nicht kompiliert hätte.
Heute akzeptiert jeder Compiler, den du wahrscheinlich benutzt, beide. Nimm // für gewöhnliche Anmerkungen und /* */, wenn sich ein Kommentar wirklich über Zeilen erstreckt. Wenn du auf einen sehr alten Embedded-Compiler zielst, prüfe nach, bevor du dich auf // verlässt.
Kommentare lassen sich nicht verschachteln
Das ist die eine echte Falle:
/* Diesen Abschnitt vorerst abschalten
int a = compute();
/* der klassische Helfer - behalte ihn im Auge */
int b = a * 2;
*/
Der Blockkommentar endet beim ersten */, also bei dem in Zeile 3. Die Zeilen 4 und 5 sind dann wieder lebender Code, und das abschließende */ in Zeile 6 ist ein Syntaxfehler. Die Meldung des Compilers zeigt auf die letzte Zeile und ist zur Ursache vollkommen unbrauchbar.
Die Lösung ist, stattdessen den Präprozessor zu nehmen, der Verschachtelung sehr wohl verträgt:
#if 0
int a = compute();
/* der klassische Helfer - behalte ihn im Auge */
int b = a * 2;
#endif
#if 0 ist nie wahr, der Präprozessor löscht also alles bis #endif, bevor der Compiler es sieht. Es übersteht Kommentare, Anführungszeichen und andere #if-Blöcke darin, und es lässt sich beim Aufräumen leicht finden.
Code beim Debuggen auskommentieren
Eine Zeile vorübergehend zu entfernen ist die häufigste alltägliche Verwendung von Kommentaren. Wenn ein Programm sich falsch verhält, sagt dir das Abschalten einer Anweisung nach der anderen, auf welche es ankommt.
Kommentiere das printf wieder ein und lass es erneut laufen, um zuzusehen, wie die Schleife ihre Antwort aufbaut. Mit Ausgaben zu verfolgen ist nicht elegant, aber in C ist es schnell und funktioniert immer - ein Debugger sagt dir mehr, und ein printf sagt dir sofort etwas.
Zwei Gewohnheiten verhindern, dass daraus ein Durcheinander wird. Lösche auskommentierten Code, bevor du ihn eincheckst; die Versionsverwaltung merkt sich die alte Fassung, damit du es nicht musst. Und wenn du eine abgeschaltete Zeile bewusst stehen lässt, schreibe daneben, warum.
Dokumentationskommentare
Ein Blockkommentar über einer Funktion ist der Ort, an dem du erklärst, was sie tut, was ihre Parameter bedeuten und was an ihr überraschend ist.
Werkzeuge wie Doxygen lesen solche strukturierten Kommentare und erzeugen daraus Referenzdokumentation. Doxygens eigener Stil verwendet /** ... */ mit @param- und @return-Markierungen:
/**
* Wandelt Celsius in Fahrenheit um.
* @param c Temperatur in Celsius
* @return dieselbe Temperatur in Fahrenheit
*/
double celsius_to_fahrenheit(double c);
Für deinen eigenen Code ist beides in Ordnung. Wichtig ist, dass der Kommentar neben der Deklaration steht, die die Leute lesen - typischerweise in der Header-Datei - statt in der Implementierung vergraben zu sein.
Was kommentierenswert ist
Die Regel, die den Kontakt mit echten Codebasen übersteht: Kommentiere das Warum, nicht das Was.
i++; // erhöhe i <- sagt nichts, was der Code nicht schon sagte
/* Das BOM überspringen: Dateien, die das alte System exportiert,
beginnen mit drei Bytes, die nicht zu den Daten gehören. */
offset += 3;
Der zweite Kommentar enthält Information, die nirgends im Code steht. Der erste ist Rauschen, das irgendwann der Zeile widersprechen wird, die es beschreibt, denn Kommentare werden nicht mitgepflegt, wenn sich Code ändert.
Was speziell in C wirklich einen Kommentar verdient:
- Wem dieser Speicher gehört. Wenn eine Funktion einen Zeiger liefert, den der Aufrufer mit
freefreigeben muss, schreib es hin. C hat keine Möglichkeit, das im Typ auszudrücken. - Einheiten und Wertebereiche.
int timeout;ist mehrdeutig - Sekunden oder Millisekunden? - Nicht offensichtliche Korrektheit. Warum die Schleife bei
n - 1stoppt, warum dieser Cast sicher ist, warum der Puffer 256 Bytes hat. - Absichtliche Merkwürdigkeit. Code, der wie ein Bug aussieht, es aber nicht ist, zieht „Korrekturen" künftiger Leser an, solange er nicht beschriftet ist.
Dieser Kommentar verdient seinen Platz: Die Zeile darunter sieht überflüssig aus und ist es nicht.
Kommentare in Zeichenketten sind keine Kommentare
Ein letztes Detail. Kommentarzeichen haben innerhalb eines Zeichenkettenliterals oder einer Zeichenkonstanten keine besondere Bedeutung:
Beide Zeilen werden vollständig ausgegeben. Der Compiler zerlegt Zeichenketten in Token, bevor er nach Kommentaren sucht, // in Anführungszeichen sind also schlicht zwei Zeichen. (Das %% in der ersten Zeile ist die Art, mit printf ein wörtliches Prozentzeichen auszugeben - ein % allein beginnt eine Formatangabe.)
Häufig gestellte Fragen
Wie schreibt man einen Kommentar in C?
Auf zwei Wegen. // das ist ein Kommentar läuft bis zum Zeilenende. /* das ist ein Kommentar */ kann sich über beliebig viele Zeilen erstrecken und endet beim schließenden */. Beide werden vor der Übersetzung entfernt und beeinflussen das Programm daher nie.
Unterstützt C //-Kommentare?
Ja, seit C99. Sie wurden von C++ übernommen und werden heute überall unterstützt. Nur wirklich uralte C89-Compiler lehnen sie ab, weshalb sehr alter Code für alles /* */ verwendet, sogar für Einzeiler.
Kann man Kommentare in C verschachteln?
Nein. /* außen /* innen */ immer noch außen */ endet beim ersten */ und lässt immer noch außen */ als kaputten Code zurück. Um einen Block abzuschalten, der bereits /* */-Kommentare enthält, nimm stattdessen #if 0 ... #endif, das sich korrekt verschachteln lässt.
Wie kommentiert man in C einen Codeblock aus?
Wickle ihn in /* */, wenn er keine Blockkommentare enthält, oder stelle jeder Zeile // voran. Die robuste Möglichkeit für große Bereiche ist #if 0 davor und #endif danach - der Präprozessor entfernt alles dazwischen, und es übersteht Kommentare und Anführungszeichen darin.