Ich habe kaum mehr als C-Kenntnisse für Anfänger und möchte wissen, ob es de facto "Standards" gibt, um eine etwas komplexe Anwendung in C zu strukturieren. Sogar GUI-basierte.
Ich habe immer das OO-Paradigma in Java und PHP verwendet und jetzt, da ich C lernen möchte, befürchte ich, dass ich meine Anwendungen falsch strukturieren könnte. Ich weiß nicht, welche Richtlinien ich befolgen muss, um Modularität, Entkopplung und Trockenheit mit einer prozeduralen Sprache zu erreichen.
Haben Sie Lesungen vorzuschlagen? Ich konnte kein Anwendungsframework für C finden, auch wenn ich keine Frameworks verwende. Ich habe immer gute Ideen gefunden, indem ich deren Code durchsucht habe.
c
project-management
Stephen
quelle
quelle
Antworten:
Der Schlüssel ist die Modularität. Dies ist einfacher zu entwerfen, zu implementieren, zu kompilieren und zu warten.
Wenn Sie Zeit zum Lernen haben, schauen Sie sich an, wie eine Ada-App mit ihren obligatorischen
package
(Modulschnittstelle) undpackage body
(Modulimplementierung) strukturiert ist .Dies dient zur Codierung.
Zur Pflege (denken Sie daran, dass Sie einmal codieren, aber mehrmals pflegen) schlage ich vor, Ihren Code zu dokumentieren. Sauerstoff ist eine gute Wahl für mich. Ich schlage auch vor, eine starke Regressionstestsuite zu erstellen, mit der Sie umgestalten können.
quelle
Es ist ein weit verbreitetes Missverständnis, dass OO-Techniken in C nicht angewendet werden können. Die meisten können - es ist nur so, dass sie etwas unhandlicher sind als in Sprachen mit Syntax für den Job.
Eine der Grundlagen eines robusten Systemdesigns ist die Kapselung einer Implementierung hinter einer Schnittstelle.
FILE*
und die Funktionen , die mit ihm arbeiten (fopen()
,fread()
etc.) ist ein gutes Beispiel dafür , wie Einkapselung kann in C angewandt werden Schnittstellen zu etablieren. (Da C keine Zugriffsspezifizierer hat, können Sie natürlich nicht erzwingen, dass niemand in ein hineinschautstruct FILE
, aber nur ein Masochist würde dies tun.)Bei Bedarf kann in C mithilfe von Tabellen mit Funktionszeigern polymorphes Verhalten festgestellt werden. Ja, die Syntax ist hässlich, aber der Effekt ist der gleiche wie bei virtuellen Funktionen:
struct IAnimal { int (*eat)(int food); int (*sleep)(int secs); }; /* "Subclass"/"implement" IAnimal, relying on C's guaranteed equivalence * of memory layouts */ struct Cat { struct IAnimal _base; int (*meow)(void); }; int cat_eat(int food) { ... } int cat_sleep(int secs) { ... } int cat_meow(void) { ... } /* "Constructor" */ struct Cat* CreateACat(void) { struct Cat* x = (Cat*) malloc(sizeof (struct Cat)); x->_base.eat = cat_eat; x->_base.sleep = cat_sleep; x->meow = cat_meow; } struct IAnimal* pa = CreateACat(); pa->eat(42); /* Calls cat_eat() */ ((struct Cat*) pa)->meow(); /* "Downcast" */
quelle
Alles gute Antworten.
Ich würde nur "Datenstruktur minimieren" hinzufügen. Dies könnte in C sogar einfacher sein, denn wenn C ++ "C mit Klassen" ist, versucht OOP Sie zu ermutigen, jedes Substantiv / Verb in Ihrem Kopf zu nehmen und es in eine Klasse / Methode umzuwandeln. Das kann sehr verschwenderisch sein.
Angenommen, Sie haben zu bestimmten Zeitpunkten eine Reihe von Temperaturmesswerten und möchten diese in Windows als Liniendiagramm anzeigen. Windows verfügt über eine PAINT-Nachricht. Wenn Sie diese erhalten, können Sie das Array mit LineTo-Funktionen durchlaufen und die Daten skalieren, während Sie sie in Pixelkoordinaten konvertieren.
Was ich viel zu oft gesehen habe, ist, dass Menschen, da das Diagramm aus Punkten und Linien besteht, eine Datenstruktur aufbauen, die aus Punktobjekten und Linienobjekten besteht, die jeweils in der Lage sind, sich selbst zu zeichnen, und diese dann nach der Theorie, dass dies der Fall ist, dauerhaft machen ist irgendwie "effizienter", oder dass sie möglicherweise in der Lage sein müssen, über Teile des Diagramms zu fahren und die Daten numerisch anzuzeigen, damit sie Methoden in die Objekte einbauen, um damit umzugehen, und das natürlich. beinhaltet das Erstellen und Löschen von noch mehr Objekten.
Sie erhalten also eine riesige Menge an Code, der ach so lesbar ist und lediglich 90% der Zeit für die Verwaltung von Objekten benötigt.
All dies geschieht im Namen von "guter Programmierpraxis" und "Effizienz".
Zumindest in C wird der einfache, effiziente Weg offensichtlicher und die Versuchung, Pyramiden zu bauen, weniger stark sein.
quelle
Die GNU-Codierungsstandards haben sich über einige Jahrzehnte weiterentwickelt. Es wäre eine gute Idee, sie zu lesen, auch wenn Sie ihnen nicht genau folgen. Wenn Sie über die darin angesprochenen Punkte nachdenken, erhalten Sie eine genauere Grundlage für die Strukturierung Ihres eigenen Codes.
quelle
Wenn Sie wissen, wie Sie Ihren Code in Java oder C ++ strukturieren, können Sie mit C-Code dieselben Prinzipien befolgen. Der einzige Unterschied besteht darin, dass Sie den Compiler nicht an Ihrer Seite haben und alles besonders sorgfältig manuell ausführen müssen.
Da es keine Pakete und Klassen gibt, müssen Sie zunächst Ihre Module sorgfältig entwerfen. Am häufigsten wird für jedes Modul ein separater Quellordner erstellt. Sie müssen sich auf Namenskonventionen verlassen, um Code zwischen verschiedenen Modulen zu unterscheiden. Stellen Sie beispielsweise allen Funktionen den Namen des Moduls voran.
Sie können keine Klassen mit C haben, aber Sie können einfach "Abstrakte Datentypen" implementieren. Sie erstellen für jeden abstrakten Datentyp eine .C- und .H-Datei. Wenn Sie möchten, können Sie zwei Header-Dateien haben, eine öffentliche und eine private. Die Idee ist, dass alle Strukturen, Konstanten und Funktionen, die exportiert werden müssen, in die öffentliche Header-Datei verschoben werden.
Ihre Werkzeuge sind auch sehr wichtig. Ein nützliches Werkzeug für C sind Flusen , mit denen Sie schlechte Gerüche in Ihrem Code finden können. Ein weiteres Tool, das Sie verwenden können, ist Doxygen, mit dem Sie Dokumentation erstellen können .
quelle
Die Kapselung ist immer der Schlüssel zu einer erfolgreichen Entwicklung, unabhängig von der Entwicklungssprache.
Ein Trick, mit dem ich "private" Methoden in C gekapselt habe, besteht darin, ihre Prototypen nicht in die ".h" -Datei aufzunehmen.
quelle
Ich würde Ihnen empfehlen, den Code eines beliebten Open-Source-C-Projekts wie ... hmm ... Linux-Kernel oder Git zu überprüfen. und sehen, wie sie es organisieren.
quelle
Die Zahlenregel für komplexe Anwendungen: Es sollte leicht zu lesen sein.
Um die komplexe Anwendung zu vereinfachen, setze ich Divide and Conquer ein .
quelle
Ich würde vorschlagen, als ersten Schritt ein C / C ++ - Lehrbuch zu lesen. Zum Beispiel ist C Primer Plus eine gute Referenz. Wenn Sie sich die Beispiele ansehen, erhalten Sie eine Vorstellung davon, wie Sie Ihr Java OO einer prozeduraleren Sprache wie C zuordnen können.
quelle