char array[] und char *zeiger



  • MFK schrieb:

    _matze schrieb:

    Das geht so nicht.

    Klar geht das, auch wenn es bedauerlich ist, dass ein kein const char* sein muss. Dass man nicht schreibend darauf zugreifen darf, ist eine andere Sache.

    Ok, ich hab mich unglücklich ausgedrückt. Es geht halt nicht, dass er mit ca3 alles machen kann wie mit ca2...



  • Vellas schrieb:

    Hi!

    Das Array ist konstant und ist eher eine Referenz (Synonym) für den Anfang eines Speicherbereichs (eher weniger ein Zeiger und wenn dann ein nicht veränderbarer).

    Nein, das ist falsch - wenn du dir schon überhaupt nicht sicher bist, stifte vielleicht besser keine Verwirrung.

    Ein Zeiger beinhaltet nur eine Adresse auf einen Speicherbereich. Bei einem Stringliteral funktioniert die Zuweisung und der folgende Zugriff, da Stringliterale im statischen Speicherbereich liegen und somit nicht nur temporär (wie andere Literale) existieren.

    char* Ptr;      // nicht initialisierter Zeiger, zeigt irgendwo hin.
    Ptr = "Hallo";  // Zeiger zeigt auf Stringliteral
    Ptr = "Hi";     // Zeiger zeigt nun auf anderes Stringliteral
    

    Ein (statisches) Array hingegen allokiert Speicher auf dem "Stack" (automatischer Speicherbereich). Es besitzt so viele Elemente, wie du bei der Deklaration angibst und stellt den entsprechenden Speicher selber bereit. Deshalb kann man auch später auf die einzelnen Elemente schreibend zugreifen.

    char Array[6] = "Hallo"; // 5 Zeichen + Nullterminierung = 6 Elemente
    Array[0] = 'J';          // Zuweisung an einzelne Elemente erlaubt
    char* Ptr = Array;       // Zeiger verweist auf den Anfang des Arrays ('J')
    Ptr++;                   // Zeiger wird inkrementiert, zeigt nun auf 'a'
    

    Vielleicht könntest du als Ergänzung den Artikel über Zeiger in diesem Forum lesen, da wird einiges erklärt. Oder zur Forensuche greifen und einen der zig anderen Threads zu diesem Thema anschauen. 😉



  • Ich schau mir grad den Link von Vellas an, kann mir da jemand diese Stückchen übersetzen?

    It is important to realize that a reference like x[3] generates different code depending on whether x is an array or a pointer. Given the declarations above, when the compiler sees the expression a[3], it emits code to start at the location "a," move three past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the location "p," fetch the pointer value there, add three to the pointer, and finally fetch the character pointed to. In the example above, both a[3] and p[3] happen to be the character 'l', but the compiler gets there differently. (See also questions 17.19 and 17.20.)

    MfG
    Stromberg



  • Stromberg schrieb:

    Ich schau mir grad den Link von Vellas an, kann mir da jemand diese Stückchen übersetzen?

    It is important to realize that a reference like x[3] generates different code depending on whether x is an array or a pointer. Given the declarations above, when the compiler sees the expression a[3], it emits code to start at the location "a," move three past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the location "p," fetch the pointer value there, add three to the pointer, and finally fetch the character pointed to. In the example above, both a[3] and p[3] happen to be the character 'l', but the compiler gets there differently. (See also questions 17.19 and 17.20.)

    3 Varianten (eine von mir, eine von google und eine von systran, von dem ich nun wirklich sehr überzeugt bin)

    Es ist wichtig zu wissen, dass eine Referenz, wie x[3] verschiedenen Code generiert, abhängig davon, ob x ein Array, oder ein Pointer ist. Mit der obigen Deklaration, wo der Compiler den Ausdruck a[3] sieht, generiert er Code, wo er an der Position a anfängt, drei Schritte weiter geht und dann den Wert von da holt. Wenn er den Ausdruck p[3] sieht, generiert er Code zum starten an der Position p, holt sich da den Zeigerwert,addiert 3 zum Pointer und holt sich schliesslich das Zeichen, auf das gezeigt wird. Im obigen Beispiel a[3] und p[3] sind schlussendlich 'l' aber der Compiler geht einen anderen Weg. (Siehe auch Fragen 17.19 und 17.20.)

    Es ist wichtig zu erkennen, dass ein Hinweis, wie x [3]-Code generiert verschiedene, je nachdem, ob x ist ein Array oder ein Zeiger. Angesichts der Meldungen über, wenn der Compiler sieht, die den Ausdruck a [3], es gibt Code, um am Standort "A", drei bewegen Vergangenheit und holen den Charakter gibt. Wenn es sich der Ausdruck p [3], es gibt Code, um am Standort "p", holen Sie den Zeiger-Wert gibt, fügen Sie drei auf den Zeiger, und schließlich den Charakter holen auf. Im obigen Beispiel ist sowohl ein [3], p [3] geschehen, werden die Zeichen "l", aber der Compiler wird es anders. (Siehe auch Fragen 17,19 und 17.20.)

    Es ist wichtig, festzustellen, dass ein Hinweis wie x [3] unterschiedlichen Code abhängig von erzeugt, ob x eine Reihe oder ein Zeiger ist. Die Erklärungen oben abgegeben, wenn der Kompilator den Ausdruck a [3] sieht, strahlt es Code aus, um an der Position „a zu beginnen,“ verschieben Sie drei hinter ihr, und holen Sie den Buchstaben dort. Wenn er den Ausdruck p [3] sieht, strahlt er Code aus, um an der Position „p zu beginnen,“ holen Sie den Zeigerwert dort, fügen Sie drei dem Zeiger, hinzu und holen Sie schließlich den Buchstaben, der auf gezeigt wird. Im Beispiel oben, geschehen a [3] und p [3], der Buchstabe „L“, aber der Compiler zu sein kommt dorthin anders als. (Sehen Sie in Frage stellt auch 17.19 und 17.20.)



  • Wenn ich jetzt folgendes mache:

    char *p = "Blabla";
    p = "HansWernerOlm";
    p = "Uschi";
    p = "EAV";
    cout << p << endl;
    

    Was passiert dann mit "Blabla", "HansWernerOlm" und "Uschi"? Werden die automatisch gelöscht? Oder befinden sich die noch irgendwo im Speicher?

    MfG
    Stromberg



  • Ich würde sagen das die sich noch im speicher befinden.



  • Die könnten auch im Nirvana rumschwirren. Du musst dich nicht darum kümmern.. Der Speicher wird automatisch freigegeben. Das einzige, auf was du hier achten musst, ist, dass du mit dem Zeiger den string nicht verändertst, denn das ist undefiniert.

    EDIT:
    C-Strings haben natürlich statischen Speicher und leben somit so lange, wie das Programm.



  • Mh, was nehm ich dann in Zukunft? char x[] oder char *x? Was nehmt ihr? Ich glaub ich nehm leiber char x[], kommt mir irgendwie seriöser vor, und verbraucht ja wohl auch weniger Speicherplatz?

    MfG
    Stromberg



  • Mh, was nehm ich dann in Zukunft?

    std::string



  • Stromberg schrieb:

    Mh, was nehm ich dann in Zukunft? char x[] oder char *x? Was nehmt ihr? Ich glaub ich nehm leiber char x[], kommt mir irgendwie seriöser vor, und verbraucht ja wohl auch weniger Speicherplatz?

    MfG
    Stromberg

    Wenn C-Strings, dann const char* .

    Aber in C++ nimmt man std::string..



  • drakon schrieb:

    Wenn C-Strings, dann const char*

    Nur bei konstanten C-Strings.

    Aber zu char* vs. char[] : Mit dem Zeiger ist man grundsätzlich flexibler, da man die Grösse zur Laufzeit ändern kann. Dafür muss man sich um die Speicherverwaltung und korrekte Freigabe kümmern. Um beide Vorteile zu nutzen, gibt es wie gesagt std::string , wozu ich auch unbedingt rate, sofern man C++ nutzt.


Anmelden zum Antworten