Hilfe bei Pointern und Dynamischen Speicher



  • buu2188 schrieb:

    Also sind character Pointer Zeiger auf die jeweiligen Blöcke eines Arrays?

    im prinzip schon.
    du schreibst also z.b. "char *a = new char[25];" und dann kannst du mit *a das erste element abrufen, mit *(a+1) das zweite, *(a+2) das dritte usw.

    was dein anderes problem angeht:
    1. wirfst du dein array weg.
    2. überschreibst du in dem programm dein array mit 0.
    3. lautet die abbruchbedingung idr. *a==0.

    &pTr: adresse der zeigervariablen
    pTr: in der zeigervariablen gespeicherte adresse
    *pTr: an in der zeigervariablen gespeicherten adresse gespeicherter wert



  • buu2188 schrieb:

    Also sind character Pointer Zeiger auf die jeweiligen Blöcke eines Arrays?

    Jein; sie zeigen, genau genommen, auf ein einzelnes Objekt vom Typ "char". Wie viele danach noch kommen mögen, ist in einem char* nicht enthalten.

    buu2188 schrieb:

    Deshalb muss ich einen neuen Character definieren und um +1 erhöhen für den zweiten Buchstaben des Arrys? 🙂

    Nein, es gibt verschiedene Möglichkeiten um auf nachfolgende chars zuzugreifen. Das wurde hier schon erklärt.



  • buu2188 schrieb:

    Habe mal versucht ein Beispiel meines Prof's umzuschreiben

    Als Lehrbeispiel ist das vielleicht geeignet, um Umgang mit Pointern zu lernen, aber in der Praxis wirst du diesen Code eher selten bis hoffentlich gar nicht sehen. Grund: keine Fehlerbehandlung, was passiert bei negativen Eingaben und außerdem wäre hier in C++ wohl ein std::vector<double> das Mittel der Wahl.

    buu2188 schrieb:

    Ich habe mal das hier zusammen geschnipselt :

    int N;
    	char* x = "ABC";
    

    Das ist schon falsch, dir fehlt const: du solltest eine Ausgabe wie "ISO C++11 does not allow conversion from string literal to 'char *'" bekommen. Wenn nicht, dann stell die Warnungen/Fehler richtig ein. Dann funktioniert natürlich auch die folgende Zuweisung auf x[i] nicht mehr. Nimm doch eine neue Variable!

    buu2188 schrieb:

    for (int i = 0 ; i < N ; i++)
    		x[i]=0;
    
    	cout << *x << endl;
    

    Bekomme das aber nur eine Adresse heraus 😕 Warum?

    Das wäre merkwürdig. Da sollte keine Adresse rauskommen, sondern nur das Zeichen mit dem Wert 0, das du vermutlich nicht am Bildschirm siehst, sowie der Zeilenumbruch.

    Ich glaube, du solltest dich dringend mit ein paar Kommilitonen zusammensetzen und die Grundlagen (was ist ein Zeiger etc.) noch einmal angucken. Das geht vermutlich besser/schneller als hier. Das soll dich aber nicht davon abhalten, hier gern konkrete Dinge nachzufragen.



  • Ein Pointer ist eine Variable, die eine Adresse speichert.

    Um an den Wert zu kommen, der an dieser Adresse liegt, muss man den Pointer dereferenzieren. Dafür ist der * Operator oder auch die [] da.

    Eine Besonderheit bei Pointern ist, das bei Addition mit einem integralen Typ die Größe des Elements (auf das der Zeiger verweist) berücksichtigt wird.

    x[i] ist identisch mit *(x+i)

    Der Pointer enthält keine weitere Information darüber, wie groß der Speicherbereich ist, auf den er zeigt.

    cout gibt bei einem Pointer dessen Inhalt (Adresse) aus, es sei denn, es ist ein char-Pointer.
    Bei char* wird das wie ein C-String behandelt.

    Das *x ist bei dir aber vom Typ char und ist bei dir 0.

    char* x = "ABC";  // 4 Zeichen 'A', 'B', 'C', 0
    
        for (int i = 0 ; x[i] != 0 ; i++)  // als Array
          cout << x[i] << endl;            
    
        for (char *p = x; *p; p++)         // mit Pointer  *p steht für *p != '\0'
          cout << *p << endl;
    

    Der Zeiger p wird hier gebraucht, da x ja weiterhin auf den Anfang der Zeichenfolge zeigen soll.



  • Vielen vielen Dank für eure Hilfe 🙂



  • DirkB schrieb:

    x[i] ist identisch mit *(x+i)

    Rätselfrage: ist x oder i der Pointer?



  • Andromeda schrieb:

    DirkB schrieb:

    x[i] ist identisch mit *(x+i)

    Rätselfrage: ist x oder i der Pointer?

    Ja



  • Andromeda schrieb:

    Rätselfrage: ist x oder i der Pointer?

    i zeigt halt auf was anderes 🙄



  • HansKlaus schrieb:

    Andromeda schrieb:

    Rätselfrage: ist x oder i der Pointer?

    i zeigt halt auf was anderes 🙄

    Auf was denn?



  • Andromeda schrieb:

    DirkB schrieb:

    x[i] ist identisch mit *(x+i)

    Rätselfrage: ist x oder i der Pointer?

    Solange da ein Pointer und ein integraler Typ ist, ist es egal.
    Dies ergibt sich aus dem Kommutativgesetz, dass für die Addition gültig ist.



  • Andromeda schrieb:

    HansKlaus schrieb:

    Andromeda schrieb:

    Rätselfrage: ist x oder i der Pointer?

    i zeigt halt auf was anderes 🙄

    Auf was denn?

    kommt halt darauf an, welchen wert i hat.



  • der witz ist, dass [] für eingebaute typen auch kommutativ ist.

    void foo (int* array, int i){
       assert(array[i] == i[array]);
    }
    


  • dove schrieb:

    der witz ist, dass [] für eingebaute typen auch kommutativ ist.

    Das ist kein Witz, sondern die logisch Folgerung daraus.



  • naja ob ich den wert von i als basisadresse nehme und dann den wert von array hinzuaddiere, oder umgekehrt ist ja auch egal.



  • DirkB schrieb:

    Andromeda schrieb:

    DirkB schrieb:

    x[i] ist identisch mit *(x+i)

    Rätselfrage: ist x oder i der Pointer?

    Solange da ein Pointer und ein integraler Typ ist, ist es egal.

    So ist es. 🙂

    DirkB schrieb:

    Dies ergibt sich aus dem Kommutativgesetz, dass für die Addition gültig ist.

    Das ergibt sich eher aus der C-Syntax, die sowas erlaubt.



  • DirkB schrieb:

    dove schrieb:

    der witz ist, dass [] für eingebaute typen auch kommutativ ist.

    Das ist kein Witz, sondern die logisch Folgerung daraus.

    logisch ist das nicht, nur wenn man wirklich die definition x[y] == *(x+y) ernst nimmt. die ist aber auch nicht absolut/in stein gemeißelt...

    struct Foo {
        int i;
        int const& operator*() const { return i; }
    
    };
    
    Foo operator+(Foo a, int i) {
     return a;
    }
    
    Foo operator+(int i, Foo a) {
     return a;
    }
    
    int main()
    {
        Foo f { 42 };
    
        *f; //ok
        *(f+0); //ok
        *(0+f); //ok
        f[0]; //ooops
    }
    


  • dove schrieb:

    DirkB schrieb:

    dove schrieb:

    der witz ist, dass [] für eingebaute typen auch kommutativ ist.

    Das ist kein Witz, sondern die logisch Folgerung daraus.

    logisch ist das nicht, nur wenn man wirklich die definition x[y] == *(x+y) ernst nimmt. die ist aber auch nicht absolut/in stein gemeißelt...

    struct Foo {
        int i;
        int const& operator*() const { return i; }
       
    };
    
     
    Foo operator+(Foo a, int i) {
     return a;
    }
        
    Foo operator+(int i, Foo a) {
     return a;
    }
    
    int main()
    {
        Foo f { 42 };
        
        *f; //ok
        *(f+0); //ok
        *(0+f); //ok
        f[0]; //ooops
    }
    

    Wenn man einfach Operatoren umbiegt, kann man natürlich jede Seltsamkeit hinfrickeln. Daher bevorzuge ich C. Bei einem C++-Codeschnipsel weißt du nie, was wirklich passiert.



  • wenn man den []-operator auch noch überlädt, klappts auch.



  • Andromeda schrieb:

    Wenn man einfach Operatoren umbiegt, kann man natürlich jede Seltsamkeit hinfrickeln. Daher bevorzuge ich C. Bei einem C++-Codeschnipsel weißt du nie, was wirklich passiert.

    ja, das überladen von operatoren ist eines der wesentlichen merkmale von C++. wenn man sich an bestehende konventionen hält, ist das auch überhaupt nicht schlimm. blöd ist es nur, wenn man einen operator falsch implementiert und daher mehr arbeit ausführen lässt, als nötig wäre. in C muss man sich dann eben darauf verlassen, das irgendwelche funktionen, die man aufruft, richtig und gut geschrieben sind.

    leider? reicht es eben nicht, operator+ und den dereferenzierungsoperator zu überladen, um dieselbe funktionalittät wie mit zeiger+integral zu bekommen. das ist aber so eine unbedeutende randerscheinung, dass man als normaler C++-anwender damit trotzdem gut leben kann.



  • Kleine Frage man schließt ja in einem char* die letzte Stelle mit einer Null ab.

    Wenn ich das hier mache :

    char* name = "Darmstadt";
    //char* ptmp = name;
    name[9] = 0 ;
    
    cout << name << endl;
    

    Warum stürzt da mein Programm ab ? Laut Debugger macht er alles richtig.
    Er erstellt ein Array und an der "9" Stelle gibt er mir eine \0 .

    Kann es seien das ich durch

    char* name = "Darmstadt";
    

    ein Array erzeuge von [i] Stellen und ich dem Array an der 9ten Stelle eine Null angebe und er versucht sie auszugeben und "0" ja kein erlaubter Zustand seien darf?

    Oder hat das was mit dem Speicher zu tuen? Weil bei meinem Dynamischen Speicher muss ich ja mit einer NULL \0 abschließen
    Mfg


Anmelden zum Antworten