Kombinationen von Operationen in C++
Kombinationen durch Anweisungsfolgen
Operationen können in C++ durch zeitliche Hintereinandersausführung kombiniert werden, in dem ein Folge von Ausdruckanweisungen geschrieben wird:
hallo.cpp#include <cstdio> // ::std::printf int main(){ ::std::printf( "Hal" ); ::std::printf( "lo!\n" ); }::std::coutHallo!
Dabei kann die zweite Operation auf den Vorzustand (hier »Hal«) aufbauen, der von der ersten Operation hinterlassen wurde.
- Kombination durch Anweisungsfolgen [Kompassdiagramm]
.------------------------------------------------------------------------>
| Werte
|
|
| leere Zeile (vorausgesetzter Vorzustand)
| |
| |
| V Messung
| .---------------.
| | ::std::printf |
| "Hal" ----------> | ( "Hal" ) |----------> 3 ----------> ;
| zeichenfolge | | Ergebnis
| '---------------'
| | Wirkung
| |
| |
| V
| "Hal" (Zwischenzustand)
| |
| |
| V Messung
| .---------------.
| | ::std::printf |
| "lo!\n" ---------> | ( "lo!\n" ); |----------> 4 ----------> ;
| zeichenfolge | | Ergebnis
| '---------------'
| | Wirkung
| |
| |
| V
| Zeile "Hallo!" (Endzustand)
|
|
|
|Zeit
V
Zur graphischen Darstellung des Geschehens wurde ein Kompaßdiagramm verwendet, bei dem Operation durch ein Kästchen veranschaulicht werden. Im Kompaßdiagramm gibt es eine zeitliche Achse in der Richtung vom Vorzustand zum Nachzustand und eine Wertachse in der Richtung von den Argumentwerten zum Wert des Resultats. Der Wert des Resultats und der Nachzustand einer Aktivierung einer Operation wird zusammenfassend auch als Verhalten dieser Aktivierung bezeichnet. Dieses Verhalten wird durch die Umstände der Aktivierung (also die Argumentwerte und den Vorzustand der Laufzeitumgebung) und natürlich durch die gewählte Operation bestimmt.
- Aktivierung einer parametrisierten Operation [Kompassdiagramm]
.------------------------------------------------------------------------->
| Werte
|
|
| Umstände --> Vorzustand/Umgebung
| | |
| v |
| V Messung
| .-----------------.
| | parametrisierte |
| Argumentwerte ----------> | Operation |----------> Wert
| Parameter | | Resultat
| '-----------------'
| | Wirkung
| |
| | ^
| V |
| Nachzustand <-- Verhalten
|
|
|Zeit
V
Nicht jede Funktion nutzt jede der Möglichkeiten, die durch die Pfeile angedeutet sind. Wenn eine Funktion eine dieser Möglichkeiten nutzt, so läßt sie sich entsprechend bezeichnen:
Das Verhalten einer Meßoperation wird durch den Vorzustand der Laufzeitumgebung beeinflußt. So hängt der Wert der Operation »::std::getchar« vom eingegebenen Zeichen ab.
Eine parametrisierte Operation ergibt erst durch bestimmte Argumentwerte eine bestimmte Operation. So bezeichnet »::std::putchar« eine parametrisierte Operation, während »::std::putchar( 'A' )« eine bestimmte Operation bezeichnet. Im allgemeinen stehen C++ -Funktionen für parametrisierte Operationen.
Bei einer Wertoperation steht der Ausdruck in Standardnotation (beispielsweise der Ausdruck »::std::getchar()«) für einen Wert (hier ist der Wert das eingegebene Zeichen). (In der Programmiersprache Pascal werden nur Wertoperationen als „Funktion“ bezeichnet, Operationen ohne Wert heißen dort „Prozeduren“.)
Die Aktivierung einer Wirkoperation verändert den Zustand der Laufzeitumgebung in spezifizierter Weise. Beispielsweise führt die Aktivierung der Operation »::std::putchar( 'A' )« zur Ausgabe des Zeichens »A«.
Eine Funktion im mathematischen Sinne ist eine Wertoperation ohne spezifizierte Wirkung, deren Resultat nur von den Argumentwerten, aber nicht vom Zustand der Umgebung während ihrer Berechnung abhängt. C++ hat den Begriff „Funktion“ aus der Programmiersprache C übernommen. C hat den Begriff „Funktion“ wahrscheinlich aus der Mathematik übernommen, da die Standardnotation für die Anwendung von Funktionen aus der Mathematik stammt. (Man darf aber beide Begriffe nicht direkt einander gleichsetzen: Wenn man einen C++ -Funktionsausdruck wie in der Mathematik interpretiert, dann ist eine C++ -Funktion keine Funktion im mathematischen Sinne. Allerdings läßt sich eine C++ -Funktion doch so interpretieren, daß sie eine Kombination zweier mathematischer Funktionen ist: Einmal wird den Argumentwerten eindeutig eine bestimmte Operation zugeordnet, dann ordnet diese Operation einem Vorzustand eindeutig einem Nachzustand zu.)
Kombinationen durch Argumente
Zwei Operationen lassen sich auch durch Verwendung des Resultatwerts der einen Operation als Argumentwert der anderen Operation kombinieren.
hallo.cpp#include <cstdio> // ::std::printf int main(){ ::std::putchar( ::std::getchar() ); }- ::std::putchar( ::std::getchar() ) [Kompassdiagramm]
.------------------------------------------------------------------------>
| Werte
| Ein Zeichen
| wurde eingegeben.
| |
| V Messung
| .----------------. .----------------.
| | ::std::getchar | | ::std::putchar |
| | |---------------------------> | |
| | | Resultat Parameter | |
| '----------------' '----------------'
| | Wirkung
| |
| |
| V
| Das eingelesene Zeichen
| ist wieder ausgegeben.
|
|Zeit
V
Die Funktion "::std::rand"
Die Funktion "::std::rand" ergibt bei jedem Aufruf eine Zahl aus einer Folge ganzzahliger Pseudozufallszahlen aus dem Bereich von Null bis zum Wert "RAND_MAX".
::std::rand [Synopse]#include <cstdlib>
int ::std::rand();
Das folgende Kompaßdiagramm gibt an, daß das Ergebnis dieser Funktion lediglich vom Zustand eines internen Pseudozufallszahlengenerators abhängt. Gleichzeitig hat diese Funktion aber auch eine Wirkung. Jeder Aufruf verändert den Zustand des Generators, denn beim nächsten Aufruf soll ja wieder eine (im Allgemeinen) andere Pseudozufallszahl erscheinen.
::std::rand [Kompassdiagramm]Vorzustand des Generators
|
V Messung
.---------------------.
| ::std::rand | int
| |--------> Pseudozufallszahl
| | Ergebnis
'---------------------'
| Wirkung
V
Nachzustand des Generators
Der Wert "RAND_MAX" ist mindestens der Wert "32767".
RAND_MAX [Synopse]#include <cstdlib>
RAND_MAX
Das folgende Beispielprogramm gibt drei Pseudozufallszahlen aus.
rand.cpp#include <iostream>
#include <ostream>
#include <cstdlib>
int main()
{ ::std::cout << ::std::rand() << ", ";
::std::cout << ::std::rand() << ", ";
::std::cout << ::std::rand() << ".\n"; }::std::cout41, 18467, 6334.
Übungsaufgaben
- / RAND_MAX
- Geben Sie den Wert des Ausdrucks »RAND_MAX« und ein Zeilenende aus. Achten Sie auf die Verwendung der für »RAND_MAX« benötigten include-Direktive.
Variation
Ist Ihnen schon aufgefallen, daß immer die gleiche Folge von Zufallszahlen erscheint?
Die Wirkfunktion "::std::srand" (set random seed , Zufallskeim festlegen) stellt den Zustand (seed ) des Pseudozufallszahlengenerators je nach der als Argument angegebenen Zahl ein. Der Datentyp "unsigned int" umfaßt nichtnegative ganze Zahlen bis zu einer bestimmten Größe.
::std::srand [Synopse]#include <cstdlib>
void ::std::srand( unsigned int );
Das wird in dem folgenden Kompaßdiagramm dargestellt.
Einstellen des Generators [Kompassdiagramm].---------------------.
Einstellung | ::std::srand |
------------->| |
unsigned int | |
'---------------------'
| Nachzustand
V
Vorzustand des Generators
|
V Vorzustand
.---------------------.
| ::std::rand |
| |--------> Pseudozufallszahl
| | int
'---------------------'
| Nachzustand
V
Nachzustand des Generators- ? »::std::srand«
- Hat der Ausdruck »::std::srand( 0 )« einen Wert?
- Hat die Auswertung des Ausdrucks »::std::srand( 0 )« eine Wirkung?
- / »::std::srand«
- Schreiben Sie ein Programm, in dem der Ausdruck »::std::srand( 0 )« ausgewertet wird, bevor ein Wert des Ausdrucks »::std::rand()« ausgegeben wird. Ändert sich der ausgegebene Wert, wenn das Programm dann so geändert wird, daß »::std::srand( 0 )« nicht ausgewertet wird?
Machen Sie sich zunächst damit vertraut, wie durch Aufruf dieser Wirkfunktion die folgenden Pseudozufallszahlen beeinflußt werden können.
Um eine andere Folge von Zufallszahlen zu erhalten, muß jedoch weiterhin das Argument der Wirkfunktion "::std::srand" verändert werden. Dies kann aber automatisch erfolgen, wenn ihr als Argument ein von der aktuellen Zeit abhängiger Wert übergeben wird. Kombinieren Sie also nun die Meßfunktion "::std::time" mit der Wirkfunktion "::std::srand", um zu erreichen, daß der Pseudozufallszahlengenerator durch die Uhrzeit beim Start des Programmes beeinflußt wird.
Einstellen des Generators durch die Zeit [Kompassdiagramm]Zeit
|
V Messung unsigned
.---------------. int .---------------.
| ::std::time | ::std::time_t | ::std::srand |
| |------------------->| |
| | Zeit Einstellung | |
'---------------' '---------------'
| Nachzustand
V
Zustand des Generators
|
V Vorzustand
.---------------.
| ::std::rand |Zufallszahl
| |---------->
| |int
'---------------'
| Nachzustand
V
Zustand des Generators