Anzeige:
Ergebnis 1 bis 7 von 7

Thema: Problem mit kleinem C Programm

  1. #1
    Moderator
    Registriert seit
    09.05.2001
    Ort
    Essen
    Beiträge
    26

    Problem mit kleinem C Programm

    In der Uni hat gerade die Vorlesung für die Programmiersprache C begonnen. Dabei taucht ein kleines Beispiel auf, das Wörter, Zeilen und Zeichen einer .c Datei zählen soll. Habe das Programm auch schön ordentlich geschrieben, analysiert und (wie ich meine) verstanden.

    #include <stdio.h>

    main()
    {

    int temp,zeichen,woerter,zeilen,status;
    cnum status {OUT, IN};
    FILE *fd;

    fd = fopen ("countchar3.c","r");
    status = OUT;
    zeichen = woerter = zeilen = 0;

    while ((temp=getc(fd))!=EOF)
    {
    ++zeichen;

    if (temp == '\n')
    {
    ++zeilen;
    }

    if (temp == ' ' || temp == '\n' || temp == '\t')
    {
    status = OUT;
    }
    else if (status == OUT)
    {
    status = IN;
    ++woerter;
    }
    }

    printf ("Zeichen=%d\tWörter=%d\tZeilen=%d\t",zeichen,woer ter,zeilen);

    }
    gcc -o countchar3 countchar3.c

    countchar3.c: In function `main':
    countchar3.c:7: `cnum' undeclared (first use in this function)
    countchar3.c:7: (Each undeclared identifier is reported only once
    countchar3.c:7: for each function it appears in.)
    countchar3.c:7: parse error before "status"
    countchar3.c:11: `OUT' undeclared (first use in this function)
    countchar3.c:29: `IN' undeclared (first use in this function)

    Er kennt den Typ cnum nicht. Offenbar soll das ein Typ sein, der entweder IN oder OUT ist. Aber das nimmt der Compiler so nicht an.

    Zudem frage ich mich warum der status vorher auch schon als Integer deklariert wird.

  2. #2
    Registrierter Benutzer
    Registriert seit
    24.06.2003
    Beiträge
    486
    enum nicht cnum .

    Weiterhin ist implicit int deprecated,also deklarriere main als int main.

  3. #3
    Moderator
    Registriert seit
    09.05.2001
    Ort
    Essen
    Beiträge
    26
    Danke. Da war die Schrift mal wieder so klein und unleserlich, das ich da doch glatt ein c entziffert habe.

    ./countchar3
    Zeichen=506 Wörter=73 Zeilen=38


    Zwei Fragen hätte ich nun:

    1. Wiso wird temp erst als int und dann als enum deklariert ? Könnte das ein Fehler sein, oder hat das einen bestimmten Grund ?

    2. Ok. Also "int main" und am Ende dann "return 0". Kannst du mir erklären, warum man das so machen muss bzw. soll ?

  4. #4
    Registrierter Benutzer
    Registriert seit
    24.06.2003
    Beiträge
    486
    Original geschrieben von hunter

    1. Wiso wird temp erst als int und dann als enum deklariert ? Könnte das ein Fehler sein, oder hat das einen bestimmten Grund ?
    Also das ist vom Autor sehr ungeschickt gemacht,gerade weil Anfänger das auch verstehen sollen.
    Gut,status wurde als int deklarriert und das bleibt status auch bis zum Ende.
    Mit enum status {OUT,IN}; wird ein neuer Datentyp deklarriert der den Namen enum status hat (das ist hier entscheidend der Name ist enum status).
    Dieser kann zwei Werte annehmen,OUT == 0,und IN == 1.
    In der Zeile status = OUT; wird also der int Variablen status eine 0 zugewiesen.

    Besser wäre ein namenloser Enum gewesen
    Code:
    enum {OUT,IN};
    Um das noch etwas zu verkomplizieren
    enum status ist ein Datentyp,jetzt kann man davon eine Instanz erzeugen,nennen wir sie status
    Code:
    enum status {OUT,IN};
    enum status status = OUT;
    Jetzt sieht man schön,das enum status und status zwei völlig verschiedene Namen sind.
    Das wäre auch die logische Variante gewesen status gleich als enum status zu deklarrieren und nicht als int.

    2. Ok. Also "int main" und am Ende dann "return 0". Kannst du mir erklären, warum man das so machen muss bzw. soll ?
    Der Standard schreibt es so vor.
    Implementierungen können auch andere Signaturen für main anbieten,aber nur int main(),und int main(int,char**) sind nötig.

  5. #5
    Moderator
    Registriert seit
    09.05.2001
    Ort
    Essen
    Beiträge
    26
    Hmm. Ich bin in der Tat nun ein kleines bischen verwirrt.

    Also status soll ja wirklich nur zwei Zustände annehmen um eben festzuhalten ob man sich gerade bei einem Wort befindet oder zwischen zwei Wörtern.

    int status weg zu lassen und nur enum status zu schreiben gibt eine Fehlermeldung. In sofern gibt das schon Sinn, "int status; enum status {OUT, IN};" zu schreiben um festzuhalten, das man sich auf die Variable status bezieht. Aber es klappt auch wenn man nur "enum {OUT, IN};" schreibt.

    Also könnte man nun OUT und IN jeder Variable zuweisen, oder ? Aber wiso dann eine Instanz status erzeugen ?


    Also "int main" braucht man später mal, weil man diese main Anweisung dann auch von anderen Anweisungen aus aufrufen könnte, was man zur Zeit nicht braucht, es didaktisch aber sinnvoll ist ?


    Hier noch ein kleines Programm was nicht will:

    /* Berechnet 2^i und (-3)^i wobei i von 0 bis 9 läuft */

    #include <stdio.h>

    int funktion (int m, int n);

    int main()
    {

    int i;

    for (i=0; i<10; ++i)
    {
    printf ("i=%d\t2^i=%d\t(-3)^i=%d\n", i, funktion (2,i), funktion (-3,i));
    }

    return 0;

    }


    int funktion (int basis, int n)
    {

    int p=0, i;

    for (i=1; i<=n; ++i)
    {
    p = p * basis;
    }

    return p;

    }
    Da kommen nur Nullen raus. Siehst du vieleicht was hier falsch ist, ich komm zur Zeit irgendwie nicht dahinter ?

  6. #6
    Registrierter Benutzer
    Registriert seit
    24.06.2003
    Beiträge
    486
    Original geschrieben von hunter

    Also status soll ja wirklich nur zwei Zustände annehmen
    Ja,darum wäre es besser gewesen,gleich status als enum status zu deklarrieren und nicht als int.
    int status weg zu lassen und nur enum status zu schreiben gibt eine Fehlermeldung.
    Wenn du int status rausnimmst,mußt du dafür das rein packen.
    Code:
    enum status {OUT,IN};//Der Datentyp
    enum status status = OUT;//Dein status Variable.
    Also könnte man nun OUT und IN jeder Variable zuweisen, oder ? Aber wiso dann eine Instanz status erzeugen ?
    IN und OUT sind einfach zwei int Konstanten.
    Man hätte sie auch einfach als Makros definieren können.
    Code:
    #define OUT 0
    #define IN 1
    die enum Variante ist aber besser.
    So und irgendeine Variable soll ja zur Laufzeit wechselweise entweder OUT oder IN enthalten.
    Also mußt du eine Variable haben,die int Werte speichern kann,daher wurde int status deklarriert.
    Aber man kann (wie bereits gesagt) auch ein Variable vom Typ enum status deklarrieren (anstatt int status).Da sieht jeder gleich,"Aha,dieses Vairable soll nur die Werte OUT und IN haben können".
    Also "int main" braucht man später mal, weil man diese main Anweisung dann auch von anderen Anweisungen aus aufrufen könnte, was man zur Zeit nicht braucht, es didaktisch aber sinnvoll ist ?
    Nein,es ist egal,ob man das Programm von einem anderen Programm ausführt,und dann den Rückgabewert braucht.
    Am Ende deines Programms steht (wird vom Compiler generiert):
    exit(main());
    also der Returnwert von main wird an exit übergeben.

    Da kommen nur Nullen raus. Siehst du vieleicht was hier falsch ist, ich komm zur Zeit irgendwie nicht dahinter ?
    Du setzt in funktion p auf 0,und multiplizierst immer irgendwas anderes dran,0 mal irgendwas bleibt aber 0.

  7. #7
    Moderator
    Registriert seit
    09.05.2001
    Ort
    Essen
    Beiträge
    26
    Erst mal danke für deine Erklärungen. So langsam steig ich da durch. Mein Problem ist halt, das ich das mehr oder weniger allein aus dem Script lernen muss, da ich die beiden ersten Vorlesungen nicht besuchen konnte.

    Zum Programm. Stimmt. p wird mit 1 initialisiert und nicht mit 0. Dann funktioniert es.

Lesezeichen

Berechtigungen

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