Der Ausgabeoperator in C++
Ausgabeanweisungen
main.cpp
#include <cstdio> /* ::std::putchar */
#include <iostream> /* ::std::cout */
#include <ostream> /* << */using namespace ::std::literals;
int main()
{ ::std::cout << ::std::putchar( 86 )<< "\n"s; }Protokoll
V86
Beispiele
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> // ""susing namespace ::std::literals;
int main(){
::std::cout << 86;
::std::cout << "\n"s;}
::std::cout
86
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> // ""susing namespace ::std::literals;
int main()
{( ::std::cout << 86 ) /* hat wieder den Wert ::std::cout */
<< "\n"s;}
::std::cout
86
Operationssequenz
- ::std::cout << 86 → Ausgabe von 86 → ::std::cout
- ::std::cout << "\n"s → Ausgabe eines Zeilenendes → ::std::cout
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> // ""susing namespace ::std::literals;
int main(){ ::std::cout << 86 << "\n"s; }
::std::cout
86
- Operationssequenz
- ::std::cout << 86 → Ausgabe von 86 → ::std::cout
- ::std::cout << "\n"s → Ausgabe eines Zeilenendes → ::std::cout
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> // ""susing namespace ::std::literals;
int main(){ ::std::cout << 86 << 87 << "\n"s; }
::std::cout
8687
- Operationssequenz
- ::std::cout << 86 → Ausgabe von 86 → ::std::cout
- ::std::cout << 87 → Ausgabe von 87 → ::std::cout
- ::std::cout << "\n"s → Ausgabe eines Zeilenendes → ::std::cout
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> // ""susing namespace ::std::literals;
int main(){ ::std::cout << 86 << "\n"s << 87 << "\n"s; }
::std::cout
86
87- Operationssequenz
- ::std::cout << 86 → Ausgabe von 86 → ::std::cout
- ::std::cout << "\n"s → Ausgabe eines Zeilenendes → ::std::cout
- ::std::cout << 87 → Ausgabe von 87 → ::std::cout
- ::std::cout << "\n"s → Ausgabe eines Zeilenendes → ::std::cout
Ausgabeanweisungen als Auswertungsanweisungen
Bisher hatten wir Ausgabeanweisungen als eine spezielle Form von Anweisungen vorgestellt. Jetzt können wir erkennen, daß sie normale Auswertungsanweisungen sind.
- Die Ausgabeanweisung als Ausgabeanweisung
::std::cout << 86 ;
'---------- Ausdruck ----------' '----- Semikolon -----'
'----------------------------- Auswertungsanweisung -----------------------------'
Ausgabeanweisungen sind normale Auswertungsanweisungen.
Eine Auswertungsanweisung, deren Ausdruck eine Ausgabe bewirkt, kann aber auch weiterhin Ausgabeanweisung genannt werden.
Aufrufklammern als Wirkoperatoren *
Das folgende Programm läuft ohne Abbruch ab:
main.cpp
#include <cstdlib> /* ::std::abort */
int main(){ ::std::abort; }
Das folgende Programm wird abgebrochen:
main.cpp
#include <cstdlib> /* ::std::abort */
int main(){ ::std::abort(); }
Der Abbruch, also die Wirkung, wird also durch die Klammern verursacht, nicht durch den Funktionsnamen. Die Klammern sind also ebenfalls Wirkoperatoren.
Die Klammern eines Aufrufs nennen wir auch Aufrufklammern. Sie können ebenfalls als ein Operator angesehen werden, nämlich als ein unärer Postfixoperator (er steht hinter seinem einzigen Operanden, daher wird ein Aufruf in C++ auch als Postfix-Ausdruck bezeichnet.)
Daher nennen wir die Aufrufklammern auch Aufrufoperator. Die Aufrufklammern sind nicht zu verwechseln mit den Ausdruckklammern, welche nicht hinter ihrem Operanden stehen sondern diesen als unärer Zirkumfixoperator umgeben.
„Rückgabe“ und „Ausgabe“
Anfänger verwechseln gerne noch die Begriffe „Rückgabe “ und „Ausgabe “. In der folgenden Beispielprogrammausführung geschieht auch beides gemeinsam, so daß es wirklich nicht einfach ist, dies auseinanderzuhalten.
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <cstdlib> /* ::std::rand */
#include <string> // ""susing namespace ::std::literals;
int main()
{ ::std::cout << ::std::rand() << "\n"s; }::std::cout
41
Der Unterschied ist jedoch folgender: Der Wert 41 wird in der obigen Ausführung zuerst von der Operation/Funktion »::std::rand()« zurückgegeben. Dann wird er von dem Ausgabeanweisungsrahmen »::std::cout << … << "\n"s;« ausgegeben (beispielsweise auf einen Bildschirm oder Drucker). Ein bloß zurückgegebener Wert ist aber im allgemeinen nicht von außen sichtbar, weil die Rückgabe eines Wertes ein programminterner Vorgang ist, welcher keine Außenwirkung entfaltet. Die Rückgabe besteht ja darin, daß ein Wert für eine Auswertung eines Ausdrucks festgelegt wird, der Wert wird damit aber nicht ausgegeben. Die Ausgabe erfolgt nur, wenn dieser Aufrufausdruck in einem Ausgabeanweisungsrahmen steht. Die Ausgabe ist die Sichtbarmachung, Zugänglichmachung oder das Abspielen eines Textes, Bildes, Klangs oder einer anderen Form der Informationswiedergabe durch das Programm.
Das folgende Beispielprogramm zeigt, was passiert, wenn man den Aufrufausdruck »::std::rand()« statt dessen in eine Aufrufanweisung schreibt: Dann wird der Wert zwar zurückgegeben, aber nicht ausgegeben – er geht verloren!
main.cpp
#include <cstdlib> /* ::std::rand */
int main(){ ::std::rand(); }
::std::cout
- (keine Ausgabe)
Das folgende Beispielprogramm zeigt nun den umkehrten Fall: Der Wert 1 wird zwar ausgegeben, aber nicht zurückgegeben.
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> // ""susing namespace ::std::literals;
int main(){ ::std::cout << 1 << "\n"s; }
::std::cout
1
Bei einem Literal, wie dem Literal »1«, spricht man nämlich nicht davon, daß diese ihren Wert „zurückgeben“. Ein Literal hat seinen Wert. Im obigen Beispiel hat das Literal »1« den Wert 1, welcher dann ausgegeben, aber nicht zurückgegeben wird. Zurückgegeben werden kann ein Wert ja nur von etwas, das vorher auch aufgerufen wurde. Ein Literal ist aber kein Aufrufausdruck.
Hinweis zur Ausgabe
- mangelhaftes Programm
#include <iostream> /* ::std::cout */
#include <ostream> /* << */int main(){ ::std::cout << 86; }
::std::cout
86
Das obenstehende Programm ist mangelhaft, da jede Textausgabe mit einem Zeilenende »"\n"s« abgeschlossen werden sollte. Trotzdem kann die Ausgabe „86“ meist noch gelesen werden, was aber wegen dieses Mangels nicht mehr von der Programmiersprache garantiert wird.
Häufiger Fehler Oft wird angenommen, daß eine Ausgabe „durch cout erfolgt“ oder gar, daß »::std::cout« ein „Ausgabebefehl“ sei. Erstens gibt es in C++ gar keine „Befehle“ und zweitens gibt »::std::cout« nur an, wohin ausgegeben werden soll, dafür daß etwas ausgegeben wird ist der Operator << verantwortlich. Richtig ist: "<<" ist in gewissen Fällen ein Ausgabeoperator, und man kann – wenn man will – »::std::cout << 86« als einen „Ausgabeausdruck“ und »::std::cout << 86;« als eine „Ausgabeanweisung“ bezeichnen.
Übungsaufgaben
- / Ausgabe eines Zeichen ohne Verwendung des Resultats
- Schreiben Sie ein C++ -Programm, mit einer Auswertungsanweisung, in welcher der Ausdruck »::std::putchar( 86 )« nur wegen seiner Wirkung ausgewertet wird, während sein Wert nicht verwendet wird.
- / Ausgabe eines Zeichen mit Verwendung des Resultats
- Ergänzen Sie das Programm der vorigen Aufgabe um eine weitere Auswertungsanweisung, mit welcher der Ausdruck »::std::putchar( 86 )« ausgewertet wird und auch auch der Wert dieses Ausdrucks ausgegeben wird.
- Dabei soll zur Ausgabe dieses Werts der Ausgabeoperator »<<« verwendet werden.
- Die neue Auswertungsanweisung soll hinter der Auswertungsanweisung aus der vorigen Übungsaufgabe eingefügt werden.
- / Ausgabe eines Zeilenendes
- Ergänzen Sie das Programm der vorigen Aufgabe um eine weitere Auswertungsanweisung, mit welcher ein Zeilenende ausgegeben wird.
- Die neue Auswertungsanweisung soll hinter der Auswertungsanweisung aus der vorigen Übungsaufgabe eingefügt werden.