Warum läuft dieser Code?



  • Stell dir das so vor:

    (*str).operator=(*str);
    

    Vielleicht wird aber auch alles klarer, wenn man das mal vernünftig aufschreibt!

    void eatspaces(char* str)
    {
        int i=0;
        int j=0;
    
        while( (str[i] = str[j++]) != '\0' ) {
        {
            if( str[i] != ' ') i++;
        }
    
        return;
    };
    

    Also: Er kopiert solange von Position j auf Position i und erhöht dann j, bis an Position i irgendwas != Leerzeichen steht. Dann erhöht er i um einen. j eilt i sozusagen voraus. Und das ganze macht er solange, bis er auf i ein \0 aka 0-Terminator geschrieben hat.



  • Decimad schrieb:

    Stell dir das so vor:

    (*str).operator=(*str);
    

    Vielleicht wird aber auch alles klarer, wenn man das mal vernünftig aufschreibt!

    void eatspaces(char* str)
    {
        int i=0;
        int j=0;
    
        while( (str[i] = str[j++]) != '\0' ) {
        {
            if( str[i] != ' ') i++;
        }
        
        return;
    };
    

    Also: Er kopiert solange von Position j auf Position i und erhöht dann j, bis an Position i irgendwas != Leerzeichen steht. Dann erhöht er i um einen. j eilt i sozusagen voraus. Und das ganze macht er solange, bis er auf i ein \0 aka 0-Terminator geschrieben hat.

    Alles klar! Astrein, Deinen neuen Code verstehe ich endlich und das, was da eigentlich passiert. Oh mann, diese c++-Syntax macht mich wirklich noch narrisch.

    Vielen Dank für die Hilfe! Wieder ein bisschen mehr verstanden.



  • Ist der Codeabschnitt aus einer Übung à la "finden Sie 10 Gründe, warum folgender Code nicht gut ist?".
    Wenn nicht, ist das "return;", die Semikolons und die Klammern um i++ wirklich so im Original abgedruckt?



  • Nanyuki schrieb:

    Ist der Codeabschnitt aus einer Übung à la "finden Sie 10 Gründe, warum folgender Code nicht gut ist?".
    Wenn nicht, ist das "return;", die Semikolons und die Klammern um i++ wirklich so im Original abgedruckt?

    Im Original:

    void eatspaces(char* str)
    {
       int i = 0;                             // 'Copy to' index to string
       int j = 0;                             // 'Copy from' index to string
    
       while((*(str + i) = *(str + j++)) != '\0')  // Loop while character
                                                   // copied is not \0
          if(*(str + i) != ' ')                    // Increment i as long as
             i++;                                  // character is not a space
       return;
    }
    

    So oder so ging's mir ja nur um die while-Kondition, die ich bis dato nicht verstanden hatte. Das Buch "Ivor Horton's c++" finde ich persönlich ansonsten ganz gut. Mein M&T-Buch ist dagegen der letzte Schrott.
    Naja, dauert dann halt schon etwas, bis ich mich vernünftig eingearbeitet habe. Aber: den obigen Code finde ich - in meinen Anfängeraugen - auch völlig unverständlich.



  • [quote="isitthatsimple"]

    Ich habe angenommen, dass der ++ -Operator Vorrang hat. Hat das speziell mit Konditionen (bedingungen) zu tun? In div. Tabellen hat ++ immer Vorrang vor +. Oder habe ich da eine generelle Lücke (zwischen den anderen Lücken; habe gerade erst mit c++ angefangen)?

    int i = 0;
    int a = 5;
    
    i = a++;
    
    // jetzt ist i == 5 und a == 6
    
    i = ++a;
    
    // jetzt ist i == 7 und a ebenfalls
    


  • Übrigens kann man bei 'int's den Test auf "!= 0" weglassen, das wird automatisch gemacht, wenn ein bool herauskommen soll (den die while-Schleife ja verlangt):

    void eatspaces(char* str)
    {
        int i=0, j=0;
        while ( str[i] = str[j++] )
            if ( str[i] != ' ' )
                ++i;
    }
    


  • Zumindest mein Compiler würde jedoch bei obigem Code warnen, daß man möglicherweise '=' anstatt "==" verwendet habe. Das Verwenden von "!= 0" dokumentiert die explizite Berücksichtigung dieser Möglichkeit für Compiler sowie für andere Programmierer.



  • Badestrand schrieb:

    Übrigens kann man bei 'int's den Test auf "!= 0" weglassen, das wird automatisch gemacht, wenn ein bool herauskommen soll (den die while-Schleife ja verlangt):

    void eatspaces(char* str)
    {
        int i=0, j=0;
        while ( str[i] = str[j++] )
            if ( str[i] != ' ' )
                ++i;
    }
    

    Wobei in diesem speziellen Fall ja nach dem EOL (\0) werden soll. Nichtsdestotrotz ist die Notation mit eckigen Klammern (str[i]) irgendwie viel einfacher zu verstehen (für mich zumindest).

    Ich hatte mir das, als ich anfing mit einem Projekt (alter C64-Zock) nicht so schwer vorgestellt mit c++. Und OO ist für einen alten 6502er wie mich sowieso nicht sehr einfach. Naja, die Fragen (Bugs) ergeben sich meistens erst zur Laufzeit. Das war früher auch schon so. 😉



  • Badestrand schrieb:

    Übrigens kann man bei 'int's den Test auf "!= 0" weglassen, das wird automatisch gemacht, wenn ein bool herauskommen soll

    Würde ich aber trotzdem nicht machen, und zwar aus dem einfachen Grund, dass man nicht gleich sieht, dass auf 0 geprüft wird. Bei Zeigern gilt das selbe...

    Bei mehreren Zuweisungen der selben Variable in einem Ausdruck (dazu gehören die Operatoren ++ , -- , += , -= , etc.) sollte man vorsichtig sein, da das Resultat möglicherweise nicht definiert ist.



  • Da haschn zonga mit dem for gmacht und musch etzt echt luga dass me alz gaut.



  • Nanyuki schrieb:

    Ist der Codeabschnitt aus einer Übung à la "finden Sie 10 Gründe, warum folgender Code nicht gut ist?".

    Ein ähnlicher Gedanke kam mir auch. Verständlich wird die Anwesenheit dieses Stück Codes wenn man weiß, dass vom gleichem Autor auch ein 'Beginning C: From Novice to Professional (Beginning: from Novice to Professional)' existiert. Und für jede neue Version des VC-Studios schreibt er ein neues Buch 🙄

    Für ein C++-Buch fände ich es angebrachter wenn man an dieser Stelle etwa ..

    #include <algorithm>  // remove
    #include <iostream>
    #include <ostream>
    #include <string>
    
    int main()
    {
        using namespace std;
        string str = "Text mit Space  ";
        str.erase( remove( str.begin(), str.end(), ' ' ), str.end() ); // == eat spaces
        cout << "[" << str << "]" << endl;
        return 0;
    }
    

    .. vorfinden würde.
    Zusammen mit einer schönen Erklärung warum das funktioniert.

    :xmas2: Werner


Anmelden zum Antworten