Kommentare, Kommentierung, Verständlichkeit.
-
Ich muss fürs Studium noch eine Abschlussarbeit in C programmierung schreiben. Also Thema will ich eine Bibliothek für Binäre Suchbäume, Binäre Suchbäume die mehrfaches eintragen erlauben und AVL Bäume machen. Dabei achtet der Prof besonders auf gute kommentierung was die benutzung von diesen Bibliotheksfunktionen angeht.
Hab da mal einen versuch gestartet und will auch Doxygen kommentare verwenden. Wollte nur mal fragen ob die Kommentare und die beschreibung der funktionen soweit verständlich ist, was unklar wäre etc. Damit ich merke was ich besser machen könnte.
/** *@file BinaryTree.h *Diese datei enthält die Definition von Funktionen zur nutzung *eines Binärbaumes. Dieser Baum eignet sich zum speichern von jeglichen Datentyp *da in den knoten des Baumes nur Zeiger gespeichert werden beim einfügen von doppelten *Elementen schlägt das einfügen fehl und liefert ein false zurück *@author Heiko Weiß */ /** *Node ist die grundlegende defintion eines Eintrages in einen *Binärbaum */ typedef struct { void * data; /*<der Zeiger auf das Datenelement dieses Knotens*/ node * leftChild; /*<der Zeiger auf den linken Sohn dieses Knotens (NULL) wenn es keinen linken Sohn gibt*/ node * rightChild; /*<der Zeiger auf den rechten Sohn dieses Knotens (NULL) wenn es keinen rechten Sohn gibt*/ } node; /** *binaryTree ist der Starteintrag eines Binärbaumes und enthält das Wurzelelement */ typedef struct { node * root; /*<der Wurzeleintrag und damit startpunkt eines binärbaumes*/ } binaryTree; /** *erzeugt einen Binärbaum und fügt das Wurzelelement in diesen ein setzt dabei den linken *und rechten Sohn der Wurzel auf NULL *@param rootdata ein Zeiger auf das Datenobjekt welches als Wurzel eingefügt werden soll */ binaryTree * newBinaryTree( void * rootdata ); /** *erzeugt aus einen schon existierenden Teilbaum einen neuen Teilbaum indem es den übergebenen node als Wurzel übernimmt *ACHTUNG es wird kein komplett neuer baum erzeugt. Sondern nur der aktuelle node als Wurzel eines neuen Teilbaumes angenommen *dadurch werden weder neue objekte erzeugt noch objekte kopiert *@param root der knoten der zur Wurzel des neuen Teilbaumes werden soll *@return ein zeiger auf diesen Teilbaum binaryTree * makeBinaryTree( node * root ); /** *fügt in einen Binärbaum ein Element an die richtige Position ein und sorgt das die Binärbaumeigenschaft erhalten bleibt. *@param tree Zeiger auf den Baum in den das datenelement eingefügt werden soll *@param data Zeiger auf ein Datenelement welches eingefügt werden soll *@param cmp vergleichsfunktion um die Elemente nach Wertigkeit vergleichen zu können diese muss vom typ int sein *gibt sie einen Wert > 0 zurück ist das linke der beiden übergebenen datenelemente von größerer Wertigkeit *gibt sie einen Wert = 0 zurück sind beide Elemente laut der Definition der Elemente gleich *gibt sie einen Wert < 0 zurück ist das rechte der beidenen übergebenen Datenelementen von größerer Wertigkeit *sie benötigt als parameter zwei void zeiger welche auf die entsprechenden datenenelemente zeigen *@return true wenn das Element erfolgreich angefuegt werden konnte, false wenn solch ein Element schon einmal vorhanden war und das einfügen daher nicht möglich war */ bool insert(binaryTree * tree, void * data, (int(cmp*)(void*,void*)); /** *löscht im einen Binärbaum ein Element sorgt dabei dafür das die Binärbaumeigenschaft erhalten bleibt *@param tree Zeiger auf den Baum in dem das Datenelement gelöscht werden soll *@param ref ein referenz objekt um ein gleichwertiges objekt im Baum zu suchen. *@param cmp verlgeichsfunktion um das referenzobjekt mit den datenobjekten im baum zu vergleichen *gibt sie einen Wert > 0 zurück ist das linke der beiden übergebenen datenelemente von größerer Wertigkeit *gibt sie einen Wert = 0 zurück sind beide Elemente laut der Definition der Elemente gleich *gibt sie einen Wert < 0 zurück ist das rechte der beidenen übergebenen Datenelementen von größerer Wertigkeit *sie benötigt als parameter zwei void zeiger welche auf die entsprechenden datenenelemente zeigen *@return true wenn ein gleichwertiges objekt wie ref gefunden und dieses gelöscht wurde, andernfalls false */ bool delete( binaryTree * tree, void * ref, (int(cmp*)(void*,void*)); /** *sucht in einen Binärbaum ein Element und gibt den knoten in dem enthalten ist in ret zurück *@param tree Zeiger auf den Baum in dem ein Datenelement gesucht werden soll *@param ref das Referenz Objekt zu dem ein gleichwertiges Objekt im Baum gesucht werden soll *@param cmp Vergleichsfunktion um das Referenzobjekt mit den den Datenobjekten im Baum zu vergleichen *gibt sie einen Wert > 0 zurück ist das linke der beiden übergebenen datenelemente von größerer Wertigkeit *gibt sie einen Wert = 0 zurück sind beide Elemente laut der Definition der Elemente gleich *gibt sie einen Wert < 0 zurück ist das rechte der beidenen übergebenen Datenelementen von größerer Wertigkeit *sie benötigt als parameter zwei void zeiger welche auf die entsprechenden datenenelemente zeigen *@param ret ein Zeiger der nach dem ausführen der funktion auf den gefundenen Knoten verweist andernfalls auf NULL gesetzt wird falls der knoten nicht gefunden wurde *@return true wenn ein gleichwertiges objekt wie ref im Baum gefunden wurde, andernfalls false */ bool find( binaryTree * tree, void * ref, (int(cmp*)(void*,void*), node * ret ); /** *ermittelt die Tiefe des binärbaumes oder eines teilbaumes *@param tree der Baum dessen Tiefe ermittelt werden soll *@return die aktuelle Tiefe des Baumes */ int getTreeDepth(binaryTree * tree); /** *ermittelt die Tiefe eines Teilbaumes *@param part der knoten der als Startknoten für diesen teilbaum gilt *@return die aktuelle Tiefe des Teilbaumes */ int getNodeDepth( node * part); /** *gibt den übergebenen Baum in In Order notation auf den Bildschirm aus *@param tree der Baum welcher in In order notation ausgegeben werden soll *@param print Ausgabefunktion welches ein Datenelement auf den Bildschirm ausgeben kann. */ void printInOrder( binaryTree * tree, (void(print*)(void*) ); /** *gibt den übergebenen Baum in Pre Order notation auf den Bildschirm aus *@param tree der Baum welcher in Pre Order notation ausgegeben werden soll *@param print Ausgabefunktion welches ein Datenelement auf den Bildschirm ausgeben kann. */ void printPreOrder( binaryTree * tree, (void(print*)(void*) ); /** *gibt den übergebenen Baum in Post Order notation auf den Bildschirm aus *@param tree der Baum welcher in Post order notation ausgegeben werden soll *@param print Ausgabefunktion welches ein Datenelement auf den Bildschirm ausgeben kann. */ void printInOrder( binaryTree * tree, (void(print*)(void*) );
-
Richtige Groß- und Kleinschreibung sowie kleine Abstände zu den "*" am Beginn wirken oft Wunder.
MfG SideWinder
-
Also mir wären des viel zu viele Kommentare.
z.B.
/**
binaryTree ist der Starteintrag eines Binärbaumes und enthält das Wurzelelement
/
typedef struct
{
node * root; /<der Wurzeleintrag und damit startpunkt eines binärbaumes/
} binaryTree;Der Kommentar sagt zweimal des gleiche - also unnötig. Was mich persönlich auch immer stört sind diese Hinweise auf "zeiger auf ..." - ich meine das das Element nen Zeiger ist seh ich am Sternchen, das brauch ich nicht nochmal

Ich bin da so ein "weniger ist mehr" Typ - eiß halt nur nicht ob sich das mit den Erwartungen deines Profs deckt
weil glaube die sollten wol doch vor persönlichen Geschmack gehen.
-
Ich habe irgendwann mal 'ne ganz gute Definition gelesen:
Kommentare sollen nicht sagen, was der Code macht -> Das sieht man am Code selbst!
Kommentare sollen erklären, warum der Code es so macht, wie er es macht!
-
Das sind keine Kommentare, das ist ne inline Doku.
-
hustbaer schrieb:
Das sind keine Kommentare, das ist ne inline Doku.
Wo wäre dabei das Problem?
-
Reyx schrieb:
Ich habe irgendwann mal 'ne ganz gute Definition gelesen:
Kommentare sollen nicht sagen, was der Code macht -> Das sieht man am Code selbst!
Kommentare sollen erklären, warum der Code es so macht, wie er es macht!im normalfall hat man den Quellcode ja bei bibliotheken nicht mehr vorliegen sondern nur noch den header bzw die doku
-
Fedaykin schrieb:
im normalfall hat man den Quellcode ja bei bibliotheken nicht mehr vorliegen sondern nur noch den header bzw die doku
Richtig, und um die Doku geht's doch hier?
Ich glaube, das wurde von mir falsch verstanden:
Ich meinte nicht das "Kommentieren" von Quellcode, sondern das Mittel "Kommentar" in der Sprache (//, /*, */), welche bei einer Doku auch genutzt wird. Meine Aussage war also viel allgemeiner gemeint
-
Bashar schrieb:
hustbaer schrieb:
Das sind keine Kommentare, das ist ne inline Doku.
Wo wäre dabei das Problem?
Garkein Problem. Bloss weil hier so oft von "Kommentaren" geschrieben wird. Kommentare und Dokumentation sind halt 2 Paar Schuhe.
z.B. braucht man in vielen Fällen garkeine Doku (z.B. wenn jedem der komplette Sourcecode vorliegt, und alles schön verständlich und sauber und mit bezeichnenden Namen geschrieben ist). Wenn aber schon, dann kann es leicht sein dass die Doxygen/Javadoc/... Kommentare die man zum Erstellen dieser Doku schreibt in ihrer Rohform (also wenn man den Source einfach so liest) ziemlich unübersichtlich sind, und der Code dadurch z.T. schlechter lesbar wird als ganz ohne Kommentare.Deswegen sollte man das IMHO unterscheiden. Mehr wollte ich damit nicht sagen.
-
im Quelltext selber kommentiere ich weniger.... naja weil eben durch viele kommentare dort auch die übersichtlichkeit, vor allem bei vielen Einrückungen verloren geht. Aber im Header versuche ich immer so genau wie möglich zu dokumentieren.
Ich hab ja schon quellcode gelesen von einen assemblerprogrammierer der das erste mal mit c gearbeitet hat. Das nenne ich unübersichtlich. Variablendeklarationen in der art p_x_zi = 0; waren dort ganz normal
Die sollte man dann schon kommentieren.
-
bool insert(binaryTree * tree, void * data, (int(cmp*)(void*,void*));
Hat C keinen typedef?
typedef (int(cmp*)(void*,void*) vergleichsFunction; // Oder wie auch immer das in C/C++ war, sorry lange kein C/C++ mehr geschrieben.The use of typedef is also valuable when you want to declare things whose declaration syntax is painfully impenetrable, like ‘array of ten pointers to array of five integers’, which tends to cause panic even amongst the hardy. Hiding it in a typedef means you only have to read it once and can also help to break it up into manageable pieces:
typedef int (*a10ptoa5i[10])[5];
/* or */
typedef int a5i[5];
typedef a5i *atenptoa5i[10];Try it out!

Operatorüberladung gibt es in C wohl auch nicht?
-
DEvent schrieb:
Hat C keinen typedef?
Doch schon, aber wozu?
Operatorüberladung gibt es in C wohl auch nicht?
Nein.
-
Reyx schrieb:
Ich habe irgendwann mal 'ne ganz gute Definition gelesen:
Kommentare sollen nicht sagen, was der Code macht -> Das sieht man am Code selbst!
Kommentare sollen erklären, warum der Code es so macht, wie er es macht!Finde ich sehr gut. Ich musste mal an einem Projekt weiterarbeiten, wo ständig
solche Zeilen standen:i++; // i wird um 1 erhöhtDa hat man die Hände öfters vorm Gesicht, als auf der Tastatur

Jockel
-
Bashar schrieb:
DEvent schrieb:
Hat C keinen typedef?
Doch schon, aber wozu?
für selbstgemachte datentypen, z.b. solche, die auf structs und enums basieren unheimlich praktisch...

-
/** *Node ist die grundlegende defintion eines Eintrages in einen *Binärbaum */ typedef struct { void * data; /*<der Zeiger auf das Datenelement dieses Knotens*/ node * leftChild; /*<der Zeiger auf den linken Sohn dieses Knotens (NULL) wenn es keinen linken Sohn gibt*/ node * rightChild; /*<der Zeiger auf den rechten Sohn dieses Knotens (NULL) wenn es keinen rechten Sohn gibt*/ } node
wäre mir selber sonst zu umständlich und ist hässlicher zu lesen wenn man immer wieder struct und sowas davor schreiben muss
-
Fedaykin schrieb:
/** *Node ist die grundlegende defintion eines Eintrages in einen *Binärbaum */ typedef struct { void * data; /*<der Zeiger auf das Datenelement dieses Knotens*/ node * leftChild; /*<der Zeiger auf den linken Sohn dieses Knotens (NULL) wenn es keinen linken Sohn gibt*/ node * rightChild; /*<der Zeiger auf den rechten Sohn dieses Knotens (NULL) wenn es keinen rechten Sohn gibt*/ } node
wäre mir selber sonst zu umständlich und ist hässlicher zu lesen wenn man immer wieder struct und sowas davor schreiben mussmach's besser so:
typedef struct __node /* den struct namen besser nicht weglassen */ { void *data; struct __node *leftChild; /* typedef kann hier noch nicht verwendet werden */ struct __node *rightChild; /* weils erst später kommt */ } node_t; /* node_t ist hier besser. an dem _t erkennt man selbstdefinierte typen */ ... node_t myNode; /* ist etwas lesbarer aus als: node myNode */ ...
-
ten schrieb:
Bashar schrieb:
DEvent schrieb:
Hat C keinen typedef?
Doch schon, aber wozu?
für selbstgemachte datentypen, z.b. solche, die auf structs und enums basieren unheimlich praktisch...

Das mag sein, ich meinte es aber im bestehenden Kontext und nicht universell.
-
ten schrieb:
typedef struct __node /* den struct namen besser nicht weglassen */ { void *data; struct __node *leftChild; /* typedef kann hier noch nicht verwendet werden */ struct __node *rightChild; /* weils erst später kommt */ } node_t; /* node_t ist hier besser. an dem _t erkennt man selbstdefinierte typen */ ... node_t myNode; /* ist etwas lesbarer aus als: node myNode */ ...Ne ne ne, das ist nicht ANSI/ISO kompatibel! Zwei Unterstriche in Bezeichnern sind dem Compiler vorbehalten!
-
rüdiger schrieb:
Ne ne ne, das ist nicht ANSI/ISO kompatibel! Zwei Unterstriche in Bezeichnern sind dem Compiler vorbehalten!
stimmt, hab' ich auch schon mal gehört.
na, dann nehmen wir einfach was anderes, ein grosses X oder sowas...

-
Oder node_s
