Funktionen



  • Hallo,
    ich werd hier noch wahnsinnig mit dem c.
    (Habt ihr Frauen schonmal wahnsinnig erlebt??? Lieber nicht!)
    Ich bin jetzt schon seit Tagen an einem Programm dran, wo ihr wahrscheinlich drüber lächelt. Ich muß dazu sagen, ich bin Anfänger ...

    Problem:
    Ich tippe über eine Funktion (Einlesen) einige Buchstaben ein - kein Problem
    Ich lasse in einer Funktion (Bearb) z.B. den Buchstaben e und i zählen-
    Das Zählen ist auch kein Problem (mit case klappt das ganz gut), aber das Gezählte soll nun über eine weitere Funktion (Auslesen) ausgegeben werden.
    Also muss ich es mittels Zeiger/Array zurückgeben. Würde ich wahrscheinlich auch hinbekommen (void bearb(char *wort)). Mein Problem ist, die Gezählten Buchst. in das Array zu bekommen. Also z.B. 4 mal e eingetippt steht in Wort[0],3 mal i in Wort[1]... ist wahrscheinlich auch ganz einfach?! Aber ich hab irgendwie ein Brett vorm Kopf...

    Programm:

    void einl (char*);
    void bearb (char*);
    //void ausg (char*);

    int main()
    {

    char buchst[11];
    einl(buchst);
    bearb(buchst);
    //ausg ....
    return 0;
    }

    void einl(char *eingabe)
    {
    .
    .
    .
    return;
    }

    void bearb (char *an)
    {

    int lauf,e=0,i=0;
    for(lauf=0;an[lauf]!=0;lauf++) // Schleife zum Auslesen des Arrays
    {
    switch (an[lauf])
    {
    case 'e': e++;break;
    case 'i': i++;
    }
    }

    printf("Die Anzahl von e ist: %i\n",e); //Möchte diese Werte jetzt in ein
    printf("Die Anzahl von i ist: %i\n",i); //Array geschrieben haben
    return;

    /* Funktion Ausgabe
    void ausg (char wort)
    {
    printf(".....",);
    return;
    }
    /

    Also, schauts Euch bitte mal an. Vielleicht könnt ihr mir ja helfen.
    Gruß
    Tanja



  • Bitte benutz die Code-Tags, dann sieht dein Code auch gleich freundlicher aus

    wie wärs mit folgendem

    void bearb(const char *an, int *es, int *is) //ein Zähler für die e's und einer
           // für die i's und const char * für die const-correctnes
    {
       int lauf;
       for(lauf=0;an[lauf]!=0;++lauf) // Schleife zum Auslesen des Arrays
       {
         switch (an[lauf])
         {
         case 'e': ++(*es);break; //erhöt die Anzahl der es
         case 'i': ++(*is);       //erhöt die Anzahl der is
         }
       }
    }
    
    void ausg(int es, int is)
    {
      printf("Anzahl der e's: %d\nAnzahl der i's: %d\n",es,is);
    }
    
    int main()
    {
      char buchst[11];
      int es=0,is=0;
      einl(buchst);
      bearb(buchst,&es,&is);
      ausg(es,is);
    }
    

    Oder willst du unbedingt ein Array benutzen? Das bekommst du mit einer kleinen Veränderung hin.

    BTW.
    Benutz am besten immer den ++ Präfix Operator, da der schneller ist als der Postfix ++ Operator

    [ Dieser Beitrag wurde am 11.10.2002 um 12:34 Uhr von kingruedi editiert. ]

    [ Dieser Beitrag wurde am 11.10.2002 um 16:41 Uhr von kingruedi editiert. ]



  • Mmh,sieht logisch aus. Array´s sind dann nicht mehr notwendig.So ähnlich habe ich es glaube schonmal versucht. Ich dachte nur bei void ausg(int es, int is)ist es nicht möglich Werte zurückzugeben (wegem dem void). Wenn das wirklich so klappt,wieviel Werte kann ich denn da zurückgeben??? Gibt es da eine Begrenzung?
    Ich versuchs nachher mal. Muss jetzt erstmal weg. Vielen Dank.
    Tanja



  • hmm ich würd das einfach so machen:

    #include <stdio.h>
    
    typedef struct {int e, i;} eicount;
    
    eicount count(char str[])
    {
       int i;
       eicount ret;
       ret.i=0;
       ret.e=0;
    
       for(i=0; ;++i)
       {
          switch(str[i])
          {
             case 'e':
                ++ret.e;
                break;
    
             case 'i':
                ++ret.i;
                break;
    
             case '\0':
                return ret;
          }
       }
    }
    
    int main()
    {
       char buchst[11];
       eicount ei;
       scanf("%s",buchst);
       ei = count(buchst);
       printf("e: %d i: %d",ei.e, ei.i);
       return 0;
    }
    

    naja is aber nicht so schön und elegant wie kingruedis 🙂 (jaja ich weiss die typ und variablen namen sind bekloppt :D)



  • Original erstellt von kingruedi:
    **
    Benutz am besten immer den ++ Präfix Operator, da der schneller ist als der Postfix ++ Operator.
    **

    hmm da muss man aber das "immer" relativieren weil jenachdem was man will:

    int a=0;
    printf("%d\n",a);
    printf("%d\n",a++);
    printf("%d\n",++a);
    

    und noch zu dem mit dem array (ist vom prinzip her meiner meinung nach die beste lösung):

    #include <stdio.h>
    
    void countall(char str[], int countarray[]) //countarray muss länge 256 haben
    {
       int i;
       for(i=0;str[i]!='\0';++i)
          ++countarray[str[i]];
    }
    
    int main()
    {
       int i;
       char buchst[11];
       int countarray[256];
       for(i=0;i<256;++i)
          countarray[i] = 0;
       scanf("%s",buchst);
       countall(buchst, countarray);
       printf("e: %d i: %d",countarray['e'], countarray['i']);
       return 0;
    }
    

    [ Dieser Beitrag wurde am 11.10.2002 um 12:55 Uhr von japro editiert. ]



  • @japro
    Ich habe ja auch geschrieben "am besten immer", dass heisst ja nicht immer, sondern immer, wenn es möglich ist 🙂 :p

    @Tanja
    du kannst INT_MAX (aus limits.h) Werte zurückgeben



  • Hi,

    Ich dachte nur bei void ausg(int es, int is)ist es nicht möglich Werte zurückzugeben (wegem dem void).

    King. hat keine Werte zurueckgegeben, sondern die Werte nur ausgegeben.

    Desweiteren kann man keine Mengen zurueckgeben, sondern nur einzelne Werte,
    Datenstrukturen (siehe japro) oder Bytefolgen (char *). Wenn du mehrere Werte
    'zurueckgeben' willst, dann deklarierst du im Funktionskopf einen Zeiger auf
    deinen Typ, oder ein Array und speicherst dort deine Werte ab. Wenn die Funktion
    dann abgearbeitet ist, hast du meherere Werte in deinem original Array stehen.

    Hmmm...hab ich das jetzt eigentlich verstaendlich erklaert, oder eher nicht? 😕

    Ich sollte besser kein Lehrer werden. 🙄

    mfg
    v R



  • Original erstellt von virtuell Realisticer:
    **
    Desweiteren kann man keine Mengen zurueckgeben, sondern nur einzelne Werte,
    Datenstrukturen (siehe japro) oder Bytefolgen (char )....*

    das mit dem char* würde ich noch erweitern. denn afaik kann man über pointer so ziemlich alles zurückgeben (sogar funktionen)...



  • Hallo, vielen Dank für eure Antworten.
    Habe es jetzt so gelöst wie "kingruedi" es vorgeschlagen hat. Es ist bestimmt mit Strukturen sinnvoller,aber das hatten wir in der Schule noch nicht. Laut Aufgabenstellung (Lehrer) soll alles mit Funktionen, Pointern, Arrays... geschehen. Ist dadurch bestimmt einiges dämlicher gelöst, aber was macht man (frau) nicht alles für den Lernerfolg. Ich habe jetzt nur noch ein Problem mit der "Wollen Sie wiederholen?"-Schleife. Dann zählt das Programm nicht mehr richtig und schreibt den ersten Satz doppelt hin?! Ihr habt bestimmt eine Idee.
    Danke Tanja

    Hier das Programm:
    #include "stdafx.h"
    #include "stdio.h"

    void einl (char*);
    void bearb (char*,int*,int*);
    void ausg (int,int);

    // Hauptprogramm
    int main(int argc, char* argv[])
    {
    char wieder,buchst[11];
    do
    {
    int es=0,is=0;
    wieder='x';
    einl(buchst); //Aufruf zum Einlesen
    bearb(buchst,&es,&is); //Aufruf zum Zählen+Ausgeben
    ausg(es,is); // Aufruf zum Ausgeben
    printf("\n E N D E\n\n");
    printf("Wollen Sie wiederholen,dann druecken Sie y oder Y \n\n");
    fflush(stdin);
    scanf("%c",&wieder);
    }
    while (wieder=='y'||wieder=='Y');
    return 0;
    }

    // Funktion Einlesen
    void einl(char *eingabe)
    {
    int i=0;
    do
    {
    printf("Bitte geben Sie einen Buchstaben ein: ");
    if (eingabe[i]>='1' && eingabe[i]<='9',break; //Abbruch bei Zahlen
    i++;
    gets(&eingabe[i]); // Buchstabeneingabe
    }
    while (i!=10); //Abbruch nach 10 Buchstaben
    printf("Sie haben 10 Buchstaben oder versehentlich eine Zahl eingegeben \n");
    return;
    }

    //Funktion Zählen und Ausgabe
    void bearb (char *an,int *es,int *is)
    {
    int i;
    for(i=0;an[i]!=0;i++) // Schleife zum Auslesen des Arrays
    {
    switch (an[i]) //Zählen der Buchstaben
    {
    case 'e': ++(*es);break;
    case 'i': ++(*is);
    }
    }
    return ;
    }

    // Funktion Ausgabe
    void ausg (int es,int is)
    {
    printf("\nEs wurde %d mal das e eingegeben!!! \n ",es);
    printf("\nEs wurde %d mal das i eingegeben!!! \n ",is);
    return ;
    }



  • Original erstellt von kingruedi:
    [QB]
    Benutz am besten immer den ++ Präfix Operator, da der schneller ist als der Postfix ++ Operator
    QB]

    Also ich hab das mal in einer for-Schleife mit 100 Trilliarden Durchläufen (ca) getestet, ungefähr so:

    int zahl;
    
    for( int i=0 ; i<100000000000000000 ; ++i )
    {
      zahl++;
    }
    

    Das Ergebnis: Beides gleichschnell bis auf wenige millisekunden ( ungefähr 4 sekunden auf Athlon 1000 )
    Ich glaub der Compiler optimiert das zahl++ wenn es so als Befehl alleine da steht, zumindest der VC++6.0.



  • @0x1

    der Compiler muss das aber nicht optimieren 🙄 aber man kann davon ausgehen, dass der Präfix Operator mindestens genauso schnell ist wie der Postfix Operator, deswegen sollte man den Präfix Oeprator nehmen.

    Bei einigen CPUs (bei RISC Systemen), ist der unterschied wahrscheinlich noch geringer, da dort so viele Register zur Verfügung stehen, dass locker eine temporäre Variable zwischen gespeichert werden kann oder die CPU hat gar einen eigenen Opcode dafür (MIPS)

    Aber da wir ja Platform/Compiler unabhängig programmieren wollen, achten wir natürlich auf solche details.

    Bei C++ ist das übrigens noch unterschiedlicher, da dort ein temporäres Objekt locker die Grenze eines Registers sprengen kann und so Zugriff auf den Arbeitsspeicher und vielleicht sogar swappen nötig ist. Deswegen gleich den Präfix Operator angewöhnen.


Anmelden zum Antworten