Warum und wie funktioniert ein char pointer?



  • Referenzen sind keine Objekte, Schlaumeier. Das war auch keine Frage, sondern vielmehr ein kleier Check, wie viel der liebe Otze wirklich verstanden hat.



  • 314159265358979 schrieb:

    Referenzen sind keine Objekte, Schlaumeier. Das war auch keine Frage, sondern vielmehr ein kleier Check, wie viel der liebe Otze wirklich verstanden hat.

    Gut. 😃



  • Ich finde eigentlich die Regel, dass alle Audrücke auf die man den Referenzoperator anwenden kann L-Values sind, am einfachsten.



  • *Adressoperator



  • inc7 schrieb:

    &10 klappt aus dem Grund nicht, weil 10 ein int ist und ein int ein rvalue ist. Bei &Test muss es sich dann um ein lvalue handeln. &Test kann aber auch ein rvalue sein, weil man einen string doch jederzeit einer anderen stringvaribale zuweisen kann. &Test = "test2" funktioniert aber auch nicht. Warum soll dann &Test ein lvalue sein?

    Dahinter muss doch eine einfache Logik stecken, die besagt wie und was ein rvalue und wie und was ein lvalue ist. Genau das ist das, wonach ich such. Wo gibt es sowas?

    Da ein Stringliteral Speicher belegt, ist es ein L-Value. Das ist so weit korrekt. Jedoch handelt es sich (wie eigentlich weiter oben bereits beschrieben) um ein const char[] und ist damit konstant. Daher kannst du diesem keinen neuen Wert zuweisen.

    Ein L-Value kann immer auch als ein R-Value verwendet werden. Der Zuweisungsoperator (=) braucht immer mindestens ein L-Value (L = R oder L = L jedoch nicht möglich R = R). 🙂

    Gruss



  • anneXus! Ja! Dank dir hab ich es jetzt endlich verstanden! 👍

    Damit die Nachwelt auch was von mir hat, ergänzend zu deinen Beitrag noch ein sehr nützlicher Artikel: http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/. Ich habe sehr lange nach einen guten Artikel suchen müssen, weil die meisten die Antworten im Internet (Foren etc.) viel zu ungenau sind. In dem Artikel wird alles erklärt.

    Meine Faustregeln und eine kurze Zusammenfassung:

    • LV = Hat immer eine Adresse (fest deklariert angegeben)
    • RV = Ist ein Ausdruck, temporär im Speicher (z.B. Werte zusammenkopieren, Beispiel: int result = f1() * f2()).
    • RV kann nicht in LV umgewandelt werden.
    • *-Operator macht aus ein LV ein RV (LValue -> RValue)
    • &-Operator macht aus LV ein RV (LValue -> RValue)
    • Eine LValue muss immer gegeben sein.
    • L = R // möglich
    • R = R // möglich
    • L = L // möglich
    • R = R // nicht möglich

    😉



  • inc7 schrieb:

    # R = R // möglich
    # R = R // nicht möglich

    Sein oder nicht sein 😉



  • Wann ist denn R = R möglich? Kannst du mir dazu ein Beispiel geben, was beweist, dass R = R möglich ist?



  • inc7 schrieb:

    []-Operator macht aus ein LV ein RV (LValue -> RValue)
    [*]&-Operator macht aus LV ein RV (LValue -> RValue)

    Wenn das stimmt, dann hab ich da was ganz Grundlegenes nicht verstanden. Was hat das mit Pointern und Referenzen zu tun? Klar, du canst C/V-qualifier hinzu/weg-casten, aber implizit funktioniert das doch nicht?

    @inc7: Das ist ja grade nicht möglich.

    const int a;//rvalue
    a = 5; //RV = RV ->NICHT MÖGLICH
    


  • Da hast du recht. Es wäre besser gewesen in meinem vorherigen Beitrag zu erwähnen, dass es sich um nicht-const-Typen handelt.



  • 314159265358979 schrieb:

    @otze:

    int&& irr = 42;
    int* ptr = &irr;
    

    Und schon hab ich die Adresse von 42, stimmts? 😉

    Liebes schlecht angenähertes PI.
    Im Gegensatz zu dir lebe ich nicht im C++11 Standard und kann dir deswegen absolut nichts über rvalue-refs sagen. Ich werde mich damit beschäftigen, wenn es Breitflächenunterstützung seitens der Compiler gibt. Ich könnte dir momentan nicht einmal sagen, ob das Ding so compiliert. Es interessiert mich einfach nicht.

    Ich muss aber wieder anmerken, dass du dein typisches "ich erhöhe mich, indem ich andere versuche zu erniedrigen"-Muster anwendest. Das ist langweilig und vorhersehbar. da spiele ich nicht mit.



  • Ach otze. Immer derselbe Scheiß.

    Ist doch lustig? Nein?

    DANN IGNORIER ES VERDAMMT NOCHMAL. Auf deine psychoanalytische, genervte Antwort wartet auch kein Mensch.

    🙂 🕶

    Edit: zu "schlecht angenährt" kann ich nur sagen, was mir schon mein Mathe-Lehrer oft erklärt hat, nähmlich dass oft schon 6-7 Stellen nach dem Komma ausreichen, um das gewünschte Ergebnis zu erzielen. Als Programmierer solltest du das wissen, ich hab beim Spiele-Programmieren noch nie ein Problem damit gehabt 😉



  • Eigentlich wollte ich dich nur testen. Dass du keinen Plan von C++11 hast, das wusste ich nicht 😉



  • inc7 schrieb:

    LV = Hat immer eine Adresse (fest deklariert angegeben)

    Richtig.

    inc7 schrieb:

    RV = Ist ein Ausdruck, temporär im Speicher (z.B. Werte zusammenkopieren, Beispiel: int result = f1() * f2()).

    Richtig.

    inc7 schrieb:

    RV kann nicht in LV umgewandelt werden.

    Falsch. In bestimmten Fällen ist dies möglich. Der folgende Code tut genau dies, erzeugt allerdings eine Dangling Reference. Eine weitere Verwendung von f würde also zu undefiniertem Verhalten führen.

    struct foo {};
    
    int main()
    {
            foo const& f = foo();
    }
    

    http://ideone.com/0K1KS

    inc7 schrieb:

    *-Operator macht aus ein LV ein RV (LValue -> RValue)
    &-Operator macht aus LV ein RV (LValue -> RValue)

    Das würde ich nicht so formulieren. Er dereferenziert einfach/nimmt einfach die Adresse, das ist keine Umwandlung.

    inc7 schrieb:

    Eine LValue muss immer gegeben sein.

    Diesen Satz verstehe ich nicht.

    inc7 schrieb:

    L = R // möglich
    R = R // möglich
    L = L // möglich
    R = R // nicht möglich

    Zeile 2 sollte wohl "L = R" heißen. Allerdings ist auch "R = R" möglich, wie z.B.:

    struct foo {};
    
    int main()
    {
            foo() = foo();
    }
    

    http://ideone.com/WoCQF

    Der Grund, warum die beiden Sonderfälle, funktionieren, ist, dass sich user-definierte RValues etwas anders verhalten als RValues von eingebauten Typen. Mit z.B. int würde das nicht funktionieren.



  • Hacker schrieb:

    @inc7: Das ist ja grade nicht möglich.

    const int a;//rvalue
    a = 5; //RV = RV ->NICHT MÖGLICH
    

    Dein "a" hier ist aber ein LValue, desweiteren wird kein Compiler deinen Code schlucken, da Konstanten immer direkt initialisiert werden müssen. Dass die Zuweisung nicht funktioniert, liegt daran, dass "a" ein konstanter LValue ist.



  • 314159265358979 schrieb:

    Falsch. In bestimmten Fällen ist dies möglich. Der folgende Code tut genau dies, erzeugt allerdings eine Dangling Reference. Eine weitere Verwendung von f würde also zu undefiniertem Verhalten führen.

    struct foo {};
     
    int main()
    {
            foo const& f = foo();
    }
    

    http://ideone.com/0K1KS

    Korrektur: Es entsteht kein undefiniertes Verhalten, da die Lebenszeit des foo-Objekts verlängert wird.



  • Hacker schrieb:

    Edit: zu "schlecht angenährt" kann ich nur sagen, was mir schon mein Mathe-Lehrer oft erklärt hat, nähmlich dass oft schon 6-7 Stellen nach dem Komma ausreichen, um das gewünschte Ergebnis zu erzielen. Als Programmierer solltest du das wissen, ich hab beim Spiele-Programmieren noch nie ein Problem damit gehabt 😉

    Welches Komma?



  • 314159265358979 schrieb:

    Hacker schrieb:

    @inc7: Das ist ja grade nicht möglich.

    const int a;//rvalue
    a = 5; //RV = RV ->NICHT MÖGLICH
    

    Dein "a" hier ist aber ein LValue, desweiteren wird kein Compiler deinen Code schlucken, da Konstanten immer direkt initialisiert werden müssen. Dass die Zuweisung nicht funktioniert, liegt daran, dass "a" ein konstanter LValue ist.

    Ich dachte, konstante LValues sind RValues? Dann habe ich es auch nicht verstanden. Aber danke für die Korrektur.

    @ScottZhang: Kommas dürfen bei Benutzernamen ja sowieso nicht auftreten, aber ich seh was du meinst 😃



  • Nein, sind sie nicht.


Anmelden zum Antworten