Ratlos bei Pointern/References



  • Hallo zusammen.

    Ich versuche seid geraumer Zeit hinter das Konzept von Pointern und References zu steigen - soweit so gut. Mein Problem leigt in der C++ Syntax

    worin liegt der Unterschied zwischen
    int* x
    *int x
    int x
    int x

    ich rall es einfach nicht ... je nachdem bekomme ich andere Ergebnisse etc

    selbiges gilt für References.

    Währe nett wenn das jemand verständlich beantworten kann (bin noch relativer neuling)



  • int* x // x ist ein pointer auf int
    *int x // syntax fehler
    int x // x ist ein pointer auf int
    int x
    // syntax fehler

    DerVollstreckerDer Vollstrecker


  • Mod

    Elor schrieb:

    Hallo zusammen.

    Ich versuche seid geraumer Zeit hinter das Konzept von Pointern und References zu steigen - soweit so gut. Mein Problem leigt in der C++ Syntax

    worin liegt der Unterschied zwischen
    int* x
    *int x
    int x
    int x

    ich rall es einfach nicht ... je nachdem bekomme ich andere Ergebnisse etc

    selbiges gilt für References.

    Währe nett wenn das jemand verständlich beantworten kann (bin noch relativer neuling)

    Grundsätzlich geht C++ beim Aufbau von Deklarationen von einer Grundform

    T x;
    

    welche eine variable x vom Typ T deklariert, aus. Dieser Typ T kann jetzt durch sogenannte Deklaratoren modifiziert werden. Das Unangenehme dabei ist, dass diese Deklaratoren rekursiv anzuwenden sind.
    Es wäre ja eine Sprachdefinition denkbar, in der eine Referenz auf einen Pointer auf ein Array aus 3 Elementen aus Zeigern auf ints so aussieht:

    &*[3]*int x;
    

    Diese Form wäre für den Anfänger sicher leichter zu verstehen, sie folgt aber grundsätzlich den selben Prinzipien und man würde eine solche Grammatik ebenfalls rekursiv darstellen. In C++ ist es nun so, dass die Deklaratoren nicht vor dem Grundtyp stehen, sondern danach, wobei noch problematisch ist, dass einige Deklaratoren sogar rechts vom Bezeichner stehen.
    Unser Beispiel sieht in C++ so aus:

    int*(*&x)[3];
    

    Um diesen Aufbau zu verstehen, geht man rekursiv vor: man sucht sich den dem Variablenbezeichner am nächsten stehenden Deklarator (wobei Deklaratoren, die rechts vom Bezeichner stehen, Vorrang haben vor solchen, die links stehen; Klammern können diesen Vorrang aber aufheben wie hier). In diesem Falle also &, was eine Referenz deklariert. Wir haben also eine Referenz auf etwas. Im nächsten Schritt lassen wir das & unter den Tisch fallen und suchen wieder nach dem nächsten Bezeichner. Also der *, was einen Pointer bezeichnet. Wir haben es also mit einer Referenz (aus dem ersten Schritt) auf einen Pointer zu tun. Wir lassen den * fallen und auch die Klammern, die jetzt nichts außer dem Bezeichner umschließen. Es kommen jetzt einmal der zweite * in Betracht als auch die eckigen Klammern für die Arraydeklaration. In diesem Fall hat letzteres Vorrang, da es rechts steht (der zweite solche Deklarator sind runde Klammern für Funktionsdeklarationen, welche auch rechts stehen und den Bezeichner gerade nicht umschließen, Deklaratoren die Funktionen beschreiben führen sehr schnell zu überkomplexen Deklarationen, wenigstens hier sollte man großzügig mit typedefs arbeiten). Wir ignorieren das Array finden dann den * und schließlich den Grundtyp int. Also
    & --> * --> [3] --> * --> int
    Man liest gewissermaßen (vorbehaltlich von Klammern, die den Vorrang verändern) zunächst die Deklaratoren rechts vom Variablenbezeichner von links nach rechts und dann diejenigen links vom Variablenbezeichner von rechts nach links.
    Im Übrigen unterscheidet sich deine erste Zeile von der dritten nur durch das Leerzeichen - whitespaces zwischen einzelnen Token sind für den Compiler aber völlig irrelevant. Ob du nun

    int* x; // oder
    int *x; // oder
    int*x;
    

    schreibst, hat keinen Einfluß auf das Programm, sondern ist eine Frage der Form und des Stils.



  • [quote="Elor"]Hallo zusammen.

    worin liegt der Unterschied zwischen
    int* x
    *int x
    int x
    int x

    ich rall es einfach nicht ... je nachdem bekomme ich andere Ergebnisse etc

    quote]

    unterschiedliche Ergebnisse?? du bekommst halt compilerfehler.....



  • Hej,

    ich wuerde aber, immer so schreiben:

    int *Variable1;
    

    👍
    Aus dem einfachen Grund wenn du dir das angewoehnst:

    int* Variable1;
    

    👎

    koennte es spaeter sein, das du faelschlicher Weise denkst das hier ZWEI Pointer deklariert werden:

    int* Variable1, Variable2;
    

    👎

    Aber 'Variable2' ist ein normaler int und kein pointer auf einen int.
    Also ist folgendes besser:

    int *Variable1, Variable2;
    

    Hier nochmal ein unschoenes Beispiel ums zu verdeutlichen.
    (so soltle man aber nichts deklarieren, zu unuebersichtlich)

    int *Variable1, Variable2, *Variable3, *Variable4, Variable5, Variable6;
    

    👍

    Am besten pointer und normale variablen eh immerin unterschiedlichen Zeilen deklarieren 🙂
    So jetzte habe ich genug geschwafelt,
    MfG, Tim :xmas1:



  • Heimdall83 schrieb:

    Hej,

    ich wuerde aber, immer so schreiben:

    int *Variable1;
    

    👍
    ...

    Ich habe mal die Eselsbrücke gelesen:

    int *v;
    

    bedeutet: Wenn man v dereferenziert (mit '*'), kommt ein int raus. 😃

    Wem's nichts bringt: Vergessen !

    Gruß,

    Simon2-.



  • Ich check die Eselsbrücke nich 😕 😞 😃


  • Mod

    Heimdall83 schrieb:

    ...

    koennte es spaeter sein, das du faelschlicher Weise denkst das hier ZWEI Pointer deklariert werden:

    int* Variable1, Variable2;
    

    👎

    Aber 'Variable2' ist ein normaler int und kein pointer auf einen int.
    Also ist folgendes besser:

    int *Variable1, Variable2;
    

    Dagegen wäre einzuwenden, dass eher die Deklaration mehrerer Variablen in einer Deklaration unschön ist. Schon allein deshalb, weil wir in C++ Variablen gleich initialisieren wollen und entsprechend die Definition erst durchführen, wenn wir initialisieren können. Wenn aber schon, wie in deinem Beispiel, ein einfacher Stern so leicht mißgedeutet werden kann, dann muss das für Initialisierungen, die ein zusätzliches syntaktisches Element sind, erst recht gelten.

    int* x;
    

    ist einfach schöner, weil es Typ und Bezeichner deutlich trennt. Im Übrigen ist das eine reine Stilfrage und insofern OT.



  • ich denk nun hab ichs.
    wenn ich int *x deklariere muss ich nachher im Code auch *x benutzen oder krieg ich dann ne Speicheradresse ausgegeben ?



  • Simon2 schrieb:

    Ich habe mal die Eselsbrücke gelesen:

    Das ist keine Eselsbrücke, das ist der Grund, aus dem C++ diese behinderte Syntax hat: Ritchie dachte sich beim Entwickeln von C, dass es sicher am intuitivsten sei, Deklarationen so zu schreiben, dass der Zugriff auf den Inhalt genauso (oder ähnlich) aussieht. Ritchie hat aber später zugegeben, dass sie sich dabei in der Praxis wohl geirrt haben [1].

    Heimdall: Da kann man sehr unterschiedlicher Ansicht sein. Ich finde das genau andersherum: '*' ist Teil des Typs und gehört deswegen zum Typ, nicht zum Bezeichner. Und mehrere Variablen hintereinander deklariert man einfach nicht, das ist unübersichtlich. Pro Variable eine Anweisung, so einfach.

    EDIT:
    [1] “Sethi [Sethi 81] observed that many of the nested declarations and expressions would become simpler if the indirection operator had been taken as a postfix operator instead of prefix, but by then it was too late to change.”
    Aber: “In spite of its difficulties, I believe that the C's approach to declarations remains plausible, and am comfortable with it;”
    [http://cm.bell-labs.com/cm/cs/who/dmr/chist.html]



  • Konrad Rudolph schrieb:

    Simon2 schrieb:

    Ich habe mal die Eselsbrücke gelesen:

    Das ist keine Eselsbrücke, das ist der Grund, aus dem C++ diese behinderte Syntax hat: Ritchie dachte sich beim Entwickeln von C, dass es sicher am intuitivsten sei, Deklarationen so zu schreiben, dass der Zugriff auf den Inhalt genauso (oder ähnlich) aussieht. ...

    Auch, wenn ich das noch nicht wusste: Das ist doch gar kein Widerspruch.
    Ritchie hat das so definiert, weil er meinte, so könnte man sich das am leichtesten Merken - er hat also diese "Eselsbrücke" (was ja nur "Merkhilfe" bedeutet) in die Sprache eingebaut. 😃

    Aber das ist auch egal - zukünftig fange ich den Satz an mit "Ritchie dachte sich damals ....", ok ? 😉

    Gruß,

    Simon2.


Log in to reply