Die Wertrückgabe in C++
Der Wert einer Funktion wird durch eine in der Funktion vorkommende Rückgabeanweisung festgelegt, die eine Art von Sprunganweisung 〈jump-statement 〉 ist.
- 〈jump-statement 〉 ::=
- "return" [〈expression 〉] ";".
Beispiel: Wie viele Tage haben 2 Wochen?
Das folgende Beispiel zeigt die Verwendung der Rückgabeanweisung in C++.
In der Definition der Funktion "Anzahl_der_Tage_einer_Woche" wird als Ergebnis der Wert des Ausdrucks "7" festgelegt. Der Datentyp "int" wird hier vor dem Funktionsnamen anstelle des bei Wirkfunktion üblichen Datentyps "void" angegeben, um festzulegen, daß das Ergebnis der Funktion vom Datentyp "int" ist.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
int main(){ ::std::cout << 2 * 7 << "\n"s; }
::std::cout
14
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
int Anzahl_der_Tage_einer_Woche(){ return 7; }
int main(){ ::std::cout << 2 * Anzahl_der_Tage_einer_Woche() << "\n"s; }
::std::cout
14
An Stelle des Rückgabetyps kann auch »auto« geschrieben werden, um diesen automatisch ermitteln zu lassen (seit C++14 ).
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
auto Anzahl_der_Tage_einer_Woche(){ return 7; }
int main(){ ::std::cout << 2 * Anzahl_der_Tage_einer_Woche() << "\n"s; }
::std::cout
14
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
int Anzahl_der_Tage_einer_Woche(){ return 7; }
int Anzahl_der_Tage_zweier_Wochen(){ return 2 * Anzahl_der_Tage_einer_Woche(); }
int main(){ ::std::cout << Anzahl_der_Tage_zweier_Wochen() << "\n"s; }
::std::cout
14
In klassischen C++ -Programmen werden Namen, die aus dem Englischen kommen, meist klein geschrieben. Wir haben »Anzahl_der_Tage_zweier_Wochen« hier abweichend in Anlehnung an die deutschen Regeln geschrieben.
Mit der Rückgabeanweisung wird auch die Kontrolle an den Aufrufer der Funktion zurückgegeben. Daher werden nachfolgende Anweisungen nicht mehr ausgeführt. Deswegen gilt die Rückgabe auch als Sprunganweisung.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
int f()
{ ::std::cout << "A\n"s;
return 7;
::std::cout << "B\n"s; }int main(){ ::std::cout << f() << "\n"s; }
::std::cout
A
7
Wertfunktionen als eine Art von Abkürzung
Das »auto« legt den Typ des return-Ausdrucks als Typ des Aufrufs fest.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
auto LKW(){ return "Lastkraftwagen"s; }
int main()
{ ::std::cout << "Von links brausen Autos und "s <<
LKW() << " in Richtung Norden vorbei.\n"s; }::std::cout
Von links brausen Autos und Lastkraftwagen in Richtung Norden vorbei.
C -Zeichenfolgen
Wenn eine C -Zeichenfolge als Rückgabeausdruck für eine Funktion mit dem Rückgabetyp »::std::string« verwendet wird, wird sie zur Initialisierung des Rückgabewertes herangezogen und dadurch automatisch in eine C++ -Zeichenfolge vom Typ »::std::string« gewandelt.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
::std::string f(){ return "abc"; }
int main()
{ { ::std::string v = "abc"; /* Definition und Initialisierung */
::std::cout << v << "\n"s; }::std::cout << f() << "\n"s; }
Protokoll
abc
abc
Rückgaben mit einer Initialisierungsliste ⃗
Eine Initialisierungsliste ist eine Liste von Werten in geschweiften Klammern.
Hinter dem Schlüsselwort »return« kann auch eine Initialisierungsliste stehen.
Eine Initialisierungsliste hinter »return« wird zur Initialisierung des Rückgabewertes wie bei einer Variablendefinition herangezogen.
Bei Verwendung eines der Typen wie »int« oder »double« als Rückgabetyp, verbietet die Initialisierungsliste also eine Typeinengung.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
int f(){ return { 2 }; } /* OK */
int g(){ return { 2.1 }; } /* error */
int main()
{ }transcript
main.cpp: In function 'int g()':
main.cpp:9:23: error: narrowing conversion of '2.1000000000000001e+0' from 'double' to 'int' inside { } [-Wnarrowing]
int g(){ return { 2.1 }; }
^
Beim Typ »::std::string« werden die Werte der Initialisierungsliste als Kennzahlen der Zeichen der Zeichenfolge interpretiert.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
::std::string f(){ return { 65, 66, 67 }; }
int main()
{ { ::std::string v{ 65, 66, 67 }; /* Definition und Initialisierung */
::std::cout << v << "\n"s; }::std::cout << f() << "\n"s; }
Protokoll
ABC
ABC
Übungsfragen
Übungsfrage 0
- Was ist die Ausgabe des folgenden Programms?
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
int f(){ return 4; }
int g(){ return f() + f() + 2; }
int main(){ ::std::cout << g() << "\n"s; }
Übungsfrage 1
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
int f()
{ ::std::cout << "A"s;
return 7; }int main(){ ::std::cout << f(); f(); ::std::cout << "\n"s; }
Protokoll
A7A
- Welchen Wert ergibt die Auswertung des Ausdrucks »f()«, wenn »f« so definiert ist, wie in dem obigen Programm?
- Welche Wirkung hat die Auswertung des Ausdrucks »f()«, wenn »f« so definiert ist, wie in dem obigen Programm?
- Warum lautet die Ausgaben »A7A« und nicht »A7A7«, obwohl »f()« zweimal aufgerufen wurde? Wo ist die zweite »7« geblieben?
Übungsaufgaben
Eine konstante Funktion
Schreiben Sie eine Definition einer Wertfunktion »f«, so daß ein Aufrufausdruck »f()« den Typ »double« und den Wert »7.2« hat. Geben Sie dann das Zehnfache des Wertes eines Aufrufs von »f« aus.
(Eine Wertfunktion ist eine Funktion, deren Aufruf einen Wert hat.)
Zusatzaufgaben
- ? Würfel
- Schreiben Sie eine Wertfunktion »wuerfel«, die eine ganzzahlige Pseudozufallszahl ergibt, die größer-gleich 1 und kleiner-gleich 6 ist.