function pointer, definitionsfrage



  • Hallo Zusammen,

    [cpp]void * (* (*fp1)(int)) [10];
    void * [b](*[/b] (*fp1)(int)[b])[/b] [10];
    [b]void *[/b] (* (*fp1)(int)) [b][10][/b];
    void * [10] (*fp1)(int);[/cpp]
    

    Ich verstehe diesen Zusammenhang nicht. Die erste Zeile soll einen Funktionszeiger darstellen, wobei es ein int als Argument gibt, sowie ein array of void pointers als Rueckgabe. Mit dem Fett gedruckten darin (Zeile 2) kann ich gar nichts anfangen. Auch verstehe ich nicht, wieso der Rueckgabewert rechts und links verteilt ist (Zeile 3). So wie ich es verstehen koennte, muesste Zeile 4 richtig sein (ist sie natuerlich nicht).



  • Eine Funktion kann kein Array returnen.



  • wollewausfander schrieb:

    void * (* (*fp1)(int)) [10];
    

    Eine Funktion, die einen solchen Rückgabedatentyp hat, müsste dann so aussehen:

    // fp1 ist ein Zeiger auf eine Funktion, die einen Zeiger auf ein Array von 10 void-Zeigern zurückgibt.
    void* (* (*fp1)(int)) [10]; // Funktionszeiger
    
    void* ar[10] = {}; // globales Testarray
    
    void* ( *(fkt)() ) [10]  { return &ar; } // Funktion
    


  • Eine Funktion kann kein Array zurückgeben.

    Wenn die Syntax in der vierten Zeile ok wär, könnte ich ein Array so deklarieren:

    int [4] arr;
    

    [] ist aber ein Postfix Oprator und genauso funktioniert er auch als Deklarator. Man kann sich, mit ein paar kleinen Ausnahmen, die rechte Seite als Ausdruck vorstellen, der dann den Typ hat, der links steht. Bei

    int arr[4];
    

    wäre der Ausdruck arr[4] und der hat quasi den Typ int, obwohl man hier 4 natürlich nicht wirklich als Index verwenden kann. Aber das Prinzip gilt für alles andere auch:

    irgendwas[N]      --> irgendwas ist ein Array von N ...
    irgendwas(params) --> irgendwas ist eine Funktion. Sie gibt ... zurück
    *irgendwas        --> irgendwas ist ein Zeiger auf ...
    &irgendwas        --> irgendwas ist eine Referenz auf ...
    

    Und die Präzedenzen sind genauso wie bei den Operatoren. Postfix vor Präfix. Dementsprechend kann man das jetzt verschachteln:

    *irgendwas[N]     --> irgendwas ist ein Array von N Zeigern auf ...
    

    und so weiter.

    Du kannst diesen Quasi-Ausdruck auch von außen außeinander nehmen, in dem Du den "letzten Operator" mit der niedrigsten Präzedenz entfernst:

    void * (* (*fp1)(int)) [10]
        ^^^^ ^^^^^^^^^^^^^^^^^^^^^^
          |            |
          |       Deklarator
          |
        Typspezifizierer
    
    bedeutet:
    
        * (* (*fp1)(int)) [10]  ist  void
    
    =>    (* (*fp1)(int)) [10]  ist  Zeiger auf void
    
    =>    (* (*fp1)(int))       ist  Array aus Zeigern auf void
    
    =>       (*fp1)(int)        ist  Zeiger auf Array aus Zeigern auf void
    
    =>        *fp1              ist  Funktion mit int-Parameter, die einen
                                     Zeiger auf Array aus Zeigern auf void
                                     zurückgibt
    
    =>         fp1              ist  Zeiger auf Funktion mit int-Parameter,
                                     die einen Zeiger auf Array aus Zeigern
                                     auf void zurück gibt.
    


  • krümelkacker schrieb:

    void * (* (*fp1)(int)) [10]
        ^^^^ ^^^^^^^^^^^^^^^^^^^^^^
          |            |
          |       Deklarator
          |
        Typspezifizierer
    
    bedeutet:
    
        * (* (*fp1)(int)) [10]  ist  void
    
    =>    (* (*fp1)(int)) [10]  ist  Zeiger auf void
    
    =>    (* (*fp1)(int))       ist  Array aus Zeigern auf void
    
    =>       (*fp1)(int)        ist  Zeiger auf Array aus Zeigern auf void
    
    =>        *fp1              ist  Funktion mit int-Parameter, die einen
                                     Zeiger auf Array aus Zeigern auf void
                                     zurückgibt
    
    =>         fp1              ist  Zeiger auf Funktion mit int-Parameter,
                                     die einen Zeiger auf Array aus Zeigern
                                     auf void zurück gibt.
    

    Danke an alle, die geantwortet haben. Krümelkacker, jetzt ist es klar, die dritte Folgerung (Zeiger auf Array aus Zeigern auf void) ist also der eigentliche Rückgabewert. Dass man kein Array zurückgeben kann, war schon klar (gibts m.W. in keiner Sprache). Nur stand die Zeile eben so in 'Thinking in C++' drinnen, daher wunderte es mich, dass dot meinte, es würde nicht gehen. Nichts desto trotz ist es m.M. eine sehr gewöhnungsbedürftige Schreibweise.



  • wollewausfander schrieb:

    Dass man kein Array zurückgeben kann, war schon klar (gibts m.W. in keiner Sprache).

    Wie kommst du denn darauf? Im Gegenteil, diese seltsame Sonderbehandlung von Arrays gibt es meines Wissens nur in C und C++.



  • Bashar schrieb:

    wollewausfander schrieb:

    Dass man kein Array zurückgeben kann, war schon klar (gibts m.W. in keiner Sprache).

    Wie kommst du denn darauf? Im Gegenteil, diese seltsame Sonderbehandlung von Arrays gibt es meines Wissens nur in C und C++.

    Ok, es ist auch zumindest auch zweimal von anderen bestätigt worden (vermutlich was das aber nur der Hinweis für mich, dass das mit der 4. Zeile Quatsch ist). Nichts desto trotz - ohne Dir widerprechen zu wollen - die Erklärung von Krümelkacker sagt ja aus, dass eben kein Array, sondern nur ein Zeiger auf das Array zurück gegeben wird. Ich hatte nur angemerkt, dass mir bekannt war, dass ein ('normales') Array in keiner Sprache rückgeliefert werden kann und das ist ja auch so. Diese 'Sonderbehandlung' hier ist ja nun was ganz anderes. Mir fällt aber auch gerade ein, dass es ggf. in Lisp möglich ist, ein Array zurück zu geben?!



  • wollewausfander schrieb:

    Ich hatte nur angemerkt, dass mir bekannt war, dass ein ('normales') Array in keiner Sprache rückgeliefert werden kann und das ist ja auch so.

    Nö.

    Diese 'Sonderbehandlung' hier ist ja nun was ganz anderes.

    Mit Sonderbehandlung meinte ich, dass Arrays keine normalen Werte sind (nicht "first-class") und dementsprechend einige Einschränkungen gelten. Wie z.B. dass man sie nicht zurückgeben kann.

    Mir fällt aber auch gerade ein, dass es ggf. in Lisp möglich ist, ein Array zurück zu geben?!

    Ja selbstverständlich. Wie gesagt, es geht in so gut wie jeder Sprache (die Arrays unterstützt).



  • Bashar schrieb:

    Wie z.B. dass man sie nicht zurückgeben kann.

    Bashar schrieb:

    Ja selbstverständlich. Wie gesagt, es geht in so gut wie jeder Sprache (die Arrays unterstützt).

    Ja was denn nun? Geht oder geht nicht? Dein Posting ist widerspruechlich. Ich versteh auch nicht, was das Katz und Maus Spiel jetzt soll. Die urspr. Frage war eine ganz andere.



  • wollewausfander schrieb:

    Bashar schrieb:

    Wie z.B. dass man sie nicht zurückgeben kann.

    Bashar schrieb:

    Ja selbstverständlich. Wie gesagt, es geht in so gut wie jeder Sprache (die Arrays unterstützt).

    Ja was denn nun? Geht oder geht nicht?

    Geht nicht in C. Geht nicht in C++. Geht fast überall sonst. Ist das so schwer?

    Dein Posting ist widerspruechlich. Ich versteh auch nicht, was das Katz und Maus Spiel jetzt soll.

    Würdest du mich nicht ständig missverstehen, hätte sich das schon lange erledigt.

    Die urspr. Frage war eine ganz andere.

    Du warst es doch, der die Aussage gepostet, dass man Arrays in keiner Programmiersprache zurückgeben kann.



  • Bashar schrieb:

    Geht nicht in C. Geht nicht in C++. Geht fast überall sonst. Ist das so schwer?

    Konnte ich so bisher nicht rauslesen. Die 'Sonderreglung' lies mich das so verstehen, dass es 'nur' in C/C++ geht.

    Bashar schrieb:

    Würdest du mich nicht ständig missverstehen, hätte sich das schon lange erledigt.

    S.o. Ansonsten hat Du sicher Recht, das Thema ist noch recht neu fuer mich und Java hatte keine Zeiger. Tut mir leid, dass ich Dich nicht schneller verstanden habe (ernst gemeint).

    Auch wenn es hier OT ist; bei Perl geht es (meiner Meinung nach!) auch nicht, da man dort nur Referenzen auf Arrays zurueck geben kann. Letztenendes ist das doch ein aehnliches Konstrukt, nicht wahr?!


Anmelden zum Antworten