Funktion für nur Zahlen und nur Buchstaben



  • Power Off schrieb:

    Frueher dachte ich auch mal so, wie Du, dass es ein hehres Ziel sei, besonders guten und sauberen Code zu schreiben, und dass man das am besten jedem unter die Nase reibt.

    es geht für dich erstmal darum, daß du auch nach dem schreiben kurz mal drüber nachdenkst und gegebenenfalls was verbesserst. nicht um diesen konkreten code besser zu haben. das wäre zu einfach. es hat dann den zweck, daß du das nächste mal es gleich richtig machst. es geht darum, eine rückkopplung zu haben, die einen dazu führt, daß man immer besser wird. daß man auf anhieb das feinste sprachmittel sieht. daß man auf anhieb die schnellste implemetierung der schleife sieht. daß man auf anhieb den fehler erkennt. kurz: es geht darum, dich ständig zu verbessern und nicht auf lorbeeren auszuruhen.
    siehe http://www.c-plusplus.net/forum/viewtopic-var-t-is-121246-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html
    klar kann ich sowas mit nur einer hand schreiben und auch fremden code lesen und den fehler auf anhieb sehen. aber ich bin einfach nicht gut genug, muß immer besser werden. nicht nur im verständnis der verrücktesten metaprogrammierungstricks, auch in den grundlagen. und sag nicht, du hättest keine solchen mikro-lücken.

    Mittlerweile stehe ich auf dem Standpunkt, dass es egal ist, wie jemand programmiert, Hauptsache der Code laeuft.

    komisch. mittlerweile stehe ich niht mehr auf dem standpunkt. wir machen temporal gegenläufige entwicklungen durch.

    Aber ich geb Dir Recht, dass es gut ist, Anfaengern gleich von Anfang an guten Code beizubringen.
    Was guter Code ist, ist aber von Betrachter zu Betrachter unterschiedlich, wie man hier deutlich sehen kann.

    jup. vor 8 jahren hab ich auch manchmal viele funktionen zu einer großen zusammengefaßt, weil die nubes gerne vergessen hatten, was welche funktion macht. naja, das hat aber nix gebracht. die nubes müssen eh lernen, mit vielen funktionen klar zu kommen. und wenn man so leichte sachen wie

    bool isDigit(char ch){
       return '0'<=ch && ch<='9';
    }
    

    reinschmiert, wird auch keiner meckern. wer schon in der lage ist, sich sowas wie isDigit zu merken, hat mehr spaß dran, damit den mini-parser zu lesen. und wer's noch nicht kann, übt das richtige.

    edit: aber da ich auch c++ lehre, muß ich an mich auch andere maßstäbe anlegen, als wenn ich nur c++ benutzen würde. ich muß ja guten gewissens sein, die schüler auf einen weg zu führen, der sie in den folgenden jahren möglichst weit bringt.



  • Hier ist mir schon wieder was in Deinem "Anfaenger-Code" aufgefallen:

    volkard schrieb:

    bool isDigit(char ch){
       return '0'<=ch && ch<='9';
    }
    

    1. Den Datentyp "bool" gibt es erst seit C99. Es gibt immer noch viele Compiler, die keinen bool-Typ haben. Also solltest Du zumindest so etwas wie

    #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
    typedef enum { false, true } bool;  /* fuer alte Compiler */
    #endif
    

    dazuschreiben. Wenn Dein Anfaenger den Code compilieren will und ein Error wegen "bool" kriegt, kann das ganz schoen frusten.
    Deswegen nehme ich in Beispielen immer noch "int" statt "bool". Das muss mir natuerlich niemand nachmachen.

    2. Im Gegensatz zu C++ sind in C Zeichenkonstanten vom Typ "int", und nicht "char".

    Der Anfaenger nimmt bei Deinem Beispiel an, dass '0' und '9' vom Typ 'char' waeren, weil Du das in den Parameter geschrieben hast.
    Dann wundert er sich, wenn Zeichen jenseits der ASCII-Range in switch-Anweisungen nicht mehr funktionieren, die er mittels der C-Standard-Bibliothek eingelesen hat.

    3. Boolescher Ausdruck ohne Kennzeichnung

    Ein Anfaenger koennte Verstaendnisprobleme kriegen, wenn er den Ausdruck "return '0' <= ch && ch <= '9';" liest.
    Daher waere es besser, ueber den Conditional-If-Operator zu zeigen, welche Werte wann zurueckgegeben werden.
    Das liest sich auch viel besser, uebrigens.

    Daher sollte das Codeschnipsel entweder so:

    #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
    typedef enum { false, true } bool;  /* fuer alte Compiler */
    #endif
    bool isDigit( int ch ){
       return '0' <= ch && ch <= '9' ? true : false;
    }
    

    oder so:

    int isDigit( int ch ){
       return '0' <= ch && ch <= '9' ? 1 : 0;
    }
    

    aussehen.



  • mit punkt 3 hast du dich endgültig disqualifiziert



  • jup schrieb:

    mit punkt 3 hast du dich endgültig disqualifiziert

    Ja, ja, die Klugscheisser sind wieder am Werk.
    Ich hoffe, dass Du mal ein besonders fettes Projekt aufs Auge gedrueckt kriegst.
    Nach Volkard's Modell mit 100.000 Funktionen in 1.000.000 Zeilen Source (nach der Regel: nie mehr als 10 Zeilen!).



  • Power Off schrieb:

    Nach Volkard's Modell mit 100.000 Funktionen in 1.000.000 Zeilen Source (nach der Regel: nie mehr als 10 Zeilen!).

    und nie mehr als 10 funktionen pro datei.
    ok, werden zwar 10000 dateien und alte dateisysteme kippen aus den latschen, aber es wird wahnsinnig übersichtlich.



  • volkard schrieb:

    ok, werden zwar 10000 dateien und alte dateisysteme kippen aus den latschen, aber es wird wahnsinnig übersichtlich.

    Ja, na klar, super-uebersichtlich. Mein Freund heisst GREP. Hast Du GREP, bist Du niemals allein. 🙄



  • Ich bin Dein Freund! 🙂



  • bool isDigit( int ch ){
       return '0' <= ch && ch <= '9' ? true : false;
    }
    

    aaaaah...ja wenn der vergleich true ist, gib true zurück. wenn der vergleich false ist, gib false zurück...sehr sinnig. wirklich, das erhöht die übersicht aber gewaltig. 🙄



  • genauso wie

    bool func( void ) {
       return zappidie(137,5) && !zippidie(99,8,2) && ~yippidie(123,4,4,2) && *(zigzag*)yayman(2374,"()!@$%") || alt327(2325,"52323") - 235 >> 35 && b || 7 || c - 345;
    }
    


  • Ich würde das vorschlagen, wenn man es den Anfängern unbedingt klarer machen will.

    int isDigit(int ch)
    {
        if('0' <= ch && ch <= '9')
        {
            return 1;
        }
    
        return 0;
    }
    


  • Stimmt, viel uebersichtlicher! 🙂 👍



  • wie waers mit...?

    int isDigit(int ch)
    {
        if (ch <= '0')
        {
            return 0;
        }
        else
        if (ch >= '9')
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
    

    😉

    PS: mit [code] will ich ausdruecken, dass dies fuer mich kein akzeptables C mehr ist.



  • bool isDigit(int ch) {
      switch(ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
          return true;
        default:
          return false;
      }
    }
    

    Übersichtlicher gehts wohl kaum!



  • bool isDigit(int ch) {
      return (((ch - '0') ? false : true) || ((ch - '1') ? false : true) || ((ch - '2') ? false : true) || ((ch - '3') ? false : true) || ((ch - '4') ? false : true) || ((ch - '5') ? false : true) || ((ch - '6') ? false : true) || ((ch - '7') ? false : true) || ((ch - '8') ? false : true) || ((ch - '9') ? false : true)) ? true : false;
    }
    

    Schön, so gefällts mir bisher am besten! Oder man nimmt isdigit...



  • nice jungs! 😋



  • Power Off schrieb:

    1. Den Datentyp "bool" gibt es erst seit C99. Es gibt immer noch viele Compiler, die keinen bool-Typ haben. Also solltest Du zumindest so etwas wie

    #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
    typedef enum { false, true } bool;  /* fuer alte Compiler */
    #endif
    

    dazuschreiben.

    seit 99 sind 6 jahre her.

    2. Im Gegensatz zu C++ sind in C Zeichenkonstanten vom Typ "int", und nicht "char".

    das char dient vor allem der kommentierung, was da reingeht. genauso das bool beim ausgang.

    3. Boolescher Ausdruck ohne Kennzeichnung
    Ein Anfaenger koennte Verstaendnisprobleme kriegen, wenn er den Ausdruck "return '0' <= ch && ch <= '9';" liest.
    Daher waere es besser, ueber den Conditional-If-Operator zu zeigen, welche Werte wann zurueckgegeben werden.

    mit dem ?: behebst du nir ein problem, das entstanden ist, weil du ist statt bool lieferst.

    int isDigit( int ch ){ 
       return '0' <= ch && ch <= '9' ? 1 : 0; 
    }
    

    das ist zu undeutlich, wenn ich deinen gedanken weiterverfolge. denn immernoch muß der anfänger "'0' <= ch && ch <= '9'" lesen und verstehen. das ist auch bei meinem stil ein problem und war eine vernachlässigung, um dich nicht vollends zu erschrecken.
    der nube muß erstmal erkennen, daß die teile '0'<=ch und ch<='9' bereits bool zurückgeben.
    also

    int isDigit( int ch ){ 
       return ( '0' <= ch ? 1 : 0 ) && ( ch <= '9' ? 1 : 0 ) ;
    }
    

    und für den gesamtausdrück natürlich auch nocht. woher soll man sonst wissen, was && zurückgibt?

    int isDigit( int ch ){ 
       return ( '0' <= ch ? 1 : 0 ) && ( ch <= '9' ? 1 : 0 ) ? 1 : 0;
    }
    

    wobei ich finde, daß man statt ?1:0 dahinter viel besser !! davor schreibt.

    int isDigit( int ch ){ 
       return !!( !!('0' <= ch) && !!(ch <= '9') );
    }
    

    ich kann deine gedanken nachvollziehen, aber ich verstehe nicht, warum du das eigentlich machst.

    ich hingegen würde

    bool isDigit( char ch ){ 
       return '0' <= ch && ch <= '9'; 
    }
    

    verbessern zu

    #define RANGE(min,x,max) ((min)<=(x))&&((x)<=(max))
    
    bool isDigit( char ch ){ 
       return RANGE('0',x,'9');
    }
    


  • volkard schrieb:

    seit 99 sind 6 jahre her.

    Sag das mal jemand, der auf einem alten Betriebssystem mit alten Entwicklungswerkzeugen arbeiten muss. Der freut sich bestimmt!

    volkard schrieb:

    das char dient vor allem der kommentierung, was da reingeht. genauso das bool beim ausgang.

    Dabei vernachlaessigst Du das Problem, dass z.B. getchar() Integers zurueckliefert. D.h. beim Aufruf muss man nach char casten. Toll! 👎

    volkard schrieb:

    #define RANGE(min,x,max) ((min)<=(x))&&((x)<=(max))
    
    bool isDigit( char ch ){ 
       return RANGE('0',x,'9');
    }
    

    Prinzipiell sehr schoen, aber die Parameterreihenfolge ist sehr bizarr (von dem Fehler in isDigit() mal abgesehen -- es muss "ch" statt "x" heissen).

    Besser und logischer waere:

    #define RANGE(x,min,max) ((min)<=(x))&&((x)<=(max))
    
    bool isDigit( int ch ){ 
       return RANGE( ch, '0', '9' );
    }
    


  • volkard schrieb:

    mit dem ?: behebst du nir ein problem, das entstanden ist, weil du ist statt bool lieferst.

    Ich verstehe ungefaehr, durch die Tippfehler, was Du damit sagen willst.

    Leider ein weiterer Irrtum von Dir: Der Ergebnistyp eines ? : Operatorpaars ist gleich dem Ergebnistyp des eingetretenen Falles.

    Also liefert bei "bool" der Ausdruck "x ? true : false" auf jeden Fall ein Ergebnis vom Typ bool.

    Siehe auch Kapitel 6.5.15 im C Standard (ISO 9899:1999).

    Die Regel "int always wins" gilt schon seit dem ersten C Standard (1990) nicht mehr.



  • Power Off schrieb:

    Prinzipiell sehr schoen, aber die Parameterreihenfolge ist sehr bizarr

    ja, das "subjekt" sollte an erster stelle in der parameterliste stehen. aber hier gewinnt die konvetion, denn borland liefert seit urzeiten eine range aus mit dem subjekt in der mitte und jeder kennt und mag sie. gleiche geschichte wie random().



  • Power Off schrieb:

    volkard schrieb:

    mit dem ?: behebst du nir ein problem, das entstanden ist, weil du ist statt bool lieferst.

    Ich verstehe ungefaehr, durch die Tippfehler, was Du damit sagen willst.
    Leider ein weiterer Irrtum von Dir: Der Ergebnistyp eines ? : Operatorpaars ist gleich dem Ergebnistyp des eingetretenen Falles.

    warum sagte das?

    oder so:

    int isDigit( int ch ){ 
       return '0' <= ch && ch <= '9' ? 1 : 0; 
    }
    

    erstmal danke für die ganzen aufklärungen, wie C geht. liege ich noch richtig, daß hier das ?1:0 gar nichts für den compiler bringt? es muß also was sein, was für den menschen da ist. soll das ?1:0 deutlich machen, daß der ausdruck "sozuagen" einen bool liefert, nur im kleidchen eines int? und hierzu sagte ich, daß der bedarf nur entsanden ist, weil du int statt bool lieferst.


Anmelden zum Antworten