Verschiedene Arten von Argumentausdrücken in Java (Verschiedene Arten von Argumentausdrücken in Java), Lektion, Seite 723704
https://www.purl.org/stefan_ram/pub/argumentarten_java (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
Java-Kurs

Verschiedene Arten von Argumentausdrücken in Java 

Operatorausdrücke  als Argumentausdrücke

Da ein Argumentausdruck ein ein im Prinzip beliebiger  Ausdruck sein kann, darf auch ein Operatorausdruck  (wie unten »2 + 3.5«) als Argumentausdruck verwendet werden. Der Argumentwert ist dann der Wert des verwendeten Operatorausdrucks.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.floor( 2 + 3.5 )); }}
transcript
5.0

Bei der Auswertung solch eines Aufrufs muß zuerst  der Operatorausdruck ausgewertet werden. Dieser hat in dem obigen Beispiel den Wert »5.5«. Dann wird die Inkarnation »java.lang.Math.floor( 5.5 )« hergestellt und ausgeführt; sie liefert schließlich das Ergebnis »5.0«.

Die Reihenfolge der Auswertung  ist hier also genau anders herum  als die Reihenfolge im Quelltext. Im Quelltext  steht (beim Lesen von links nach rechts) zuerst  »floor« und dann »+«. Ausgewertet  wird zuerst »+« und dann »floor«.

Operatorausdrücke als Argumentausdrücke  veranschaulichen noch einmal den Unterschied zwischen Argumentausdrücken  und Argumentwerten.

In den beiden folgenden Programmen ist der Argumentausdruck  einmal »5.5« und einmal »2 + 3.5«, der Argumtwert  ist aber in beiden Fällen derselben.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.floor( 5.5 )); }}
transcript
5.0
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.floor( 2 + 3.5 )); }}
transcript
5.0

Für das Ergebnis einer Auswertung eines Methodenaufrufs kommt es nur auf den Argumentwert  an, nicht auf den Argumentausdruck.

Das folgende Diagramm zeigt noch einmal die einzelnen Schritte der Auswertung von »java.lang.Math.floor( 2 + 3.5 )«.

Schritte bei der Auswertung von »java.lang.Math.floor( 2 + 3.5 )«

2 + 3.5

1.) | Operationsvorgang
v

5.5 Operationsprodukt

2.) | Inkarnationsvorgang
v (Einsetzen des Argumentwertes)

java.lang.Math.floor( 5.5 ) Inkarnationsprodukt

3.) | Operationsvorgang
v

5.0 Operationsprodukt

Ein Inkarnationsvorgang  ist das Einsetzen von Werten für Operanden (damit sind hier auch Argumente gemeint). Beispielsweise das Einsetzen des Wertes »5.5« für den Argumentausdruck »2 + 3.5«.

Ein Inkarnationsprodukt  ist das Ergebnis eines Inkarnationsvorganges, beispielsweise »java.lang.Math.floor( 5.5 )«. In einem Inkarnationsprodukt sind alle Operanden (einschließlich der Argumenten) Werte. Falls ein Methodenaufruf (wie beispielsweise »java.lang.Math.random()«) gar keine Ausdrücke enthält, so kann dieser bereits so wie er ist als Inkarnationsprodukt angesehen werden.

Falls nur von einer „Inkarnation “ gesprochen wird, so ist damit – je nach Zusammenhang – entweder der Vorgang  oder das Produkt  einer Inkarnation gemeint.

Ein Operationsvorgang  ist die Ausführung eines Inkarnationsproduktes, beispielsweise die Auswertung von »java.lang.Math.floor( 5.5 )«.

Ein Operationsprodukt  ist das Ergebnis eines Operationsvorgangs, beispielsweise der Wert »5« als Produkt der Auswertung von »java.lang.Math.floor( 5.5 )«.

Falls nur von einer „Operation “ gesprochen wird, so ist damit der Vorgang  einer Operation gemeint.

Falls die Inkarnation oder Operation zu einem Operator beziehungsweise einer Methode gehört, sprechen wir von einer Operatorinkarnation  oder Operatoroperation  beziehungsweise einer Methodeninkarnation  beziehungsweise einer Methodenoperation.

Namen  als Argumentausdrücke

Das folgende Beispiel zeigt, daß auch ein Name  (hier »java.lang.Math.PI«) als Argumentausdruck vorkommen kann. Der Argumentwert ist dann der Wert des verwendeten Namens.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.floor( java.lang.Math.PI )); }}
transcript
3.0

Das folgende Diagramm zeigt die einzelnen Schritte bei der Auswertung von »java.lang.Math.floor( java.lang.Math.PI )«.

Schritte bei der Auswertung von »java.lang.Math.floor( java.lang.Math.PI )«

java.lang.Math.PI

1.) | Vorgang des Auslesen
v des Wertes des Namens

3.141592653589793 Ausgelesener Wert

2.) | Inkarnationsvorgang
| (Einsetzen des
v Argumentwertes)

java.lang.Math.floor( 3.141592653589793 ) Inkarnationsprodukt

3.) | Operationsvorgang
v

3.0 Operationsprodukt

Aufrufausdrücke  als Argumentausdrücke

Das folgende Beispiel zeigt, daß auch ein Aufrufausdruck  (hier »java.lang.Math.random()«) als Argumentausdruck vorkommen kann. Der Argumentwert ist dann der Wert einer Auswertung des als Argumentausdrucks verwendeten Aufrufausdrucks.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.floor( java.lang.Math.random() )); }}
java.lang.System.out
0.0

Das voranstehende Beispiel zeigt, daß ein Argumentwert auch ein Laufzeitwert (also ein vor der Ausführung des Programms noch nicht bekannter Wert) sein darf. Durch Lesen des Quelltextes kann man den Argumentwert also gar nicht erfahren, man sieht nur den Argumentausdruck! Auch dies verdeutlicht wieder den Unterschied zwischen Argumentwert und Argumentausdruck.

Das folgende Diagramm zeigt die einzelnen Schritte bei der Auswertung von »java.lang.Math.floor( java.lang.Math.random() )«. Da der Wert einer Auswertung von »java.lang.Math.random()« von der Auswertung abhängt, können wir hier nur einen möglichen Wert als Beispiel  herausgreifen.

Schritte bei der Auswertung von »java.lang.Math.floor( java.lang.Math.random() )«

java.lang.Math.random() Inkarnationsprodukt

1.) | Operationsvorgang zur
v angegebenen Inkarnation

0.8765990144933389 Operationsergebnis (Beispiel)

2.) | Inkarnationsvorgang
| (Einsetzen des
v Argumentwertes)

java.lang.Math.floor( 0.8765990144933389 ) Inkarnationsprodukt

3.) | Operationsvorgang
v

0.0 Operationsprodukt

Argumentausdrücke mit Aufrufen und Operatoren

Es ist auch möglich, daß ein Argumentausdruck Namen, Operatoren und Aufrufausdrücke gleichzeitig  enthält.

Wir hatten bei dem folgenden Beispielprogramm schon gesehen, daß die Ausgabe immer »0.0« ist.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.floor( java.lang.Math.random() )); }}
java.lang.System.out
0.0

Da es langweilig ist, wenn die Ausgabe immer gleich ist, zeigen wir das folgende Beispielprogramm, welches nun sowohl  einen Methodennamen als auch  einen Operator im Argumentausdruck enthält.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.lang.Math.floor( 3 * java.lang.Math.random() )); }}
transcript
0.0
transcript
1.0
transcript
2.0

Das direkt obenstehende Programm kann nun bei jedem weiteren Start einen anderen Wert als beim vorherigen Start  ausgeben.

Dieses Programm illustriert deutlich den Unterschied zwischen Argumentausdruck  („Argument“) und Argumentwert : Der Argumentausdruck, ist immer derselbe, nämlich »3 * java.lang.Math.random()«; der Argumentwert kann bei jeder Auswertung des Aufrufs ein anderer sein.

Auch hier hängen einige Werte nun wieder von der Auswertung ab und können deswegen im folgenden nur durch willkürlich ausgewählte Beispiele  dargestellt werden.

Mögliche Schritte bei der Auswertung von »java.lang.Math.floor( 3 * java.lang.Math.random() ))«

java.lang.Math.random() Inkarnationsprodukt

1.) | Vorgang der Ermittlung
v einer Zufallszahl

0.5702739229044615 Zufallszahl (zwischen 0 und 1)

2.) | Inkarnationsvorgang
| (Einsetzen der
v Operandenwerte)

3 * 0.5702739229044615 Inkarnationsprodukt

3.) | Operationsvorgang
v

1.7108217687133846 Operationsprodukt
(zwischen 0 und 3)

4.) | Inkarnationsvorgang
| (Einsetzen des
v Argumentwertes)

java.lang.Math.floor( 1.7108217687133846 ) Inkarnationsprodukt

5.) | Operationsvorgang
v

1.0 Operationsprodukt
(0.0, 1.0 oder 2.0)

Das folgende Diagramm zeigt den Wertebereich des Ausdrucks »java.lang.Math.random()« mit Nummernzeichen an.

Die Werte sind darin alle gleich wahrscheinlich.

Mit »#« markierter Wertebereich des Ausdrucks »java.lang.Math.random()«

java.lang.Math.random()

0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 2.25 2.5 2.75 3.0 3.25 3.5 3.75 4.0
| ' ' ' | ' ' ' | ' ' ' | ' ' ' |

####################

Das folgende Diagramm zeigt den Wertebereich des Ausdrucks »3 * java.lang.Math.random()« mit Nummernzeichen an.

Die Werte sind darin weiterhin gleich wahrscheinlich, da die Streckung des Bereichs an der Art der Verteilung der Werte nichts ändert.

Mit »#« markierter Wertebereich des Ausdrucks »3 * java.lang.Math.random()«

3 * java.lang.Math.random()

0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 2.25 2.5 2.75 3.0 3.25 3.5
| ' ' ' | ' ' ' | ' ' ' | ' '

############################################################

Solch eine Multiplikation eines Bereichs mit einem positiven Faktor nennt man auch Skalierung. Falls der Faktor größer als »1« ist, spricht man von einer Streckung. Falls der Faktor kleiner als »1« ist, spricht man von einer Stauchung.

Das folgende Diagramm zeigt den Wertebereich des Ausdrucks »java.lang.Math.floor( 3 * java.lang.Math.random() )« mit Nummernzeichen an.

Die drei Werte sind darin weiterhin gleich wahrscheinlich, weil zu jedem Wert des folgenden Diagramms ein Bereich aus dem vorigen Diagramm gehört, dessen Breite eins beträgt. Dadurch ergibt sich der Wert »1.0« gleich vielen Fällen wie der Wert »2.0« oder der Wert »3.0«.

Wertebereich des Ausdrucks »java.lang.Math.floor( 3 * java.lang.Math.random() ))«

java.lang.Math.floor( 3 * java.lang.Math.random() ))

0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 2.25 2.5 2.75 3.0 3.25 3.5
| ' ' ' | ' ' ' | ' ' ' | ' '

# # #

Die Auswertung: Erster Schritt: Die Inkarnation

Wenn eine Methode auf ein Argument angewendet wird, dann wird eine Verbindung  zwischen der Methode und dem Wert des Arguments hergestellt, die auch als Aktivierungsverbund  oder als eine Inkarnation  der Methode bezeichnet wird. (Auch bei Methoden ohne Argument gibt es eine entsprechende Vorbereitung zum Start der Methode, die wir hier ebenfalls als „Inkarnation“ bezeichnen.)

Im Ausdruck »java.lang.Math.negateExact( 3 )« ist die Verbindung zwischen dem Methodennamen und dem Argumentwert bereits für den Programmierer sichtbar, aber bei der Ausführung des Programms muß der Computer sie bei der Auswertung dieses Ausdrucks noch einmal neu anlegen. Dies ist die Inkarnation  der Methode. Das Wort „Inkarnation “ bedeutet hier den Prozeß des Zusammenfügens zweier Informationen und auch dessen Ergebnis, also die Verbindung zwischen Methode und Argumentwert.

Die Auswertung: Zweiter Schritt: Die Ausführung

Nachdem die Inkarnation hergestellt wurde, wird sie dann als eine Operation ausgeführt. Eine Operation  ist ein bestimmter Vorgang der Datenverarbeitung, der ein Ergebnis liefern kann, wie hier den Wert »-3«.

Eine Methode alleine  ist im allgemeinen noch keine  Operation, beispielsweise kann die Methode »java.lang.Math.negateExact« alleine (ohne Inkarnation) noch nicht ausgeführt werden, weil ihr ja noch ein Argumentwert fehlt. Erst mit den Werten aller Argumente zusammen wird aus einer bloßen Methode  eine Operation.

Verwendung von »java.lang.Math.ceil« **

Sollen ganzzahlige Zufallszahlen bei »1« beginnen, so könnte man auf die Idee kommen, dafür »java.lang.Math.ceil« heranzuziehen. Diese Methode rundet ihren Argumentwert auf.

Der manchmal dafür verwendete Ausdruck »java.lang.Math.ceil( 3 * java.lang.Math.random() ))« hat jedoch nicht  die Zahlen von »1« bis »3« mit gleicher Wahrscheinlichkeit als Wert, sondern vielmehr die Zahlen von »0« bis »3«, wobei »0« aber viel unwahrscheinlicher ist, da »java.lang.Math.random()« auch einmal den Wert »0.0« ergeben könnte. In diesem Fall wäre »java.lang.Math.ceil( 3 * java.lang.Math.random() ))« dann gleich »0«.

Wertebereich des Ausdrucks »java.lang.Math.ceil( 3 * java.lang.Math.random() ))«

java.lang.Math.ceil( 3 * java.lang.Math.random() ))

0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 2.25 2.5 2.75 3.0 3.25 3.5
| ' ' ' | ' ' ' | ' ' ' | ' '

? # # #

Die Verwendung von »java.lang.Math.ceil( 3 * java.lang.Math.random() ))« ist also falsch, wenn gleich wahrscheinliche Zahlen aus dem Bereich von »1« bis »3« ausgedrückt werden sollen.

Verallgemeinerungen Programmierfehler

Das eben beschriebene Problem mit der Verwendung von »java.lang.Math.ceil« ist ein Beispiel für einen typischen Programmierfehler: Beim Ausprobieren scheint alles richtig zu sein, denn der Fehler tritt nur sehr selten  auf. Dennoch kann er irgendwann einmal auftreten, und dann könnte dies gerade ein „schlechter Zeitpunkt“ sein, zu dem das Auftreten des Fehlers zu erheblichen Problemen führt.

Dies bedeutet: Nur, weil ein Programm sich beim Ausprobieren wie erwartet verhält, muß es noch lange nicht korrekt sein!

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 stefanram723704 stefan_ram:723704 Verschiedene Arten von Argumentausdrücken in Java Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723704, slrprddef723704, 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/argumentarten_java