Anfänger - Verständnisfrage Rückgabe Referenzen



  • Ich möchte sicher gehen, dass ich eine Aufgabe richtig verstanden habe.

    Aufgabe war, durch eine Funktion einen Wert speichern zu können, sprich die Funktion musste einen Speicherplatz zurückgeben.
    "Können Sie die Funktion in der Form valueAt(array, i) = 1.0; verwenden? Geben Sie eine Begründung und verändern Sie ggf. die Funktion, um es möglich zu machen."

    Lösung:

    double & valueAt( double * array , unsigned int index) {
    return array[index];
    } 
    valueAt(x, 2) = 1.0;
    

    Nun meine Schlussfolgerungen:

    1. Würde ich double array[] übergebe, würde eine lokale Kopie erzeugt, die nach Verlassen der Funktion zerstört wird. Sprich, der Wert von return array[index] existiert nicht mehr.

    2. Mit double * array (call-by-value) arbeite ich jedoch weiterhin mit dem Originalwert. return array[index] gibt also auch nach Verlassen noch einen existierenden Wert zurück.

    3. Würde ich return array[index] als Zeiger zurückgeben, wäre eine Speicheradresse übergeben und die Funktion könnte die 1 hier nicht eintragen, da ich ja nicht dereferenziere. Daher eine Referenz des Arrays, um auch wirklich auf array[index] zuzugreifen und nicht auf die Speicheradresse.

    Öhm.. richtig?! 😮 😕


  • Mod

    Zwischen typ *foo und typ foo[] in der Funktionssignatur gibt es keinen Unterschied. Bloß zwei verschiedene Arten und Weisen in der Schreibweise. Geht auf Sonderregeln für Arrays als Funktionsparameter zurück, die es in C so gab und in C++ so übernommen wurden. Es ist gar nicht möglich, ein Array als Kopie an eine Funktion zu übergeben, außer es ist Teil eines structs (z.B. std::array aus der C++-Standardbibliothek).



  • Siehe hier: http://www.c-plusplus.net/forum/322841 . Hast meinen Rat nicht befolgt. Doppelposts mag keiner!



  • So, jetzt hänge ich komplett.
    Wieso muss der Rückgabetyp dann eine Referenz sein?
    Wenn keine Kopie erzeugt wird, müsste es doch eig reichen, wenn ich nur das Array zurückgebe?!
    Oder muss ich char& angeben, da ich ja innerhalb der Funktion mit einem anderen namen arbeite? Nach dem Motto "Achtung, hier kommt ein Array. Das heißt hier "array", aber eig handelt es sich nur um "a"..." (sprich eine Referenz)

    Ich freue mich auf den Tag in vielen, vielen jahren, wo mir das auch so in Fleisch und Blut übergegangen ist wie euch ;)..

    knivil, entschuldige! Ich hatte den Post bereits geschrieben und abgeschickt, als ich deine Nachricht noch nicht gelesen hatte. Da ich jedoch lediglich auf senden geklickt und die anschließende Spam-Prüfung vergessen hatte, wurde mein Beitrag erst später veröffentlicht. Bin neu hier und gelobe Besserung ;).



  • dummwiebrot schrieb:

    Nun meine Schlussfolgerungen:

    1. Würde ich double array[] übergebe, würde eine lokale Kopie erzeugt, die nach Verlassen der Funktion zerstört wird.

    Falsch. Dann wäre C++ ja regulär 🙂 Ist es aber nicht. Array-Typen haben eine Sonderstellung bei Funktionsparametern. Der Compiler ersetzt [] durch * auf der obersten Ebene, weil sich irgendwer gedacht hat, dass das praktisch sei und weil man rohe Arrays eben nicht einfach so kopieren kann, wie man alles andere auch kopieren kann.

    dummwiebrot schrieb:

    2. Mit double * array (call-by-value) arbeite ich jedoch weiterhin mit dem Originalwert. return array[index] gibt also auch nach Verlassen noch einen existierenden Wert zurück.

    Was meinst du denn mit "dem Originalwert"? double* ist ein Zeigertyp, dementsprechend speichert der array -Parameter ein Zeigerwert, auch bekannt als "Adresse". Und die Adresse wird hier kopiert.

    dummwiebrot schrieb:

    3. Würde ich return array[index] als Zeiger zurückgeben, wäre eine Speicheradresse übergeben und die Funktion könnte die 1 hier nicht eintragen, da ich ja nicht dereferenziere. Daher eine Referenz des Arrays, um auch wirklich auf array[index] zuzugreifen und nicht auf die Speicheradresse.

    Wenn du mit "array[index] als Zeiger zurückgeben" die Adresse des Arrayelements meinst, dann ja.

    dummwiebrot schrieb:

    Wieso muss der Rückgabetyp dann eine Referenz sein?

    Weil nur dann der Funktionsaufruf ein sogenanntes "Lvalue" ist, was sich auf eine bestimmte Speicherlokation bezieht.

    Ich verstehe Dein Problem wohl noch nicht ganz.



  • dummwiebrot schrieb:

    Wieso muss der Rückgabetyp dann eine Referenz sein?

    Müssen muss da gar nichts, kannst auch einen Ochsenfrosch zurückgeben. Entspricht dann evtl. nicht mehr deiner Aufgabenstellung, aber das können wir nicht wissen.

    dummwiebrot schrieb:

    Wenn keine Kopie erzeugt wird, müsste es doch eig reichen, wenn ich nur das Array zurückgebe?!

    Dir sollte mittlerweile klar sein, dass du nirgendwo Arrays übergibst oder zurückgibst, sondern nur Zeiger auf einzelne doubles, z.B. auf das erste double von einem double-Array. Freilich kannst einen Zeiger zurückgeben, dann musst du diesen noch dereferenzieren, um an das double zu kommen, auf das er verweist:

    *valueAt(x, 2) = 1.0;
    

    Hat gegenüber der Referenz-Variante ganz sicher keinen Mehrwert.

    dummwiebrot schrieb:

    Oder muss ich char& angeben, da ich ja innerhalb der Funktion mit einem anderen namen arbeite? Nach dem Motto "Achtung, hier kommt ein Array. Das heißt hier "array", aber eig handelt es sich nur um "a"..." (sprich eine Referenz)

    Hab nichts davon verstanden, bin aber geneigt, mit einem kollektiven "Nein" zu antworten.


Log in to reply