Fragen zu Referenzen und Return
-
Hallo,
ich bin momentan am Erlernen von C++ und habe hier noch zwei Fragen an euch:
- Gibt es eine Möglichkeit, mit "return" oder einer anderen Anweisung mehrere Werte einer Funktion zum Aufrufer zurückzugeben?
- Bin ich richtig der Annahme, dass eine Referenz keinen Speicher benötigt? Weil eine Referenz "zeigt" ja direkt auf die Variable und speichert keine Adressen.
Danke schon im Voraus!
-
-
Mehrere Werte kann man nicht zurückgeben. Dafür musst du Werte per Referenz/Zeiger als Parameter mitgeben, diese werden dann von der Funktion verändert.
-
Keinen Speicher können Referenz/Zeiger nicht brauchen, denn ohne Seicher könnte man doch auch keine Adresse speichern, oder?

Aber der Speicherverbrauch ist sehr gering.
-
-
Per return kannst du nur eine Variable zurückgeben. Dies kann aber auch eine Liste oder sonstige Formen von Containern oder komplexen Strukturen sein.
Eine recht übliche Methode ist es aber auch nur einen Statuswerd zurückzugeben und die zu füllenden Variablen als Referenzen oder Pointer übergeben zu bekommen und diese zu verändern.
Zum Beispiel:
bool convertWhateverToSthelseAndStuff(const WhatEver &whatever, Sthelse &blupp, Stuff &stuff){ // convert convert convert return success; }Referenzen sind im Grunde auch nur Pointer und belegen sizeof(int*) was in etwa ein int sein dürfte.

-
Miness schrieb:
- Gibt es eine Möglichkeit, mit "return" oder einer anderen Anweisung mehrere Werte einer Funktion zum Aufrufer zurückzugeben?
Ja, es gibt mehrere Möglichkeiten, hier ein paar davon:
std::pairbzw.boost::tuplezum Zusammenfassen mehrerer Werte- eigene Klasse zurückgeben, die Werte zusammenfasst
- Output-Parameter benutzen
Miness schrieb:
- Bin ich richtig der Annahme, dass eine Referenz keinen Speicher benötigt? Weil eine Referenz "zeigt" ja direkt auf die Variable und speichert keine Adressen.
Das stimmt nur bedingt. In vielen Situationen kannst du dir eine Referenz wie ein eingeschränkter Zeiger vorstellen (automatische Dereferenzierung, kein Nullwert, keine eigene Adresse, konstant). Wenn du zum Beispiel eine Referenz an eine Funktion übergibst, braucht die Referenz Speicher, da sie ja eine Adresse (die des referenzierten Objekts) speichern muss.
-
Vielen Dank für eure Antworten!
Um Werte zurückzugeben habe ich erst gar nicht an Zeiger und Referenzen gedacht. Aber so funktionierts natürlich auch, obwohl ja auf diese Weise die Variablen direkt verändert werden.@Nexus: Was meinst du mit Output-Parameter?
@Fellhuhn: Wenn ich den Statuswert "success" zurückgebe weiss der Aufrufer, dass die Funktion erfolgreich durchgelaufen ist? Verstehe ich das richtig?
-
Jenachdem wie du das machst.
Ich hab hier zB gerade eine Funktion die Lat/Lon-Coordinaten in Bildschirmkoordinaten umwandelt. Alle Koordinaten (Lat/Lon und x/y) werden als Referenzen übergeben und der Rückgabewert zeigt mir ob die Umwandlung erfolgreich war. Der Aufruf ist dann in etwa:
if (convertLatLonToXY(coord.lat, coord.lon, screenX, screenY)) { // erfolgsfall }else{ // fehlermeldung, rest abbrechen }Da es dein Code ist, ist das natürlich deine Entscheidung.

-
Okay, alles klar! Wieder etwas dazugelernt.

Aber eine Funktion sollte ja eigentlich immer funktionieren, sonst würde der Compiler das ja bemerken und eine Fehlermeldung ausgeben. Ausser man prüft innerhalb der Funktion dann auch, unter welchen Bedingungen "success" zurückgegeben wird. Oder?
-
In C++ gibt es noch den Weg von Exceptions. Damit kann man den Rückgabetypen der Funktion für Daten nutzen. Aber je nachdem ist Fellhuhns Ansatz praktischer.
Miness schrieb:
@Nexus: Was meinst du mit Output-Parameter?
Mit Output-Parameter meinte ich Funktionsparameter (Zeiger oder Referenzen), die für Ausgabewerte der Funktion verwendet werden. Die Funktion speichert ihre Ergebnisse also dort.
Miness schrieb:
Aber eine Funktion sollte ja eigentlich immer funktionieren, sonst würde der Compiler das ja bemerken und eine Fehlermeldung ausgeben.
Naja, je nachdem kann die Funktion eben eine angeforderte Aufgabe nicht lösen. Zum Beispiel eine singuläre Matrix zu invertieren. Oder wenn externe Daten angefordert werden müssen, die nicht vorhanden sind (z.B. Dateizugriff). Dann muss dem Aufrufer auf eine Weise mitgeteilt werden, dass er kein erwartetes Resultat erhält. Wobei es je nach Situation auch angebracht sein kann, Assertions zu verwenden, da es sich bei falschen Argumenten um Programmierfehler handelt.
Miness schrieb:
Ausser man prüft innerhalb der Funktion dann auch, unter welchen Bedingungen "success" zurückgegeben wird. Oder?
Ja, genau so.
-
Miness schrieb:
Okay, alles klar! Wieder etwas dazugelernt.

Aber eine Funktion sollte ja eigentlich immer funktionieren, sonst würde der Compiler das ja bemerken und eine Fehlermeldung ausgeben. Ausser man prüft innerhalb der Funktion dann auch, unter welchen Bedingungen "success" zurückgegeben wird. Oder?Bei meinem Beispiel würde false zurückgegeben werden, wenn:
a) Die Lat/Lon-Werte nicht gültig wären
b) Das Mappen auf Bildschirmkoordinaten nicht möglich ist, zum Beispiel weil der Punkt auf der anderen Seite des Planeten liegt.Ein Fall für Exceptions wäre da zB wenn der Algorithmus noch gar nicht angesprochen werden kann, weil er nicht initialisiert wurde oder keine gültigen Daten vorliegen etc. Also alles was wirklich Ausnahmen (Exceptions) sein sollten.
-
Okay, noch einmal danke für eure Ausführungen!
Jetzt weiss ich auch, für was Funktionen sonst noch verwendet werden können.
-
Zu dem Return gibt es schon einen Thread, vielleicht ist etwas für dich dabei:
http://www.c-plusplus.net/forum/viewtopic-var-p-is-1855253-and-highlight-is-.html#1855253