Hallo, bin gerade dabei ein etwas umfangreicheres Programm zu schreiben. Der µC soll diverse Schalt- und Steuerungsaufgaben übernehmen. Steuerbefehle bzw. Änderungen der Einstellungen sollen dabei über die serielle Schnittstelle mit einem V24 Terminal erfolgen. Mein Problem ist jetzt hier die Struktur des Programms. Hab mir das im Ansatz so vorgestellt: die Daten vom Terminal werden empfangen und in einem String gespeichert. Ist die Eingabe abgeschlossen soll der String ausgewertet werden. Die Struktur der Befehle wollte ich wie unter DOS mach (Befehlsname Parameter). Die einzelnen Befehlsnamen wollte ich in eine verkettet Liste schreiben mit einem dazugehörigem Funktionspointer auf die entsprechende Funktion. Suche dann in der Liste mit stringcompare nach dem entsprechendem Eintrag und springe dann über den Funktionspointer in die entsprechende Funktion. Die Parameter sollen dann einfach als String an die Funktion übergeben werden die diese dann entsprechen auswertet. Was sagt Ihr dazu ?? Fällt Euch da eine bessere Lösung ein ? bzw. wie würdet Ihr das realisieren ? Schon mal vielen Dank für die Hilfe ;) Philipp
Eine Kleinigkeit fällt mir dazu ein: Der Befehlsvorrat ist doch statisch? Dann braucht man keine verketteten Listen, zu denen man zur Laufzeit Einträge hinzufügen kann (und die dann vermutlich mit malloc und free arbeiten). Ein simples Array tut's auch schon. Wenn man sich mit den Befehlen auf ein Zeichen beschränkt, kann dessen ASCII-Wert (ggf. minus einen festen Offset) auch schon der Index auf das Element im Array sein und man spart sich das strcmp.
strcmp hört sich seeeehr langsam an. Lieber eindeutige Mnemonics die als INT intepretiert werden können. Ein INT-Vergleich + Sprung geht rasch.
Je nachdem wieviele Befehle man da eintippt und wie schnell diese ausgeführt werden müssen ist es vielleicht nicht so schlimm, wenn das String-Vergleichen etwas länger dauert. Denke selbst bei vielen Befehlen, dürfte man da noch unter 100ms bleiben - für einen Menschen eine verschmerzbare Wartezeit. Und eindeutige Namen kann man sich schon besser merken, als einzelne Buchstaben. Aber trotzdem sollte ein festes Array an Stelle der verketteten Liste reichen.
Strcmp ist nicht automatisch "seeehr langsam". Erstmal kommt es darauf an, wie oft der Befehlsname gesucht werden muss. Wenn nur alle paar Sekunden ein neuer Befehl gesendet wird, oder die serielle Schnittstelle mur mit 9600 Baud betrieben wird, kann die Suche auch etwas dauern. Zuerst also mal klären, wie oft und in welchen zeitlichen Rahmen die Befehle über die serielle Schnittstelle abgesetzt werden. Zweitens spielt bei der linearen Suche die Größe der zu durchsuchenden Tabelle eine wichtige Rolle. Wieviele verschiedene Befehle sind es? Drittens macht sich die lexikalische Struktur der Befehle bemerkbar. Unterscheiden sich die Suffixe der Befehlswörter, muss strcmp relativ viele Zeichen vergleichen bis er einen Eintrag in der Liste ausschliessen kann. Sind die Prefixe unterschiedlich, ist strcmp mit einer negativen Antwort schnell. Dann ist zu klären, ob bestimmte Befehle sehr häufig vorkommen und andere seltener. Denn hier setzt die erste, trviale Optimierung an. Die Befehle die häufig aufgerufen werden, am Anfang der Liste setzen, damit sie schnell gefunden werden. Die zweite Möglichkeit zu optimieren, ist, die Befehle in der Liste/Tabelle zu sortieren und z.B. eine binäre Suche oder eine heuristische Suche in der Tabelle durchzuführen. Aber mein dritte Vorschlag wäre für diese Aufgabe wohl die effektivste: Da sich die Befehl-Pointer-Paare nicht ändern, also konstant sind, kannst Du sie in einem Baum anordnen, und diesen statischen Baum komprimieren. Als Ergebnis erhältst Du eine Art Zustandsmaschine, die einen Befehl sehr schnell erkennt und findet. Das rentiert sich aber eigentlich nur für große Bäume. Andererseits, gibt es dafür genügend Tools und Algorithmen (so was möchte man nicht von Hand machen), so dass es wiederrum kein so ein großer Aufwand ist. Es kommt eben immer ganz auf die Umgebungsparameter an. Eine unnötige Vergoldung einer Software, bringt praktisch keinen Nutzen, ist jedoch eine Fehlerquelle. Daher: KISS-Prinzip.
"Eine unnötige Vergoldung einer Software, bringt praktisch keinen Nutzen, ist jedoch eine Fehlerquelle." Sehr schön, trifft den Nagel genau auf den Kopf ! Ich habs gesehen, wei sich Leute mit kryptischen 1 oder 2-Zeichen Kürzeln abquälen, sowas mache ich nicht. Namen müssen ausagekräftig sein ! Man kann aber Abkürzungen zulassen, indem zusätzliche Zeichen ignoriert werden, wenn schon die ersten 2 oder 3 Zeichen signifikant sind. Ich mache den Vergleich also immer mit der Länge des Strings in der Tabelle. Auch ignoriere ich Groß- und Kleinschreibung. Ich habs aber bisher nur beim 8051 in C gemacht bzw. in meinem AVR Bootloader in Assembler. Wäre aber mal interessant zu sehen, wie man mit dem WINAVR ein struct im Flash hinkriegt. Peter
Hallo, erst mal vielen Dank für die vielen und schnellen Antworten. Auf die Idee mit dem Array hätte ich eigentlich auch kommen können. @Michael (ein anderer) Die Idee mit dem Baum gefällt mir eigentlich sehr gut. Muss allerdings sagen das ich mich noch nie mit Bäumen beschäftigt habe. Hab da gerade eben mal gegoogled und stelle mit das jetzt so vor: Abhängig vom Anfangsbuchstaben wird der entsprechende Baum ausgewählt und dann folgen die entsprechenden Verzweigungen für jeden weiteren Buchstaben bis zur untersten Ebenen bzw. Befehlende. Oder kann man das noch einfach zusammenfassen ?? Wie sieht das den mit den Tools ? wo bekomme ich die, oder nach welchen Stichworten könnte ich da mal suchen ? mit "binärer Baum" und "c" oder "programmieren" bin ich nicht all zu weit gekommen. Mit freundlichen Grüßen Philipp
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.