Unterschied zw. Zeiger und Vektoren



  • Hallo Leute,

    - dachte eigentlich, das ich den Zusammenhang zwischen Zeigern und Feldern(das sind doch Vektoren?) in C verstanden habe. Aber das folgende Beispiel machte diese Vorstellung zu Nichte.

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char **argv)
    {
    
    char src[20], dst[20];
    
    strcpy(src,"Hallo Welt!\0");
    
    while ( *(dst++) = *(src++) );
    
    printf("%s\n", dst);
    
    return 0;
    }
    

    Dieser Code bringt mir beim compilieren mit VC++ folgende Fehlermeldungen:
    Cpp1.cpp(14) : error C2105: '++' needs l-value
    Cpp1.cpp(14) : error C2105: '++' needs l-value

    Was mache ich falsch?
    Sind Namen von Arrays (dst, src) äquivalent zu Zeigern(char *ptr)?

    Danke für alle Antworten schon mal im Voraus?

    Chiao



  • Hallo,

    du hast hier keine Zeiger, sondern Arrays. Hierauf kannst du das '++' nicht
    anwenden. Du brauchst in diesem Falle eine Zaehlvariable:

    int i = 0;
    while( i < 20 ) {
        dst[i] = src[i];
        ++i;
    }
    

    mfg
    v R



  • virtuell Realisticer schrieb:

    Hallo,

    du hast hier keine Zeiger, sondern Arrays. Hierauf kannst du das '++' nicht
    anwenden. Du brauchst in diesem Falle eine Zaehlvariable:

    int i = 0;
    while( i < 20 ) {
        dst[i] = src[i];
        ++i;
    }
    

    Danke für deine Hilfe, deine Lösung kannte ich schon.
    Hatte mir allerdings ne tiefgründigere Antwort gewünscht.
    Vielleicht kommt die ja noch.
    Danke euch allen für eingehende Hilfen.

    Chiau



    1. Bei der Funktion strcpy() brauchst du kein '\0' anzuhängen. Das macht die Funktion selbst.

    Was dein Programm macht:

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char **argv)
    {
    
    char src[20], dst[20]; //Deklaration (speicherreservierung der Felder)
    
    strcpy(src,"Hallo Welt!\0"); // Initialisierung( '\0' weglassen!)
    
    while ( *(dst++) = *(src++) ); // Hier werden Sie Startadressen der Felder um eins erhöht.
    //Das ist gefählich, weil der Pointer um (ich glaube) 4 erhöht wird.
    //Dieser Speicherbereich kann bereits von einem anderen Programm verwendet werden.
    // dann giebt es ein Prob: das ist eine Zuweisung in einer While-Schleife
    // *) weiter gehts unten
    printf("%s\n", dst);
    
    return 0;
    }
    

    😉 Das müsste lauten:
    while(dst++=src++);
    weil du kein 2-dimensionales Feld deklariert hast.
    das ist in einer while scheife aber sinnlos, also:
    dst++=src++;
    die Erhöhung der Adressen ist gefählich und wird nicht benötigt.
    Wenn ich das richtig gesehen habe, sollest du auf "virtuell Realisticer" hören! 😃



  • chille07 schrieb:

    1. Bei der Funktion strcpy() brauchst du kein '\0' anzuhängen. Das macht die Funktion selbst.

    Was dein Programm macht:

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char **argv)
    {
    
    char src[20], dst[20]; //Deklaration (speicherreservierung der Felder)
    
    strcpy(src,"Hallo Welt!\0"); // Initialisierung( '\0' weglassen!)
    
    while ( *(dst++) = *(src++) ); // Hier werden Sie Startadressen der Felder um eins erhöht.
    //Das ist gefählich, weil der Pointer um (ich glaube) 4 erhöht wird.
    //Dieser Speicherbereich kann bereits von einem anderen Programm verwendet werden.
    // dann giebt es ein Prob: das ist eine Zuweisung in einer While-Schleife
    // *) weiter gehts unten
    printf("%s\n", dst);
    
    return 0;
    }
    

    😉 Das müsste lauten:
    while(dst++=src++);
    weil du kein 2-dimensionales Feld deklariert hast.
    das ist in einer while scheife aber sinnlos, also:
    dst++=src++;
    die Erhöhung der Adressen ist gefählich und wird nicht benötigt.
    Wenn ich das richtig gesehen habe, sollest du auf "virtuell Realisticer" hören! 😃

    Das wird schlicht und einfach nicht funktionieren, da wir hier keine Zeiger
    haben!

    mfg
    v R



  • strcpy(src,"Hallo Welt!\0");
    

    \0 ist nicht notwendig, weil "..." bereits ein 0-terminierendes String erzeugt.

    edit: uppss, ich war ein bisschen zu langsam 🙂

    dein Problem ist dass du versuchst explizit die Arrays als Pointer zu behandeln, und das geht so nicht. Arrays und Pointer verhalten sich ähnlich, sind aber nicht dasselbe. So ginge es aber auf jeden Fall (pass auf a und b auf!)

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char **argv)
    {
    
        char* a, *b;
        char src[20], dst[20];
    
        strcpy(src,"Hallo Welt!");
    
        a=src; b=dst;
    
        while ( *(b++) = *(a++) );
    
        printf("%s\n", dst);
    
    return 0;
    }
    


  • Ein Array ist erstmal was völlig anderes als ein Pointer. Aber der Name eines Arrays wird in den meisten Kontexten (im Prinzip alles ausserhalb von sizeof) sofort in einen Pointer auf das erste Element umgewandelt. Auf einen Pointer-Rvalue, und das ist hier entscheidend.



  • Bashar schrieb:

    Aber der Name eines Arrays wird in den meisten Kontexten (im Prinzip alles ausserhalb von sizeof) sofort in einen Pointer auf das erste Element umgewandelt. Auf einen Pointer-Rvalue, und das ist hier entscheidend.

    Schnell mal SG1s Signatur kopiert:

    Except when it is the operand of the sizeof operator or the unary & operator,
    or is a string literal used to initialize an array, an expression that has type
    ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’
    that points to the initial element of the array object and is not an lvalue.

    Nur um ganz korrekt zu sein 🙂



  • 😉
    Danke, die Sache ist jetzt klarer geworden.
    Der Name eines Arrays ist also eine symbolische Anfangsadresse des Beginns eines zusammenhängenden Speicherbereiches, kein wirklicher Pointer, mit dem sich Adressarithmetik durchführen lässt. Um trotzdem mit den Adressen der Felder zu rechnen, muss der Wert des Arraynamens in eine als Pointer explizit definierte Variable kopiert werden. 🤡

    Korrekt soweit?

    Chiao



  • /bin/bash0R schrieb:

    😉
    Danke, die Sache ist jetzt klarer geworden.
    Der Name eines Arrays ist also eine symbolische Anfangsadresse des Beginns eines zusammenhängenden Speicherbereiches, kein wirklicher Pointer, mit dem sich Adressarithmetik durchführen lässt. Um trotzdem mit den Adressen der Felder zu rechnen, muss der Wert des Arraynamens in eine als Pointer explizit definierte Variable kopiert werden. 🤡

    Korrekt soweit?

    Chiao

    Einem Pointer gleichen Typs muss die Startadresse des Speicherbereich, an welchem
    das Array beginnt, zugewiesen werden. Das passiert i.d.R. durch eine simple
    Zuweisung: pointer = array

    mfg
    v R



  • Also ist:

    a=src; 
    b=dst;
    

    Das gleiche wie:

    a = &src[0];
    b = &dst[0];
    

    🙂 🤡 🤡 🤡 😃 🤡 🤡 🤡 🙂



  • flyingCoder schrieb:

    Also ist:

    a=src; 
    b=dst;
    

    Das gleiche wie:

    a = &src[0];
    b = &dst[0];
    

    🙂 🤡 🤡 🤡 😃 🤡 🤡 🤡 🙂

    imho ja, ich mache jedenfalls immer nur so. Ich finde Pointers bequemer als Arrays und deshalb deklariere ich gleichzeitig ein pointer, wenn ich ein Array brauche. Schau mein beispiel auf der anderen Seite, da hab ich auch so gemacht.



  • Oder lies dir nochmal Humes Zitat durch 😉

    mfg
    v R



  • chille07 schrieb:

    1. Bei der Funktion strcpy() brauchst du kein '\0' anzuhängen. Das macht die Funktion selbst.

    Was dein Programm macht:

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char **argv)
    {
    
    char src[20], dst[20]; //Deklaration (speicherreservierung der Felder)
    
    strcpy(src,"Hallo Welt!\0"); // Initialisierung( '\0' weglassen!)
    
    while ( *(dst++) = *(src++) ); // Hier werden Sie Startadressen der Felder um eins erhöht.
    //Das ist gefählich, weil der Pointer um (ich glaube) 4 erhöht wird.
    //Dieser Speicherbereich kann bereits von einem anderen Programm verwendet werden.
    // dann giebt es ein Prob: das ist eine Zuweisung in einer While-Schleife
    // *) weiter gehts unten
    printf("%s\n", dst);
    
    return 0;
    }
    

    😉 Das müsste lauten:
    while(dst++=src++);
    weil du kein 2-dimensionales Feld deklariert hast.
    das ist in einer while scheife aber sinnlos, also:
    dst++=src++;
    die Erhöhung der Adressen ist gefählich und wird nicht benötigt.
    Wenn ich das richtig gesehen habe, sollest du auf "virtuell Realisticer" hören! 😃

    kleine frage, wenn er das \0 schon manuell anghängt, kommt dann von der funktion auch noch eins hinzu? also stehen dann plötzlich 2 im string?



  • Nein, die zweite '\0' wird nicht kopiert, da bereits die erste '\0' als Terminator für den String zählt.



  • chille07 schrieb:

    while ( *(dst++) = *(src++) ); // Hier werden Sie Startadressen der Felder um eins erhöht.
    //Das ist gefählich, weil der Pointer um (ich glaube) 4 erhöht wird.
    //Dieser Speicherbereich kann bereits von einem anderen Programm verwendet werden.
    // dann giebt es ein Prob: das ist eine Zuweisung in einer While-Schleife
    // *) weiter gehts unten
    printf("%s\n", dst);
    

    so viel blödsinn auf einem haufen hab' ich noch hier nie gelesen... 😮



  • Ist ja auch schon über zwei Jahre her 😉



  • Hab hier was für dich, weiss aber nicht ob es das, ist wonach du gesucht hast:

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char **argv)
    {
    
    char src[20], dst[20],*zeiger=&src[0];
    int i=0;
    
    strcpy(src,"Hallo Welt!");
    
    while ((dst[i]=*(zeiger+i))&&(i<20)) i++;
    
    printf("%s\n",dst);
    return 0;
    }
    

    ist jetzt halt auch mit ner zählervariable aber ne andere variante wie die von virtuell Realisticer

    mfg
    ode


Anmelden zum Antworten