Wirkfunktionen mit Parametern in C++
Eine Konstante kann auch einen Wert bezeichnen, der bei einem Funktionsaufruf als Argument angegeben wurde.
In den runden Klammern einer Funktionsdefinition kann eine Parameterdeklaration stehen, die einer Konstantendefinition ohne Angabe des Wertes ähnelt. Der Wert der Konstante wird nämlich durch den Wert des Arguments beim Aufruf der Funktion angegeben.
constparameter.cpp
#include <iostream>
#include <ostream>
void ausgeben( int const n )
{ ::std::cout << n << '\n'; }
int main(){ ausgeben( 7 ); }std::cout
7
Die Übergabe eines Wertes an einen Konstantenparameter beim Funktionsaufruf wird Kopier-Initialisierung genannt und entspricht der Definition einer Konstanten mit 〈type-specifier 〉 "const" 〈declarator 〉 "=" 〈assignment-expression 〉, im Falle des Programms "constparameter.cpp" also wie bei "int const n = 7".
constparameter1.cpp
#include <iostream>
#include <ostream>
void ausgeben( int const n ){ ::std::cout << n << '\n'; }
int main(){ ausgeben( 7 ); ausgeben( 3 ); }std::cout
7
3
Eine Konstantenbezeichner bezeichnet während der Lebenszeit der Konstante immer den gleichen Wert. Dadurch ist es aber nicht ausgeschlossen, daß während einer anderen Lebenszeit der gleiche Bezeichner einen anderen Wert bezeichnet. In dem Programm "constparameter1.cpp" wird die Funktion "ausgeben" zweimal aufgerufen. Dadurch entstehen hintereinander zwei Inkarnationen der Funktion "ausgeben". Zu jeder Inkarnation gehört ein „Leben“ der Konstante. Während des ersten Lebens ist sie 7, während des zweiten Lebens ist sie 3. Während jedes Lebens ist sie konstant.
Mehrfache Uebergabe eines Arguments
|Zeit main
| .----------------.
| | |
| | |
| | ausgeben( 7 ) | void ausgeben
| | | .-------------------------------.
| | | | ( int const | Erstes
| | '-----> n ) | Exemplar
| | | { ::std::cout << n << '\n'; } | der Funktion
| | | | | "ausgeben"
| | '-------------|-----------------'
| | | V
| | | 7
| | |
| | |
| | ausgeben( 3 ) | void ausgeben
| | | .-------------------------------.
| | | | ( int const | Zweites
| | '-----> n ) | Exemplar
| | | { ::std::cout << n << '\n'; } | der Funktion
| | | | | "ausgeben"
| | '-------------|-----------------'
| | | V
| | | 3
| | |
V '----------------'
Mehrfache Exemplare eine Funktion sind ein Beispiel für die Möglichkeit der Erzeugung mehrerer Laufzeitexemplare durch ein einziges Stück Quelltext. Dadurch ist es möglich, beim Programmieren Arbeit zu sparen, da nicht alles, was mehrfach passiert soll, genauso oft auch im Programmtext stehen muß. Hier wird beispielsweise die Funktionsdefinition mehrfach verwendet, um verschiedene Werte auszugeben, obwohl sie nur einmal im Quelltext vorkommt.
Das Geschehen kann mit zwei aufeinanderfolgenden Blöcken verglichen werden, in denen jeweils eine Konstante "n" definiert wird. (Tatsächlich ist eine Funktionsdefinition ja auch die Benennung eines Blocks.) Die Lebenszeit der ersten Konstanten "n" mit dem Wert "7" endet bevor die Lebenszeit der zweiten Konstanten "n" mit dem Wert "3" beginnt. Da die Lebenszeiten und Gültigkeitsbereiche sich nicht überlappen entsteht kein Konflikt.
constexample.cpp
#include <iostream>
#include <ostream>
int main()
{ { int const n = 7; { ::std::cout << n << '\n'; }}
{ int const n = 3; { ::std::cout << n << '\n'; }}}std::cout
7
3
Mehrere Parameter
Eine Funktion kann auch mehrere Parameterdeklarationen haben, die dann durch ein Komma voneinander getrennt werden.
multiparameter.cpp
#include <iostream>
#include <ostream>
void doppelausgabe( const int a, const int b )
{ ::std::cout << a << ", " << b << '\n'; }
int main()
{ doppelausgabe( 4, 9 ); }std::cout
4, 9
Produktionen
Die für die Funktionsdefinition relevanten Produktionen von C++ lauten vereinfacht folgendermaßen.
- 〈function-definition 〉 ::=
- 〈type-specifier 〉〈declarator 〉〈function-body 〉.
- 〈function-body 〉 ::=
- 〈compound-statement 〉.
Die Funktionsdefinition "double kelvin( double const celsius ){ return celsius + 273.15; }" besteht also aus dem Typspezifikator "double", dem Deklarator "kelvin( double const celsius )" und dem Funktionsrumpf "{ return celsius + 273.15; }", letzterer ist eine Verbundanweisung.
Der Deklarator einer Funktionsdefinition hat oft die Form der folgenden vereinfachten Produktion.
- 〈direct-declarator 〉 ::=
- 〈direct-declarator 〉 "(" 〈parameter-declaration-clause 〉 ")".
Und der Parameterdeklarationsabschnitt 〈parameter-declaration-clause 〉 hat oft die Form einer Parameterdeklarationsliste 〈parameter-declaration-list 〉.
- 〈parameter-declaration-list 〉 ::=
- [〈parameter-declaration-list 〉 ","] 〈parameter-declaration 〉.
Aufgaben zu Parametern
Schreiben Sie eine Wirkfunktion "schreibzahl", die eine als Argument beim Aufruf angegebene Zahl ausgibt!
Schreiben Sie eine Wirkfunktion "summe", die die Summe der beiden als Argument angegebenen Zahlen ausgibt!
Verkürzung
Schreiben Sie ein möglichst kurzes Programm, das genau die folgende Ausgabe erzeugt.
Ausgabe
11910
11910 32251
11910
23141
23141 32251
23141
10312
10312 32251
10312
24170
24170 32251
24170
17233
17233 32251
17233
24947
24947 32251
24947
In der Lösung darf jedes Numeral im Programmtext (Quellcode) nur einmal vorkommen! Die Schreibweise und Formatierung der Ausgabe muß mit dem folgenden Muster exakt übereinstimmen. Versuchen Sie, eine sich wiederholende Struktur in der Ausgabe als eine Wirkfunktion zu definieren.
Wenn die Lösung nicht gleich gelingt, dann verringern Sie vorübergehend die Anforderungen und schreiben Sie erst einmal ein Programm, daß z.B. nur einen Teil der Ausgabe erzeugt, aber noch Wiederholungen enthält oder die Ausgabe nicht ganz genau so wie vorgegeben erzeugt. Versuchen Sie Ihr Programm dann in kleinen Schritten zu verbessern, bis es den Anforderungen der Aufgabenstellung möglichst nahekommt.
Ein möglicher Weg zu Lösung könnte folgendermaßen beginnen.
1.) Ein Programm schreiben, das alle Zeilen so ausgibt, wie sie aufgelistet werden.
2.) Dieses Programm schrittweise umstrukturieren, bis jedes Numeral nur noch einmal vorkommt.
- Würfel
- Schreiben Sie eine Wertmethode "wuerfel", die eine ganzzahlige Pseudozufallszahl ergibt, die größergleich 1 und kleinergleich dem Wert ihres ganzzahligen Parameters ist. (Die Methode soll sich für Parameterwerte zwischen 1 und 32768 so verhalten.) So soll der Wert von "wuerfel( 6 )" beispielsweise eine ganzzahlige Pseudozufallszahl zwischen 1 und 6 sein.