Hallo, mit folgendem Problem schlage ich mich nun schon seit einiger Zeit herum. Ich beginne ein Gcc Projekt schreibe die ersten funktionen, alles prima. Über kurz oder lang wird das ganze aber so unübersichtlich, dass der aufwand um weiter funktionen einzubauen zu groß wird und ich das Projekt unfertig stehen lasse. Die Lösung ist denke das Projekt von vornherein zu planen anstatt einfach drauf los zu programmieren. Nur hab ich keine Ahnung wie ich sowas anfange. Gibt es Tutorials oder Bücher die einen an die Hanmd nehmen? Wie macht ihr das bzw wie habt ihr das gelernt?
Bücher kenne ich leider keine. Hier jedoch einige Tips für C (nicht C++): - möglichst viele Funktionen - Eine Funktion sollte möglichst kurz sein, idealerweise auf einen Bildschirm passen - Benennung von Variablen und Funktionen sind meiner Meinung nach sehr wichtig, man sollte auf den ersten Blick am Namen erkennen können um was es nich handelt. Ungarische Notation (oder sowas ähnliches, je nach Vorliebe) kann auch nicht schaden. - Die Funktionen und Variablen nach logischen Einheiten in einzelnen .c und .h Dateien zusammenfassen - Schnittstellen zwischen den Logischen Einheiten möglichst klein halten (Schnittstelle: Funktionen und Variablen im .h file die von anderen .c Dateien benutzt werden) - hier und da kann Kommentar nicht schaden - Pattern init/run/done verwenden, auch für Sub-Module
RestInPieces schrieb: > Wie macht ihr das bzw wie habt ihr das gelernt? Top-Down-Entwurf: Man skizziert zuerst die grobe Funktion (top-level), wobei die tatsächliche Implementierung einfach mal noch nicht bekannt ist, sondern als black box (Funktion ohne Inhalt) stehen bleibt. Bei einem größeren Projekt kann dann jeder Funktionsblock in einer Datei stehen, bei einem kleineren Projekt genügt oft auch eine einzige Datei. Bottom-Up-Entwurf: Man implementiert zuerst die Funktionalität einzelner Blöcke, und testet diese jeweils separat mit einem eigenen Szenario. Danach führt man alle diese Funktionsblöcke in einem Gesamtprojekt zusammen. Ist etwas schwieriger als top-down, weil man natürlich schon eine grundlegende Idee über die Schnittstellen der Funktionsblöcke nach oben haben muss, bevor man die Schicht darüber tatsächlich implementiert hat.
>möglichst viele Funktionen
Das steht zwar in allen Lehrbüchern zum Thema so geschrieben, aber ich
stehe dieser Pauschalaussage inzwischen nicht mehr ganz unkritisch
gegenüber.
IMO kann die immer weiter verringerte Komplexität und Länge einer
Funktion/Methode die Komplexität des Gesamtsystems deutlich erhöhen. Man
sollte also die Funktionalität mit Verstand auf
Klassen/Methoden/Funktionen aufteilen und nicht mit der
Lehrbuch-Holzhammermethode. Und man braucht auch kein schlechtes Gefühl
zu haben, falls eine Methode mal ein wenig länger als die beschriebene
Bildschirmseite wird. Just my 2 cents.
RestInPieces schrieb: > Die Lösung ist denke das Projekt von vornherein zu planen anstatt > einfach drauf los zu programmieren. Nur hab ich keine Ahnung wie ich > sowas anfange. Gibt es Tutorials oder Bücher die einen an die Hanmd > nehmen? Wie macht ihr das bzw wie habt ihr das gelernt? ich ändere manchmal bestimmte Abschnitte meines Programmes komplett um, nur um dann festzustellen, dass es Quatsch war. Ich arbeite Aktiv an meinem Code, um ihn zu verbessern. Versuche möglichst alle Programme so zu schreiben, dass sie jederzeit abänderbar sind, so wie du sie brauchst. Halte deinen Code so kurz wie möglich. Das erspart dir Tipparbeit, wenn du Änderungen vornimmst (Lieber einmal Gedanken über ein Array oder eine Klassendefinition gemacht, als 5 mal je 100 Konstanten abändern zu müssen) Versuche Parameter getrennt und übersichtlich zu speichern. Lege Variablen dort an, wo sie auch gebraucht werden und initialisiere sie korrekt. Finde einen Kompromiss aus Länge und Sinnhaftigkeit deiner Variablenbezeichnungen, separiere namen mit _ (zB main_control_grid). Bastle abgeschlossene Funktionen, die möglichst nicht auf globale Variablen zurückgreifen. Bastle dir Scripten, die ein schnelles kompilieren und testen deiner Programme ermöglichen. Versuche jede Compilerwarnung oder Fehler auszumerzen und zwar von der Wurzel aus Überlege bevor du tippst. Überlege nachdem du getippt hast, ob es gut war. Scheue nicht davor zurück, Arbeit zu wiederholen, wenn du merkst, den Durchblick verloren zu haben. Wenn du code hast, den du selbst nicht mehr verstehst, hast du verloren und musst von Vorn anfangen.
Versuche, das Rad neu zu erfinden, solange du in der Lernphase bist. Es gehört dazu, mal einen eigenen Pseudozufallsgenerator gebastelt zu haben oder Stringfunktionen selbst zu programmieren. Später, wenn du weisst, wie es geht, kannst du die Standartlibraries benutzen. Lass dir auch mal den Assemblercode von deinen eigenen Programmen anzeigen, um ein Gefühl zu bekommen, was der Compiler eigentlich macht.
- Überlege dir eine Architektur. Sinnvoll ist häufig der Aufbau in Schichten. Trenne z.B. konsequenz hardwareabhängige Teile und hardwareUNabhängige Teile voneinander. Zum Beispiel werden alle Module welche die Peripherie kapseln in einer Schicht zusammengefaßt (Hardwareabstraktionsschicht). - Denke in Modulen. Jedes Modul sollte eine einzige logisch klar definierbare Aufgabe erfüllen. Module sollten so entwickelt sein, dass sich die Schnittstelle bei Änderungen der Hardware nicht verändert. - Abläufe sollten als Zustandsautomaten realisiert werden. Komplexe Ausdrücke mit "if then else" die auf vielen Variablen operieren sind meist ein Indiz für einen nicht-erkannten Zustandsautomat. Trenne die Logik des Zustandsautomaten von der anwendungsspezifischen Logik (kein switch case). - Versuche die Notwendigkeit von Datenstrukturen zu erkennen. Arrays die mit einer Index Variable beschrieben werden deuten häufig darauf hin, dass eigentlich eine Queue benötigt wird (z.B. gepufferter Empfang von Zeichen via UART). Derartige Konstrukte sollten aufgeteilt werden und die Queue in einem separaten Modul allgemeingültig implementiert werden. - Jede Funktion sollte eine einzige logisch klar definierbare Aufgabe erfüllen.
Und halte dich nicht zu sklavisch an Entweder Top-Down oder Bottom-Up In der Praxis ist es ein ständiges Wechseln zwischen den beiden, die Wahrheit liegt hier als mehr in der Mitte. Denn wie soll man beim Top-Down die Verfeinierungen in die Tiefe machen ohne sich zu verzetteln, wenn man nicht weiß, wo die Reise hingehen soll? Man muss also auch beim Top-Down immer wieder mal einen Blick auf den Bottom werfen und auch nachsehen wo es Berührungspunkte zwischen ein paar Schichten Top-Down und ein paar Schichten Bottom-Up geben wird, bzw. geben soll. Bzw. dasselbe in Grün für die umgekehrte Richtung.
RestInPieces schrieb: > Hallo, > > mit folgendem Problem schlage ich mich nun schon seit einiger Zeit > herum. Ich beginne ein Gcc Projekt schreibe die ersten funktionen, > alles prima. Über kurz oder lang wird das ganze aber so unübersichtlich, > dass der aufwand um weiter funktionen einzubauen zu groß wird und ich > das Projekt unfertig stehen lasse. > > Die Lösung ist denke das Projekt von vornherein zu planen anstatt > einfach drauf los zu programmieren. Nur hab ich keine Ahnung wie ich > sowas anfange. Gibt es Tutorials oder Bücher die einen an die Hanmd > nehmen? Wie macht ihr das bzw wie habt ihr das gelernt? Das kann aber auch am Editor liegen. Bei "Eclipse" z.B. hast du eine gute Syntax-Hervorhebung und noch einige andere nette Features. Ein reiner Editor ist sehr mühsam, weil man sich z.B. die Strukturelemnte selbst zusammen suchen muss, Eclipse bietet dir die Strukturelemente einer Struktur an.
Da ist ja schon ne ganze Menge zusammengekommen, danke euch! Falk danke, den Artikel kannte ich noch nicht. Kapselung habe ich probiert, ich kam aber dann an die Stelle wo ich wild durch die Module gesprungen bin um eine aktion durchzuführen :P Ich denke das sinnvollste ist für mich mal bottom up zu probieren und mir das ganze vorher mal aufzuzeichnen. Dann kann ich erstmal einzelne Module für die Hardware schreiben und die damit kapseln. Datenstruckturen ist so ne Sache, meisten hab ich einfach mal ne Variable angelegt und wenn sie nicht mehr "gereicht" hat wurde sie "aufgebohrt". Was dann erstmal zu zig Fehlern geführt hat, weil ich diese natürlich noch an anderen Stellen verwendet hatte. Ich denke da fehlt mir einfach die Weitsicht (oder Übersicht?) Eclipse hatte ich probiert war mir aber zu langsam, ich kanns nicht haben wenn ich auf den PC warten muss :P Arbeite jetzt mit CodeBlocks. Das letzte Projekt ist allerdings auch schon etwas her. Da ich aber demnächst wieder was vorhabe dachte ich frage ich mal hier nach wie mans richtig macht/lernt. Zustandsautomaten: Bisher hatte ich mich auf einfache switch case beschränkt. Werd mir das mal genauer ansehen. - Pattern init/run/done verwenden, auch für Sub-Module Kannst du das etwas genauer ausführen? Meinst du das sequentiell oder funktional? Bisher hatte ich oft eine Init und eine ausführende Funktion. Bzw eine Init eine -Aktion anstoßende- und eine -Daten abholende- Funktion.
RestInPieces schrieb: > Datenstruckturen ist so ne Sache, meisten hab ich einfach mal ne > Variable angelegt und wenn sie nicht mehr "gereicht" hat wurde sie > "aufgebohrt". Was dann erstmal zu zig Fehlern geführt hat, weil ich > diese natürlich noch an anderen Stellen verwendet hatte. Das macht ja nichts. Die findet der Compiler. > Ich denke da fehlt mir einfach die Weitsicht (oder Übersicht?) Genau da liegt der springende Punkt. Man braucht Übung. Das ist wie Bilder malen. Das kann man auch nicht aus einem Handbuch lernen. Aber mit der Zeit kriegt man Übung was Bildkomposition, Farbkompoasition etc. angeht. Genauso auch hier. Mit der Zeit kriegt man es ins Gefühl, wie eine gute Struktur aussehen muss. Gerade in OOP ist es immer in gutes Zeichen, wenn die Einzelteile zusammenpassen und sich 'höhere Funktionen' ganz zwanglos, fast schon wie von alleine, ergeben und alles wie bei den letzten Puzzlestückchen von alleine in Position fällt. Muss man hingegen krampfhaft ständig umcasten, hat die Werte die man benötigt nicht in den Klassen, dann kann man darauf wetten, dass das Design mies ist.
flash gordon schrieb: > Versuche, das Rad neu zu erfinden, solange du in der Lernphase bist. Es > gehört dazu, mal einen eigenen Pseudozufallsgenerator gebastelt zu haben > oder Stringfunktionen selbst zu programmieren. Seh ich auch so, steht der exklusiven Meinung des ein- oder anderen Foren-Urgesteins übrigens entgegen. ("Warum nimmst du nicht MEINEN Scheduler?";)) Es gibt aus meiner Sicht keinen Fachbereich, wo man mehr vom "Learning-by-doing" profitiert als bei der Softwareentwicklung.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.