- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: For Schleife mit Hindernissen

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076

    For Schleife mit Hindernissen

    Anzeige

    E-Bike
    Bevor ich wieder eine Panikattacke auslöse weil ich das Wort Pascal benutze
    würde ich mich über sinnvolle Äußerungen zu meinem C Problem freuen


    Ich hab grad ein Modülchen von Pascal nach C umgeschrieben für ein LCD Display.
    Nix aufregendes, aber erstaunt war ich doch, als die Texte nicht komplett ausgegeben wurden.
    Immer nur die vordere Hälfte.
    Der Fehler war mir erstmal völlig rätselhaft.
    StrLen liefert das richtige Ergebnis nämlich 4
    es wurden aber nur 2 Zeichen ausgegeben.

    Code:
    /*----------------------------------------------*/
    int StrLen(const char *p)
    { int len = 0;
    
      while (*p++) len++;
      return len;
    }
    /*----------------------------------------------*/
    void LcdWriteChar(const char c)
    { 
        /*... gib Zeichen auf dem LCD aus ...*/
    }
    /*----------------------------------------------*/
    void LcdWriteStr(const char* s)
    { int i;
    
      for (i=0; i<StrLen(s); i++)
      {
        LcdWriteChar(*s++);
      }
    }
    /*----------------------------------------------*/
    int main(void)
    {
      LcdWriteStr("ABCD");
    }
    Dann hab ich die Funktion umgeschrieben und siehe da es funktioniert

    Code:
    void LcdWriteStr(const char* s)
    { int i,len;
    
      len = StrLen(s);
      for (i=0; i<len; i++)
      {
        LcdWriteChar(*s++);
      }
    }
    Als ich mir den Assemblercode ansah, wurde der Fehler klar.
    Er ruft bei jedem Durchlauf, also für jedes Zeichen die Funktion StrLen auf,
    aber jedesmal mit dem incrementierten Pointer
    Wie kommt das denn ? Das ist doch eine Konstante und die StrLen braucht er doch nur
    einmal aufrufen. Da kann sich doch nichts ändern.
    Und es Ist auch egal ob ich da Const benutze oder nicht, der Code bleibt exakt identisch.

    Eigentlich sind das ja schon 2 Fragen. Wozu das Const in der Funktion. Ich hätt gedacht daurch kann der Compiler eventuelle Optimierungen vornehmen.

    Danke Euch im Voraus für Infos

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Hallo

    *s++
    sind eigentlich zwei Befehle!
    *s und s++
    Es wird also das Zeichen auf welches s zeigt geholt und danach wird s um eins erhöht.

    Da s erhöht wird, wird auch der String immer kürzer.
    Sagen wir mal im Speicher liegt folgendes
    'A','B','C','D',0
    Dann zeigt s auf 'A' und der string ist 4 zeichen lang (0 markiert das Ende).
    Nach s++ zeigt s auf 'B', der String ist jetzt nur noch 3 Zeichen lang ...

    const char* s
    bedeutet, dass s auf einen Speicherbereich zeigt, welcher nicht beschrieben werden kann.
    s darf aber verändert werden.

    const char* const s
    dann wäre auch s gegen Veränderung geschützt und der Compiler könnte optimieren. Aber dann geht s++ nicht mehr .....

    Da aber ein String in C mit einem 0 am Ende markiert ist, was auch StrLen() so auswertet, kann man das Ganze viel einfacher schreiben.
    Code:
    /*----------------------------------------------*/
    void LcdWriteStr(const char* s)
    { 
      while (*s)
        {
          LcdWriteChar(*s++);
        }
    }
    /*----------------------------------------------*/
    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Ich fang mal von hinten an:

    Wozu das Const in der Funktion. Ich hätt gedacht daurch kann der Compiler eventuelle Optimierungen vornehmen.
    Das const sagt dem Benutzer der Funktion, daß die Funktion diese Variable nicht ändern wird. Andere String-Funktionen tun das, diese aber nicht. Das hat mit optimieren nichts zu tun. Wenn du selber weißt, was die Funktion tut, kannst du das getrost weglassen.

    Er ruft bei jedem Durchlauf, also für jedes Zeichen die Funktion StrLen auf, aber jedesmal mit dem incrementierten Pointer
    Das muß er auch tun. s wird ja in der Schleife verändert (s++), also muß strlen neu berechnet werden. Und jetzt doch zum Optimizer: wenn s innerhalb der loop konstant wäre, könnte der Optimizer die Berechnung von strlen aus der loop nehmen und außerhalb berechnen. Dein for()

    for (i=0; i<StrLen(s); i++)
    ist einfach falsch, zumindestens beschreibt es nicht, was du meinst.

    Das ganze macht man eigentlich viel einfacher, so in der Richtung:
    Code:
    while(*s) {
          ....
          s++;
    }
    Und Funktionen wie strlen() o.ä. gibts fertig in der libc, die schreibt man nicht selbst

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Moin Leute,

    wie ich sehe wart Ihr schon fleissig und habt mich ein bischen aufgeklärt.

    Ja, Ihr habt beide recht, das kann ich doch ganz anders schreiben und brauche strlen garnicht
    Manchmal hat man echt eine Brett vor den Augen bzw. fehlt mir bei der Stringverarbeitung in C noch die Übung....
    Wird sofort so übernommen und vielen Dank für die Infos.


    Und Funktionen wie strlen() o.ä. gibts fertig in der libc, die schreibt man nicht selbst
    Eigentlich schon, hast Du recht, aber ich benutze generell KEINE Bibliotheken, nichteinmal stdlib, damit
    hat sich das Thema SOUP bei der Softwaredoku erledigt und ich habe den gesamten Source-Code zur Verfügung.

    Na dann einen schönen Tag Euch noch.
    Siro

  5. #5
    shedepe
    Gast
    Ist SOUP nicht eher ein Argument dagegen alles selber zuschreiben. Die C Standard Bibliothek wird vermutlich viel mehr kritischen Anwendungen eingesetzt und getestet als deine eigenen Routinen.

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Hallo Siro,
    Zitat Zitat von Siro Beitrag anzeigen
    Eigentlich schon, hast Du recht, aber ich benutze generell KEINE Bibliotheken, nichteinmal stdlib, damit
    hat sich das Thema SOUP bei der Softwaredoku erledigt und ich habe den gesamten Source-Code zur Verfügung.
    Also woher die Standardbibliotheken kommen weisst du doch eigentlich?

    Zudem hat ein vernünftiger Compilerhersteller auch entsprechende Testsuiten. Die kosten zwar ein Heiden Geld, finden aber praktisch alle Fehler.

    Desweiteren hat C einen grossen Vorteil! Du kannst auch die Standardbibliotheken durch eigene ersetzen und somit die gebräuchlichen Funktionsnamen verwenden., was den Code wesentlich lesbarer macht.
    Zudem ist es kein Problem, den Sourcecode der Standardbibliotheken zu bekommen.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo Peter,
    ehrlich gesagt ich weis nicht wo do Standard Bibliotheken her kommen, ich hab auch noch nie eine benutzt.


    Das ist sicher eine Einstellungssache was man benutz oder auch nicht.

    Deshlab mal eine kurze Übersicht warum ich ungerne Bibliotheken benutze:

    Was ich nicht benutze, brauche ich auch nicht zu dokumentieren oder zu verstehen.
    Wenn MEINE Funktion fehl schlägt bin NUR ich selber dafür verantworlich, siehe meine Lcd Ausgabe die nicht richtig lief.

    Sicherlich sollten die vorgegebenen Funktionen in den Standardbibliotheken funktionell und gut getestet sein,
    das will ich auch nicht annähernd anzweifeln. Wer schreibt die eigentlich ?

    Aber:
    Ich blicke gerne durch. Möchte den Code verstehen.
    Ich habe gerne ALLE Dateien in MEINEM Projektordner.
    Solange ich keine fremden benutze geht das auch einwandfrei.
    Bei der Datensicherung wird lediglich MEIN Order gesichert , da ist ALLES drin was für ein neues Compilat auf irgendeinem Rechner erforderlich ist,
    sofern der Compiler installiert ist.

    Aber sobald ich <include.....> mit benutze geht das Chaos schon los.
    Welche Datei aus welchen Ordner auf welcher Platte benutzt er denn jetzt ?
    Wie bekomme ich die denn mit in meine Datensicherung ?
    Wo muss ich die auf einem anderen System hinpacken, damit ich es wieder kompilieren kann.

    Das ist für mich ein ziemlich undurchschaubares Unterfangen, geschweige denn das ich das irgendwie dokumentieren könnte oder will.
    Ich bin eigentlich ständig auf der Suche nach irgendwelchen Dateien.

    Das Suchprogramm "Everything" ist inzwischen mein täglich Brot geworden, wenn ich das hier erwähnen darf.

    Ich hab z.B. auf meinem Rechner 57 mal stdarg.H drauf.
    Das bewegt sich in Speichergrößen von 1K bis 5K Das soll alles das Gleiche sein ?
    wenn ich da reingucke, bekomme ich eine Augenlähmung so würde ich das mal nennen.
    Oft muss ich mit dem Cursor erstmal zählen wieviele Unterstriche es sind.
    Aha, das waren 4, deshalb meckert er, ich hab nur 3 gemacht.

    Und so ist es für mich wesentlich einfacher und vor allem Übersichtlicher mal eben eine Funktion selbst zu implementieren.
    Einen Dreizeiler brauche ich auch nicht in zig Dateien aufzusplitten die irgendwie auch noch von einander abhängig sind.

    Das ist natürlich meine ganz persönliche Einstellung.

    Allein der Header string.H ist schon für mich unverständlich:
    Zumal ich davon 64 Objekte auf meinem Rechner habe.
    In manchen steht teilweise nur ein Kommetar, sehr sinnig......
    andere sehen aus wie eine Unterstrichsammlungsbibliothek

    Siro

  8. #8
    shedepe
    Gast
    Dann hast du doch bestimmt auch deinen Compiler selber geschrieben, sonst kannst du ja nicht sicher gehen, dass der Compiler wirklich den Binärcode erzeugt den er soll. (Die C - Standardbibliothek wird entweder von deinem System bereitgestellt oder von deinem Compiler hersteller und diese Leute wissen warum sie etwas so implementieren wie sie es machen. Oftmals wird das ganze deswegen so "kompliziert" gestaltet und Portierbarkeit bzw. Flexibilität zu ermöglichen). Wenn du Gründen der Portierbarkeit bzw. dem Compilieren auf einem frischen System sorgen machst, schau dir lieber ein vernüftiges Dependency und Makefilesystem wie Cmake an.

    Versuch mal eine eigene printf Funktion auf einem anderen System zumlaufen zu bekommen ^^

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Abspecken ist meine Devise, nicht nur am Bauch Mehr will ich auch garnicht dazu sagen.
    auf jeden Fall habt Ihr mir hier wieder weitergeholfen und darum ging es und dafür danke ich Euch.
    Siro

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Hallo Siro,
    Zitat Zitat von Siro Beitrag anzeigen
    Was ich nicht benutze, brauche ich auch nicht zu dokumentieren oder zu verstehen.
    Wenn MEINE Funktion fehl schlägt bin NUR ich selber dafür verantworlich, siehe meine Lcd Ausgabe die nicht richtig lief.
    Also die Standard-Bibliotheken sind zur genüge in Handbüchern dokumentiert.

    Zitat Zitat von Siro Beitrag anzeigen
    Sicherlich sollten die vorgegebenen Funktionen in den Standardbibliotheken funktionell und gut getestet sein,
    das will ich auch nicht annähernd anzweifeln. Wer schreibt die eigentlich ?
    Das macht der Compilerhersteller, dadurch nutzen die auch Compilerspezifische Optimierungen.

    Zitat Zitat von Siro Beitrag anzeigen
    Oft muss ich mit dem Cursor erstmal zählen wieviele Unterstriche es sind.
    Aha, das waren 4, deshalb meckert er, ich hab nur 3 gemacht.
    Da machst du grundsätzlich etwas falsch!
    Alle normalen Bibliotheks-Funktionen haben keinen Unterstrich am Anfang.
    Alte Bezeichner und nicht dem ANSI-Standard entsprechende Bezeichner (Erweiterungen durch den Compilerthersteller) beginnen mit einem Unterstrich.
    Zwei Unterstriche am Anfang sind reserviert für Compilerinterne Dinge.
    In deinem Code sollten also gar keine Bezeichner mit mehr als einem Unterstrich am Anfang auftauchen!

    Zitat Zitat von Siro Beitrag anzeigen
    Allein der Header string.H ist schon für mich unverständlich:
    Zumal ich davon 64 Objekte auf meinem Rechner habe.
    In manchen steht teilweise nur ein Kommetar, sehr sinnig......
    andere sehen aus wie eine Unterstrichsammlungsbibliothek
    Ich weiss nicht welche(n) Compiler du installiert hast.

    Die meisten Compiler unterstützen mehrere Speichermodelle. Viele CUs unterstützen near und far Zeiger, je nach Anwendung kann man Speicherplatz sparen, wenn ein Zeiger nur 16-Bit belegt, anstatt 32 oder 64 Bit.
    Da braucht es dann auch unterschiedliche Header, bzw. im Header müssen die aktuellen Compilereinstellungen abgefragt werden.
    Für den Anfänger sieht das dann recht wirr aus, vermeidet aber viele Fehler.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. [ERLEDIGT] Programmstart mit Hindernissen
    Von basteluwe im Forum Robby RP6
    Antworten: 14
    Letzter Beitrag: 09.02.2016, 19:16
  2. Ortung in einem Raum mit Hindernissen
    Von Checker108 im Forum Software, Algorithmen und KI
    Antworten: 14
    Letzter Beitrag: 14.03.2010, 14:59
  3. robotorprojekt_linie folgen/hindernissen ausweichen
    Von julian_f im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 4
    Letzter Beitrag: 27.03.2009, 21:30
  4. Hindernissen Ausweichen -> Fehlfunktion
    Von JeyBee im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 2
    Letzter Beitrag: 15.11.2008, 14:51
  5. LED-Darstellungs Idee mit ein paar Hindernissen
    Von Strahleman im Forum Elektronik
    Antworten: 51
    Letzter Beitrag: 24.01.2007, 16:20

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen