Auswertungen in Umgebungen in C++ (Auswertungen in Umgebungen in C++), Auswertungen in Umgebungen in C++, Seite 721241
https://www.purl.org/stefan_ram/pub/auswertungen_c++_de (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
C++-Kurs

Lesen

Eine Lesefunktion

 .----------------------.
| Umgebung |
| |
| |
| |
| |
'----------------------'
Schreiben ^ |
| |
| v Lesen
.----------------------.
| Auswertung |
| |
| |
| |
| |
'----------------------'

Tip zum schnellen Lernen Versuchen Sie jetzt nicht, zu verstehen, was die »0« in »::std::perror( 0 )« bedeutet. Dies ist derzeit noch nicht wichtig! Vorläufig reicht es sich zu merken, daß bis auf weiteres als Argument immer »0« verwendet werden muß.

Die Auswertung von »::std::perror( 0 )« gibt den letzten zur Laufzeit aufgetretenen Fehler aus. Die Auswertung von »::std::ftell( 0 )« soll in dem folgenden Program einen Laufzeitfehler hervorrufen. (Also einen Fehler, der erst beim Ablauf der Programmes begangen wird.)

#include <cstdio>

int main()
{ ::std::perror( 0 );
::std::perror( 0 );
::std::perror( 0 );
::std::ftell( 0 );
::std::perror( 0 );
::std::perror( 0 );
::std::perror( 0 ); }

(Falls hier nach »::std::ftell( 0 )« kein Fehler gemeldet wird, könnten anderen Zahlen an Stelle von »0« in »::std::ftell( 0 )« probiert werden.)

Bei der Auswertung von »::std::perror( 0 )« wird ein Information über einen Fehler gelesen, die zuvor bei der Auswertung von »::std::ftell( stdin )« in den Speicher geschrieben wurde. Wir können sagen, daß diese beiden Auswertungen über einen Zustand kommunizieren.

Kommunikation über die Umgebung (den Speicher)
        ::std::ftell   .-----------------.        ::std::perror  .-----------------.    
---------------------->| Speicher |---------------------->| Ausgabeflaeche |
Schreiben '-----------------' Lesen Schreiben '-----------------'

»::std::ftell« ist eine Funktion, die in den Speicher schreibt.

»::std::perror« ist eine Funktion, die aus dem Speicher liest und auf die Ausgabefläche schreibt.

Eine Leseauswertung  ist eine Auswertung, die etwas einliest und deren Verhalten dann von dem Eingelesenen abhängt (wie beispielsweise eine Auswertung des Ausdrucks »::std::perror( 0 )«).

Laufzeitwerte ⃗

Man nennt Werte, die erst bei der Ausführung des Programms ermittelt werden, Laufzeitwerte. Das bedeutet, daß nicht schon der Aufrufausdruck  den Wert festlegt, sondern erst der Aufrufvorgang. (Dies wurde zuvor schon als „Nicht-Determinismus“ und „Messung“ behandelt.) Derselbe  Aufrufausdruck kann bei zwei verschiedenen Aufrufvorgängen  (wie oben), also zur Laufzeit, zwei verschiedenen Werte  haben. Der Aufrufausdruck steht im Quelltext für den Laufzeitwert, der sich bei jeweils einem Aufrufvorgang ergibt.

Der Aufrufausdruck »::std::time( null )« steht immer für dieselbe Operation, aber diese Operation kann bei verschiedenen Ausführungen, verschiedene Werte  für den Aufrufausdruck liefern. Durch eine Aufrufausdruck kann also ein Laufzeitwert angegeben werden, während ein Literal immer denselben Wert hat.

Im Grunde sind alle  Werte in C++  Laufzeitwerte, aber einige dieser Laufzeitwerte sind dann doch schon durch den Quelltext festgelegt, wie beispielsweise die Werte von Literalen, weil bei ihnen jede Auswertung zum selben Wert führt.

Wirkfunktion »::std::srand«

Der Aufruf von »::std::srand« stellt den Zufallszahlengenerator auf einen Ausgangswert ein, der durch den Argumentwert des Aufrufs festgelegt wird. Dieser Wert bestimmt dann die nächsten Zufallszahlen, welche »::std::rand« liefert. So kann verhindert werden, daß bei Programmstart immer dieselben Zahlen erscheinen.

Wir sehen hier das wichtige Prinzip, daß es einen von mehreren Funktionen geteilten Zustand gibt, auf den von außen nicht direkt zugegriffen werden kann. Wir haben eine Wirkfunktion, welche die Veränderung dieses Zustandes erlaubt und eine Wertfunktion (Meßfunktion), deren Verhalten von diesem Zustand beeinflußt wird.

»::std::srand« (vereinfachte und übersetzte Dokumentation)

#include <cstdlib>

void ::std::srand( int a );

Der Aufruf von »::std::srand« stellt den Zufallszahlengenerator auf den Ausgangswert »a« ein.
?    »::std::srand«
Die folgenden beiden Fragen sollen an Hand der oben abgedruckten Dokumentation beantwortet werden.
Ergibt die Auswertung des Ausdrucks »::std::srand( 0 )« einen Wert?
Hat die Auswertung des Ausdrucks »::std::srand( 0 )« eine Wirkung?
/    »::std::srand«
Schreiben Sie ein Programm, in dem ein Wert des Ausdrucks »::std::rand()« ausgegeben wird.
Welcher Wert wird ausgegeben, wenn »::std::srand( 10 )« direkt vor der Ausgabe von »::std::rand()« ausgewertet wird?
Welcher Wert wird ausgegeben, wenn »::std::srand( 1 )« direkt vor der Ausgabe von »::std::rand()« ausgewertet wird?

.----------------------------------------------------------------------------------------.
| Welt |
| (Speicher, Uhr) |
| |
| |
| |
'----------------------------------------------------------------------------------------'
^ ^ ^
| | |
| v v
.----------------------. .----------------------. .----------------------.
| Auswertung von | | Auswertung von | | Auswertung von |
| ::std::srand( 10 ) | | ::std::rand() | | ::std::rand() |
| | | | | |
| | | | | |
| | | | | |
'----------------------' '----------------------' '----------------------'

Zeit --->

Informationsübertragung

Wir haben jetzt insgesamt zwei Wege kennengelernt, auf denen Informationen  von einem Aufruf zu einem anderen übertragen  werden können:

Die Wertverbindung findet man auch in der Mathematik. Die Wirkverbindung wird in der Mathematik selten verwendet.

Wertfunktion »::std::time«

Der Aufruf von »::std::time« liefert eine Zahl, die sich im Laufe der Zeit verändert. Meist wird jede Sekunde um 1 hochgezählt.

»::std::time« (vereinfachte und übersetzte Dokumentation)

#include <ctime>

int ::std::time( int );

Ergibt eine Zahl, die sich im Laufe der Zeit verändert. Muß immer mit dem Argumentausdruck »nullptr« aufgerufen werden (vereinfacht gesagt).
?    Übungsfragen zu »::std::time«
Ergibt die Auswertung des Ausdrucks »::std::time( nullptr )« einen Wert?
Hat die Auswertung des Ausdrucks »::std::time( nullptr )« eine Wirkung?

Tip zum schnellen Lernen Versuchen Sie jetzt nicht, zu verstehen, was »nullptr« in »::std::time( nullptr )« bedeutet. Dies ist derzeit noch nicht wichtig! Vorläufig reicht es sich zu merken, daß bis auf weiteres als Argument immer »nullptr« verwendet werden muß.

time.cpp

#include <iostream>
#include <ostream>
#include <ctime>
#include <string> // ""s

using namespace ::std::literals;

int main()
{ ::std::cout << ::std::time( nullptr )<< "\n"s;
::std::cout << ::std::time( nullptr )<< "\n"s; }

/    Zufallszahlen verbessern
Kombinieren Sie den Ausdruck »::std::time( nullptr )« mit der Wirkfunktion »::std::srand«, um zu erreichen, daß der Pseudozufallszahlengenerator durch die Uhrzeit beim Start des Programmes beeinflußt wird.
Geben Sie danach einige Zufallszahlen, die durch eine Aufruf von »::std::rand« erhalten wurden, aus, um den Effekt sichtbar zu machen. In »::std::time( nullptr )« sollte »nullptr« so belassen und nicht durch etwas anderes ersetzt werden!
»::std::time« (vereinfachte und übersetzte Dokumentation)

#include <ctime>

int ::std::time( int );

Ergibt eine Zahl, die sich im Laufe der Zeit verändert.
»::std::srand« (vereinfachte und übersetzte Dokumentation)

#include <cstdlib>

void ::std::srand( int a );

Der Aufruf von »::std::srand« stellt den Zufallszahlengenerator auf den Ausgangswert »a« ein.
Dokumentation von »::std::rand()« (gekürzt und überarbeitet)

#include <cstdlib>

int rand();

Ergibt eine Pseudo-Zufallszahl zwischen »0« (einschließlich) und »RAND_MAX« (einschließlich)

Es ist typisch für C++  und für das Programmieren insgesamt, daß man keine  fertige Funktion für unvorhersehbare Zufallszahlen erhält, sondern diese sich aus einzelnen Bausteinen selber zusammensetzen muß. Würde es nämlich für alle vorstellbaren Zwecke bereits fertige Funktionen geben, dann wären dies so viele  Funktionen, daß man die Übersicht verlieren würde.

Programmieren heißt, ein Ziel durch Zusammenfügen vorhandener Grundelemente zu erreichen.

Übungsfragen

?    = Wertebereich
Bei den folgenden beiden Übungsfragen wird die Verwendung der Präprozessor-Direktive »#include <cstdlib>« vorausgesetzt.
Obwohl der Wert des Aufrufs »::std::rand()« oben immer als 41 angenommen wurde, könnte er gemäß der C++ -Norm auch irgendein anderer Wert zwischen 0 und RAND_MAX sein. Solch eine Unbestimmtheit des genauen Wertes kommt öfter vor. Deswegen ist es hilfreich, zur Übung im Umgang mit ihr die folgenden Fragen  zu beantworten:
In welchem Bereich liegt der Wert des Ausdrucks »::std::rand()/10«?
In welchem Bereich liegt der Wert des Ausdrucks »::std::rand() - 10«?
In welchem Bereich liegt der Wert des Ausdrucks »::std::rand() / RAND_MAX«?
In welchem Bereich liegt der Wert des Ausdrucks »::std::rand()/( 1. * RAND_MAX )«?

Zusatzfragen

?    = Wertebereich
In welchem Bereich liegt der Wert des Ausdrucks »::std::rand()/( 1. + RAND_MAX )«?
In welchem Bereich liegt der Wert des Ausdrucks »::std::rand()/( 1. + RAND_MAX )* 10«?

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram721241 stefan_ram:721241 Auswertungen in Umgebungen in C++ Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd721241, slrprddef721241, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/auswertungen_c++_de