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

    • Unseen schrieb:

      Fröhn schrieb:

      #define?

      const!

      Geht nicht immer...

      Noch einer:

      Quellcode

      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.
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      Bau Dir ein eigenes Modul! EasyFlash
    • sauhund schrieb:

      const int j = 10;
      char str[j];

      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...
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      Bau Dir ein eigenes Modul! EasyFlash
    • Das ist jetzt zwar ne Frage zu BASIC, aber wichtig um das Beispiel zu verstehen:

      Quellcode

      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 ???? ?(
      Teilnahme geplant:
      24.02. - 26.02. BCC#11 Party - Berlin
      15.09. - 17.09. DoReCo#54 Party - Anröchte
    • helmutx schrieb:

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

      Quellcode

      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:

      Quellcode

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

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

      Quellcode

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

      in c auch gerne so abgekürzt wird:

      Quellcode

      1. if (prim) ...

      btw. die klammern um "(PRIM)" sind in basic nicht notwendig ...
    • helmutx schrieb:

      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

      Quellcode

      1. #include <stdio.h>
      2. /******************************************************************************/
      3. /*
      4. * Hauptprogramm
      5. */
      6. int main(void)
      7. {
      8. unsigned int zahl;
      9. /* Von 3 beginnend jede zweite Zahl testen, bis unter 1000 */
      10. for (zahl = 3; zahl < 1000; zahl += 2)
      11. {
      12. if (istPrimzahl(zahl))
      13. {
      14. printf("Primzahl: %u\n", zahl);
      15. }
      16. }
      17. }
      18. /******************************************************************************/
      19. /*
      20. * Ueberpruefe, ob die uebergebene Zahl eine Primzahl ist.
      21. *
      22. * Parameter:
      23. * n Zahl
      24. * Return:
      25. * 0 => Zahl ist keine Primzahl
      26. * sonst => Zahl ist Primzahl
      27. */
      28. unsigned char istPrimzahl(unsigned int n)
      29. {
      30. unsigned int divisor;
      31. unsigned int testEnde = n / 2;
      32. /* Alle potentiellen Teiler bis zur Mitte testen */
      33. for (divisor = 3; divisor < testEnde; divisor += 2)
      34. {
      35. /* Mit Rest 0 teilbar? */
      36. if (n % divisor == 0)
      37. {
      38. /* Ueberprüfung abbrechen, keine Primzahl */
      39. return 0;
      40. }
      41. }
      42. /* Kein Test durchgefallen, ist eine Primzahl */
      43. return 1;
      44. }
      Alles anzeigen


      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. ?(
      Teilnahme geplant:
      24.02. - 26.02. BCC#11 Party - Berlin
      15.09. - 17.09. DoReCo#54 Party - Anröchte
    • (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.

      (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.

      (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?
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      Bau Dir ein eigenes Modul! EasyFlash
    • 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 !
      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...
      Teilnahme geplant:
      24.02. - 26.02. BCC#11 Party - Berlin
      15.09. - 17.09. DoReCo#54 Party - Anröchte
    • 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.
    • Benutzer online 1

      1 Besucher