Sehr komplizierte Variablendeklarationen - HILFE!



  • Aufgabe:

    a) Bestimmen Sie, ob das Konstrukt eine Deklaration oder eine Definition ist. Geben Sie im Falle einer Definition das Objekt an, mit dem der Name assoziiert ist.
    b) Schreiben Sie das Konstrukt als gültigen C++-Quellcode an.
    c) Identifizieren Sie die Teile Spezifizierer, Basistyp, Deklarator und Initialisierer

    Gegeben sind die folgenden Konstrukte:

    1. p ist ein Zeiger auf einen konstanten double. Der Zeiger wird mit 0 initialisiert.
    mein vorschlag: double const* p = 0;

    2. q ist eine Funktion mit einem Zeiger auf char als Argument, die einen Zeiger auf eine Funktion liefert, die eine Referenz auf einen konstanten int als Argument besitzt und eine Referenz auf einen konstanten double liefert.
    mein vorschlag: (double const& f(int const&))* q(char*);

    3. r ist ein Zeiger auf eine Funktion, die keine Argumente besitzt und einen int liefert. Der Zeiger wird mit s initialisiert.
    mein vorschlag: (int f())* r = s;

    4. t ist ein Feld der Länge 7 mit Zeigern auf eine Funktion, die eine Referenz auf einen int als Argument besitzt und einen Zeiger auf eine Funktion liefert, die keine Argumente besitzt und einen Zeiger auf void liefert. Die ersten vier Elemente von t werden mit w, x, y, z initialisiert.
    mein vorschlag: ((void* q())* f(int&))* t [7] = {w, y, y, z};

    Bitte helft mir 🙂



  • ..



  • thomassteiner schrieb:

    1. p ist ein Zeiger auf einen konstanten double. Der Zeiger wird mit 0 initialisiert.
    mein vorschlag: double const* p = 0;

    Das ist ein konstanter Zeiger, der auf double zeigt.
    //edit: const* is eh Rotz^^

    const double* p = 0;
    

    so ist das besser



  • Meiner C++-Kenntnis nach ist beides das gleiche.



  • int j = 578;
    
    int *p = &j;  //Variabler Zeiger, variables Objekt
    
    const int *p2 = &j;  //Variabler Zeiger, konstantes Objekt
    //int const *p2 = &j;  //ebenso: Variabler Zeiger, konstantes Objekt
    
    int * const p3 = &j; //Konstanter Zeiger, variables Objekt
    
    const int * const p4 = &j;  //Konstanter Zeiger, konstantes Objekt
    


  • Pellaeon schrieb:

    thomassteiner schrieb:

    1. p ist ein Zeiger auf einen konstanten double. Der Zeiger wird mit 0 initialisiert.
    mein vorschlag: double const* p = 0;

    Das ist ein konstanter Zeiger, der auf double zeigt.
    //edit: const* is eh Rotz^^

    const double* p = 0;
    

    so ist das besser

    nö.
    "p ist ein Zeiger auf einen konstanten double" liest man vom p aus nach außen.
    double const* p
    "p ist ein konstanter Zeiger auf einen double" liest man auch vom p aus nach außen.
    double * const p


  • Mod

    du hast noch probleme mit der deklaration von funktionen und -zeigern.
    die C syntax ist hier sehr eigenwillig, aber wenn man das prinzip verstanden hat, ist es im grunde simpel:
    - es gibt 2 arten von modifikatoren: prä- und postfix (stets bezogen auf den bezeichner, der evtl. fehlen kann) modifikatoren (ganz analog zu operatoren in ausdrücken), postfix-modifikatoren haben stets vorrang vor präfix-modifikatoren
    - präfix: * & const volatile
    - postfix: () []

    also

    int *a
    

    lies von rechts nach links (immer vom bezeichner weg, zeiger auf int)

    int a[]
    

    zunächst die postfix-modifikatoren also ein array, dann die linke seite 'von ints'

    int *a[]
    

    - analog ein array von zeigern auf int
    mit zusätzlichen klammern können wir den vorrang von modfikatoren ändern:

    int (*a)[]
    

    ist ein zeiger auf ein array von ints

    unterscheiden kannst du diesen fall (klammern benutzt um vorrang zu ändern) von funktionsdeklarationen leicht dadurch, dass hier die klammern den bezeichner umschliessen.

    also

    int a()
    

    eine funktion, die keine argumente hat und ein int zurückliefert

    int *a()
    

    eine funktion, die keine argumente hat und einen zeiger auf int zurückliefert

    int (*a)()
    

    ein zeiger auf eine funktion, die keine argumente hat und ein int zurückliefert

    implizite typdefinitionen für rückgabewerte oder argumente einer funktion schreibst du auf dieselbe weise, nur lässt du einfach den bezeichner weg

    wir nehmen das letzte beispiel, einen zeiger auf eine funktion, die keine argumente hat und ein int zurückliefert und wollen jetzt eine funktion, die einen solchen funktionszeiger zurückliefert:

    also

    int (*a)()
    

    wir lassen den bezeichner weg:

    int (*)()
    

    und machen eine funktion daraus, die diesen zeiger zurückgibt:

    int (*)() f()
    

  • Mod

    hier noch was exotisches:

    volatile X*const& (Y::*[])(Z(&)())const foo()
    

    🕶



  • thomassteiner schrieb:

    Bitte helft mir 🙂

    Gerne, welche Probleme hast du denn?



  • thx für die antworten erstmal.
    gleich mal umsetzen 😃



  • okay, erstmal danke.

    ich habe folgende ergebnisse:
    1. double const* p = 0;
    2. const double& (* q(char*))(int&);
    3. int (r)() = s;
    4. void
    ()() ( t[7])(int&) = {w, x, y, z};

    die drei ersten ausdrücke lassen sich kompilieren.
    der 4. ausdruck liefert aber folgende fehlermeldung:

    error C2059: syntax error : ')'

    wer kann mir weiterhelfen? 😉


  • Mod

    der letzte teil meines postings war unsinn ... eine solche grammatik wäre auch nicht eindeutig. richtig ist:

    int (*a)()
    

    nun soll a kein einfacher bezeichner sein, sondern selbst eine funktion, also:

    int (*f())()
    

    diese verschachtelung macht das ganze ziemlich schnell unübersichtlich, zum glück gibt es ja typedefs; und ein C++ programmierer muss sowas gar nicht lesen können 🙂



  • ah perfekt. dann lautet der ausdruck also:

    void* (*(* t[7])(int&))();
    

    wo liegen bei so einem ausdruck aber basistyp und deklarator?
    ist der basistyp einfach der am weitesten links liegende datentyp und der deklarator der rest?

    in diesem fall also:

    basistyp: void
    deklarator: * (( t[7])(int&))()


Anmelden zum Antworten