Hallo Besucher, der Thread wurde 11k mal aufgerufen und enthält 32 Antworten

letzter Beitrag von sauhund am

C-Kurs, Abend 4 - Lösungen und Fragen

  • #define?


    const!


    Geht nicht immer...


    Code
    1. #define IEC_PIN PINA
    2. #define IEC_DDR DDRA
    3. #define IEC_PORT PORTA
    4. #define IEC_PIN_ATN PA0
    5. #define IEC_PIN_DATA PA1
    6. #define IEC_PIN_CLOCK PA2
    7. #define IEC_PIN_SRQ PA3

  • Geht nicht immer...


    Noch einer:


    Code
    1. const int i = 10;
    2. char str[i];


    bringt auf C90-Compilern schöne Fehlermeldungen:
    const.c(4): Error: Constant integer expression expected
    oder:
    const.c:4: Warnung: ISO-C90 verbietet Feld »str« variabler Größe


    In C99 und C++ geht's aber. Und prinzipiell stimme ich Fröhn auch zu.


  • wer sowas macht dem gehört auch der compiler abgenommen =)


    Wenn Du mal zurückblätterst, wirst Du sehen, dass es um const vs. define ging. Und das war ein Beispiel für eine Stelle, wo const nicht weiterhilft. In Sprachen, wo es keinen Präprozessor gibt, ist das aber die einzige sinnvolle Möglichkeit, das zu tun. Und *wenn* ein Compiler das beherrscht (z.B. Constant Propagation), ist das genauso legitim wie inline functions statt macros.


    Aber ich drifte vom Thread-Thema ab...

  • Das ist jetzt zwar ne Frage zu BASIC, aber wichtig um das Beispiel zu verstehen:


    Code
    1. 120 : IF (PRIM) THEN PRINT "PRIMZAHL: "; ZAHL


    hinter dem IF steht ja keine Bedingung mit =<> so wie ich das kenne. Wann wäre die Bedingung (PRIM) denn erfüllt und wann nicht ???? ?(

  • Das ist jetzt zwar ne Frage zu BASIC, aber wichtig um das Beispiel zu verstehen:


    Code
    1. 120 : IF (PRIM) THEN PRINT "PRIMZAHL: "; ZAHL


    hinter dem IF steht ja keine Bedingung mit =<> so wie ich das kenne. Wann wäre die Bedingung (PRIM) denn erfüllt und wann nicht ???? ?(


    vollständig müsste das so lauten:


    Code
    1. IF (PRIM <> 0) ...


    ich habe es deshalb so geschrieben, damit man den zusammenhang zu c sehen kann, da:


    Code
    1. if (prim !=0) ...


    in c auch gerne so abgekürzt wird:


    Code
    1. if (prim) ...


    btw. die klammern um "(PRIM)" sind in basic nicht notwendig ...

  • Die Abkürzung in BASIC kannte ich bis vorhin noch nicht...


    um es noch genauer zu schereiben:


    also in BASIC gibt es die beiden wahrheitswerte "0"( ~ "false") und "-1" ( ~ "true"), wobei der interpreter IMO alles, was "nicht null" ist, als "true" wertet.


    die IF-abfrage prüft deshalb einfach, ob die bedingung - hier die variable PRIM - "nicht null" ist. ein expliziter vergleich mit "<> 0" wäre dann nur doppelt gemoppelt ; )


    diese erkenntnisse lassen sich auch in c weiternutzen. nur das dort die beiden wahrheitswerte "0" und "1" sind ...

  • Aufgabe 1:


    Funktionen main und istPrimzahl sind vertauscht


    Fehlermeldungen des CC65:
    (14): Warning: Function call without a prototype
    (32): Error: Conflicting type for 'istPrimzahl'
    (34): Error: Undefined symbol: 'n'


    Der erste Fehler ist klar. Der Compiler kennt die Funktion nicht, da sie erst nach main kommt.
    Die anderen Fehlermeldungen sind mir unklar. In Zeile 32 steht doch nur eine { Funktionsklammer. Und n, wird in 34 als undefined bemängelt, obwohl n ja in 31 definiert wird. ?(

  • Zitat

    (14): Warning: Function call without a prototype
    ...
    Der erste Fehler ist klar. Der Compiler kennt die Funktion nicht, da sie erst nach main kommt.


    Richtig. Und jetzt kommt das, was auch die anderen Fehlermeldungen (mehr oder weniger) erklärt: Der Compiler "erfindet" die fehlende Funktion und nimmt an, das diese bestimmte Parameter und einen bestimmten Rückgabetyp hat. Obwohl ich jetzt nicht extra nachgesehen habe, vermute ich, dass er "int istPrimzal(unsigned int)" erfindet. Ich schau jetzt auch nicht nach, weil man sich auf so eine Sauerei sowieso nicht verfässt... Diesen erfundenen Funktionsprototyp merkt sich der Compiler in seiner Symboltabelle.


    Zitat

    (32): Error: Conflicting type for 'istPrimzahl'


    Hier steht zwar nur eine Klammer, aber der Compiler muss bis zu dieser Klammer "lesen", um das Ende des Funktionskopfs zu erkennen. Die Fehlermeldung bezieht sich also wahrscheinlich nicht auf die Klammer, sondern auf das, was davor steht. Solche Situationen sieht man in C (wahrscheinlich auch bei anderen Sprachen) übrigens oft.


    Was stört an dem Funktionskopf? Er stimmt nicht mit der erfundenen Funktion überein. Der Compiler findet "int istPrimzahl(unsigned int)" in seiner Tabelle, jetzt aber "unsigned char istPrimzahl(unsigned int)" im Quelltext. Dieser Unterschied ist ein Fehler.


    Zitat

    (34): Error: Undefined symbol: 'n'


    Das ist vermutlich ein Folgefehler der nicht "akzeptierten" Funktion istPrimzahl. Wenn der Compiler einmal richtig schiefhängt, kommen danach oft eine Unmenge Fehlermeldungen, über die man nicht weiter nachdenken sollte. Die erste Fehlermeldung ist oft die wichtigste.


    Hilft das?

  • Zitat

    Der Compiler "erfindet" die fehlende Funktion und nimmt an, das diese bestimmte Parameter und einen bestimmten Rückgabetyp hat. Obwohl ich jetzt nicht extra nachgesehen habe, vermute ich, dass er "int istPrimzal(unsigned int)" erfindet.
    ...
    Was stört an dem Funktionskopf? Er stimmt nicht mit der erfundenen Funktion überein. Der Compiler findet "int istPrimzahl(unsigned int)" in seiner Tabelle, jetzt aber "unsigned char istPrimzahl(unsigned int)" im Quelltext. Dieser Unterschied ist ein Fehler.


    Danke ! Das ist einleuchtend !

    Zitat

    Hier steht zwar nur eine Klammer, aber der Compiler muss bis zu dieser Klammer "lesen", um das Ende des Funktionskopfs zu erkennen. Die Fehlermeldung bezieht sich also wahrscheinlich nicht auf die Klammer, sondern auf das, was davor steht. Solche Situationen sieht man in C (wahrscheinlich auch bei anderen Sprachen) übrigens oft.


    Das dürfte für die Zukunft auch sehr wichtig zu wissen sein...

  • Zitat

    Obwohl ich jetzt nicht extra nachgesehen habe, vermute ich, dass er "int istPrimzal(unsigned int)" erfindet.


    genau


    generell sollte man bei compilerfehlern immer nur den allerersten ernst nehmen (und erstmal beheben), alles was nach dem ersten kommt sind oft folgefehler und teilweise auch totaler quark.