Kap.5: ANWEISUNGEN, BLOCKSTRUKTUR
Kapitel-Index
5.1 Zuweisung
5.2 Verzweigungen
5.2.1 if-Verzweigung
5.2.2 switch-Verzweigung
5.3 Schleifen
5.3.1 for-Schleife
5.3.2 while-Schleife, do-Schleife
5.4 Strukturierte Sprünge
5.4.1 break, continue, ggf. labeled
5.4.2 exit, return, assert
5.5 Bereichsschachtelung
5.5.1 vereinbart / sichtbar
5.5.2 lokal / global / verdeckt
5.5.3 Einschränkung der Namensfreiheit
5.6 Testfragen
Eine Anweisung (statement) ist eine Tätigkeit, die bei Erreichen
der betreffenden Programmstelle ausgeführt wird. Do/Break/Continue/
Return/Assert/Throw-Anweisungen enden mit Semikolon,
z.B. do x++;while(x<y); .
Anweisungsausdrücke (StatementExpression), d.h. Assignment/
Crement/MethodInvocation/ClassInstanceCreationExpression, werden
durch Setzen eines abschließenden Semikolons zu Ausdrucks-Anweisungen (ExpressionStatement). Der Seiteneffekt des Ausdrucks wird
zum Effekt der Anweisung,
z.B. x=1 (Effekt: Ausdruck x=1 erhält Wert 1)
(Seiteneffekt: Variable x erhält Wert 1) ,
x=1; (Effekt: Variable x erhält Wert 1) .
Switch/Try/Synchronized-Anweisungen enden mit einem Block,
z.B. switch(x) {case 0:y=0;break;default:y=1;} .
If/For/While-Anweisungen enden mit Semikolon oder Block,
z.B. if(x==1) y=1; (nicht empfehlenswert) ,
if(x==1){y=1;} (empfehlenswert) .
Eine Anweisung ist nach Syntaxdiagramm 69 von der Form
069°:Statement Anweisung
HHHHHHHHHHHHHHHHHHHHHHHHHH
-------------
HHHHHHHHHHHHHHHHHHHHHHHHH
H -
----------------
-
-
IfStatement
-----------
H
H
Label
-------------
Semi- H
H
------
--------------
colon H
H
- :
-
Identi
-
-
ForStatement
----------
or H
H
-fier
--------------
Block H
H
------
----------------
ending H
H nested labels must
-
WhileStatement
--------
State- H
H be different
----------------
ment H
H
-------------
H
H
-
DoStatement
-----------
H
H
-------------
H
H
----------------
H
H
-
BreakStatement
--------
H
H
----------------
H
H
-------------------
H
H
-
ContinueStatement
-----
H
H
-------------------
H
H
-----------------
H
H
-
ReturnStatement
-------
H
H
-----------------
H
H
-----------------
H
H
-
AssertStatement
-------
H
H
-----------------
Semi- H
H
----------------
colon H
H
-
ThrowStatement
--------
ending H
H
----------------
State- H
H
-
------------
ment H
H
-
Assignment
-----
H
H
------------
H
H
---------
H
H Statement-
-
Crement
--------
H
H Expression -
---------
H
H
----------------
H
H
-
MethodInvocation
-
H
H
----------------
H
H
----------------
H
H
-
Cl.Inst.Cr.Expr.
-
H
H
-
----------------
H
H
-
-------------------
-
; -
H
H
-----------------
H
H
-
SwitchStatement
-------
H
H
-----------------
H
H
--------------
H
H
-
TryStatement
----------
Block H
H
--------------
ending H
H
-----------------------
State- H
H
-
SynchronizedStatement
-
ment H
H
-----------------------
H
H
-------
H
H
-
Block
-----------------
-
H
HHHHHHHHHHHHHHHHHHHHHHHHHH
-------
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
Eine Zuweisung (Assignment) ohne abschließendes Semikolon ist
ein Ausdruck (Expression), speziell eine Operation mit einem Zuweisungsoperator (AssignmentOperator Syntax.036), und nach Syntaxdiagramm 058 von der Form
058: Assignment Zuweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H H
H L e f t H a n d S i d e H
H VariableOrField- H
H
------
H
H -
-
Name
--------
H
H
------
H
H
-------------
H
H
-
FieldAccess
-
H
H
-------------
-------------
H
H
-------------
Assignment-
------------
H
H
-
ArrayAccess
-
-
Operator
-
Expression
-
H
H
-------------
-------------
------------
H
H H
H The LeftHandSide must be a na- Die LinkeSeite muss eine be- H
H med variable, such as a Name nannte Variable sein, z.B. der H
H of a local variable or a Name einer lokalen Variablen H
H field, or results from a oder eines Datenfelds, oder H
H FieldAccess or an ArrayAccess. ergibt sich aus einem Daten- H
H feldZugriff oder einem Rei- H
H hungsZugriff. H
H H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
Mit abschließendem Semokolon wird eine Zuweisung zu einer Zuweisungsanweisung (AssignmentStatement), d.h. zu einer Anweisung
(Statement, Syntax.069),
z.B. c =Math.sqrt(a*a+b*b); // Identifier Name
Ware.preis +=kost1*x+kost0; // qualified Name
super.color*=fact; // FieldAccess
pas[n][n] =1; // ArrayAccess
Obwohl allgemeine Zuweisungen, d.h. Zuweisungen mit Operatoren
* Multiplication, / Division, % Remainder, + AdditionRespConcatenation, - Subtraction, << BitwiseShiftLeft, >> BitwiseShiftRightSameSign, >>> BitwiseShiftRightZeroSign, & BitwiseRespLogicalAnd,
^ BitwiseRespLogicalNotEqual, | BitwiseRespLogicalOr, vereinfacht
als Operation mit anschließender einfacher Zuweisung erklärt werden, sind doch Unterschiede zu beachten,
z.B. int i=0;int[] a={0,3,5};out.print( a[++i]+=1); // 4
int i=0;int[] a={0,3,5};out.print(a[++i]=a[++i]+1); // 6
char c='c'; out.print(c+=1); // d
char c='c'; out.print(c=(char)(c+1)); // d
char c='c'; out.print(c=c+1); // Typ-Fehler
Vor allem ist eine allgemeine Zuweisung (Assignment),
schneller als die entsprechende einfache Zuweisung (SimpleAssignment)
z.B. x=x*3
---------------------
VVVVVVVVVVVVVVVVVVVVVV
Zuweisung (Prinzip)
VVVVVVVVVVVVVVVVVVVVV
VV
---------------------
VV
VV VV
VV
Aufbau: VV
VV Links muss eine Variable stehen (siehe oben Syntax.058). VV
VV Rechts kann ein beliebiger Ausdruck (Expression) stehen. VV
VV VV
VV
Typ-Übereinstimmung, implizite Konvertierung (2.1): VV
VV Der Typ rechts muss mit dem Typ links übereinstimmen, VV
VV z.B. double arc; arc=2*rad*3.14; VV
VV Bei numerischen Operanden wird falls möglich der rechte VV
VV Operand in den Typ des linken Operanden verlustfrei oder VV
VV erweiternd zum nächsten Gleitpunktzahl-Wert konvertiert, VV
VV z.B. int i=123456789;float f;f=i; // f==1.23456792E8 VV
VV Bei konstantem Ausdruck (Syntax.060) als rechter Operand VV
VV und einem linken Operanden vom Typ char/byte/short wird VV
VV der rechte Operand in den Typ des linken Operanden kon- VV
VV vertiert, wenn der konstante Ausdruck verlustfrei (ein- VV
VV engend) im Typ der linken Seite darstellbar ist, VV
VV z.B. char c;c=33; // c=='#' VV
VV VV
VV
Berechnung des Ergebnisses (ist keine Variable): VV
VV Die Variable links wird bestimmt und ergibt Ergebnis-Typ. VV
VV Der Wert des Ausdrucks rechts wird berechnet. VV
VV Der Variablen-Wert ist eine Kopie des Ausdrucks-Werts. VV
VV Der Ergebnis-Wert ist eine Kopie des Variablen-Werts. VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Das nachfolgende Programm Fibonaccci berechnet die Vermehrung
von Individuen-Paaren in Zeitschritten von der Paar-Population alt
zur Paar-Population neu aus den Start-Zuweisungen
rekursiv bis zum größten Wert MAX_VALUE mit den Zuweisungen
Man beachte, dass nur zwei Variablen alt, neu benötigt werden.
n dient nicht zur Indizierung, sondern nur zur Protokollierung der
Zeitschritte. Wie das Ergebnis zeigt, vermehrt sich ein Paar in
46 Zeitsschritten, z.B. Kaninchen in 46 Monaten (ca. 4 Jahre), auf
1836311903 Paare. Die Berechnung der Vermehrung wird komplizierter, wenn man die Sterblichkeit mit berücksichtigt.
//************************ Fibonacci.java ************************
// Fibonacci-Zahlen fuer die Vermehrung von (Kaninchen-) Paaren *
// Leonardo Pisano (aus Pisa), Filius Bonacci, 13.Jh. *
// Regel 1: 1 Paar wird nach 1 Zeitschritt geschlechtsreif *
// Regel 2: 1 reifes Paar gebiert pro Zeitschritt 1 Paar *
// Daraus folgt fuer Paar-Populationen alt, neu die Rekursion *
// neu=alt+neu;alt=neu-alt; mit Startwerten alt=0;neu=1; *
//****************************************************************
// java.lang. Object
import static java.lang.System .out; // |`System
import static java.lang.Integer.MAX_VALUE; // `Integer
class Fibonacci
{public static void main(String[] args) // args ungenutzt
{out.println("Zeit Paare");
int n=0,alt=0,neu=1;
out.printf ("%1$-10d%2$1d Start alt\r\n",n++,alt);
out.printf ("%1$-10d%2$1d Start neu\r\n",n++,neu);
while (neu<=MAX_VALUE-alt) // kein Ueberlauf bei alt+neu
{ neu=alt+neu; // Summe der Vorgaenger alt+neu
alt=neu-alt; // neues alt ist altes neu
out.printf("%1$-10d%2$-10d neu\r\n",n++,neu);
}
out.println ("MAX_VALUE="+MAX_VALUE);
}
}
//****************************************************************
Output
------------------------
Zeit Paare
0 0 Start alt
1 1 Start neu
2 1 neu
3 2 neu
4 3 neu
5 5 neu
6 8 neu
7 13 neu
... ... ...
24 46368 neu
25 75025 neu
26 121393 neu
... ... ...
44 701408733 neu
45 1134903170 neu
46 1836311903 neu
MAX_VALUE=2147483647
Da es keine Fehlermeldungen für Überlauf bei der Ganzzahl-Arithmetik gibt (4.3), muss der drohende Überlauf bei neu=alt+neu; vom
Programmierer im Kopf der while-Schleife vorher abgefangen werden.
Bedingte Anweisungen, auch Verzweigungen genannt, bestehen aus
einer "Bedingung" (hier ist nicht die Bedingung gemäß Syntax.056
gemeint) und verschiedenen Anweisungen, die dynamisch beim Erreichen der "Bedingung" ausgewählt werden. Eine Verzweigung kann je
nach dem Typ ihrer "Bedingung" eine If-Anweisung (5.2.1) mit
"logischer Bedingung" oder eine Switch-Anweisung (5.2.2) mit
"ganzzahliger Bedingung" sein.
Eine If-Anweisung (IfStatement) ist nach ist nach Syntaxdiagramm
069 (für Statement, hier ein Auszug 069°) von der Form
069ø:IfStatement IfAnweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H boolean or Boolean H
H
----------
---------
-
Short-
H
H -
if -
( -
Expression
-
) -
Statement
-
-If-
H
H
----------
---------
-
State-
H
H besser Block
ment
Long- H
H
------------------------------------------
-If- H
H
---------
State-H
H
-
else ---------------------
Statement
-
-
ment H
H belongs to left-next
---------
-
H
H else-free if besser Block H
H H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
--------------------------
VVVVVVVVVVVVVVVVVVVV
if-Verzweigung (Prinzip)
VVVVVVVVVVVVVVVVVV
VV
--------------------------
VV
VV
if-Langform mit else: VV
VV Je nachdem, ob der boolean bzw. Boolean Expression VV
VV true oder false ist, VV
VV wird der then-Block oder der else-Block durchlaufen, VV
VV VV
VV z.B. i=0; if(i>0) {out.print("i>0" );} VV
VV else {out.print("i<=0");} // i<=0 VV
VV VV
VV
if-Kurzform ohne else: VV
VV Je nachdem, ob der boolean bzw. Boolean Expression VV
VV true oder false ist, VV
VV wird der then-Block durchlaufen oder übersprungen, VV
VV VV
VV z.B. i=0; if(i%8==0){out.println();} // new line VV
VV VV
VV
if-Schachtelung (leider gibt es kein endif): VV
VV Ein else mit seinem else-Block gehört VV
VV jeweils zum links nächsten if ohne else, VV
VV VV
VV z.B. i=0;if(1<2)if(3>4)if(5<6){i=7;}else{i=8;}else{i=9;} VV
VV out.print(i); // 9 VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Nach Syntaxdiagramm Syntax.069 (siehe 5) kann ein Statement auch
ein Block sein. Der Autor setzt in den Beispielen dieses Buchs
stets einen then-Block und ggf. einen else-Block, um Blockstruktur
zu erzeugen und "open-end-festival" zu vermeiden.
Eine Switch-Anweisung ist nach Syntaxdiagramm 069 (für Statement, hier ein Auszug 069°) von der Form
069ø: SwitchStatement SwitchAnweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H H
H Enum or IntegralNotLongType H
H or IntegralNotLongClassType H
H
------------
H
H -
switch -
( -
Expression
-
) -
H
H
------------
H
H
------------------------------------
H
H
S w i t c h B l o c k H
H
---------------------------------------------
H
H
switch-
H
H
assignable
H
H
not null
-------------
H
H
----------
---------
H
H
no two
Constant-
Block-
H
H
-
{ 
case -

Expression
-
: -

Statement
-
-
} -
H
H
of same
----------
---------
H
H
value
e.g. break;
H
H
EnumConstant-
H
H
----------
---------------
H
H


Identifier
-
H
H
one
----------
H
H 
default -------------
H
H
at most
H
H
-----------------------------------------------
H
H H
H If code is not to fall through Damit das Programm nicht auch H
H subsequent case labels, e.g durch die nachfolgenden case H
H a BreakStatement should be Sprungziele läuft, sollte z.B. H
H used as the last BlockState- eine BreakAnweisung als letzte H
H ment. BlockAnweisung gesetzt werden. H
H H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
z.B.
import static java.lang.System.*;
...
int tag=2;
switch(tag)
{case 0: out.print("Mo");break; case 1: out.print("Di");break;
case 2: out.print("Mi");break; case 3: out.print("Do");break;
case 4: out.print("Fr");break; case 5: out.print("Sa");break;
case 6: out.print("So");break; default:out.print("??");break;
} ... // Mi
------------------------------
VVVVVVVVVVVVVVVVVV
switch-Verzweigung (Prinzip)
VVVVVVVVVVVVVVVV
VV
------------------------------
VV
VV VV
VV
case-Auswahl: VV
VV Je nachdem, mit welcher case-Auswahl der switch überein- VV
VV stimmt, werden die Blockanweisungen nach dem betreffen- VV
VV den case durchlaufen. Damit nicht auch die nachfolgenden VV
VV case-Auswahlen durchlaufen werden,muss der Programmierer VV
VV z.B. eine break-Anweisung (5.4.1) als letzte Blockanwei- VV
VV sung setzen. Es dürfen nur solche case-Auswahlen vorkom- VV
VV men, deren Typ dem Typ des switch zuweisbar ist (5.1). VV
VV VV
VV
default-Auswahl: VV
VV Wenn keine case-Auswahl mit dem switch übereinstimmt, VV
VV werden ggf. nur die Blockanweisungen der default-Auswahl VV
VV durchlaufen. Es darf höchstens ein default im switch VV
VV gesetzt werden. VV SS SS
VV VV SS SS
VV
keine Auswahl: VV
VV Wenn keine case-Auswahl mit dem switch übereinstimmt VV
VV und keine default-Auswahl gesetzt wurde, wirkt die VV
VV switch-Anweisung wie eine leere Anweisung. VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Im folgenden Programm WochenTag wird der Wochentag aus dem Datum
bestimmt. In christlicher Zeitrechrechnung ist der Tag mit der
Nummer 1 der 1. Januar im Jahr 1, ein Montag. Man muss nur die
Nummer des Datum-Tages in christlicher Zeitrechnung bestimmen,
eine 1 subtrahieren und den Rest bei Division durch Wochenlänge 7
bestimmen. Das Ergebnis 0..6 entspricht den Wochentagen Mo..So .
Bei der Bestimmung der Anzahl der Tage im Februar, 28 bzw. 29, und
der Anzahl der Tage im Jahr, 365 bzw. 366, sind die Schaltjahr
-Regeln zu beachten:
j ist Schaltjahr, wenn j durch 4 teilbar (Caesar),
aber j ist kein Schaltjahr, wenn j durch 100 teilbar (Gregor),
oder j ist doch Schaltjahr, wenn j durch 400 teilbar (Gregor).
d.h. j%4==0 && j%100!=0 || j%400==0
Bei der switch-Anweisung
switch((gibZeitTag(t,m,j)-1)%7)
kann auf default-Setzung verzichtet werden, denn der Rest durch 7
liegt immer im Bereich 0 bis 6. Weil die Methode gibWochTag(int,
int,int) mit Resultattyp String ein abschließendes return verlangt, setzen wir return "Sonntag"; ans Ende.
Der Gregorianische Kalender gilt für die Jahre 1582 bis 3299.
Vor 1582 galt der Julianische Kalender. Nach 3299 wird der tatsächliche Kalender vom Gregorianischen Kalender abeichen, d.h. der
Sommer beginnt in den Winter zu wandern. Wir verweisen auch auf
die Klasse GregorianCalendar im Paket java.util, die mit einigem
Aufwand den Zugriff auf DAY_OF_WEEK ermöglicht.
//*********************** WochenTag.java *************************
// Bestimmung des Wochentags aus dem Datum, *
// nach Gregorianischem Kalender 1582-3299. *
// Command: java WochenTag Tg Mo Jahr *
//****************************************************************
// java.lang. Object
import static java.lang.System .out; // |`System
import static java.lang.Integer.parseInteger; // `Integer
class WochenTag
{static final int //1 2 3 4 5 6 7 8 9 10 11 12 Monat:
MLEN[][]={{0,31,28,31,30,31,30,31,31,30,31,30,31}, //normal
{0,31,29,31,30,31,30,31,31,30,31,30,31}};//schalt
static int schalt(int j) // 0,1
{return (j%4==0 && j%100!=0 || j%400==0 ? 1 : 0);}
static int gibJahrTag(int t,int m,int j) // 1..366
{for(int i=1;i<m;i++)
{ t+=MLEN[schalt(j)][i];}
return t;
}
static int gibZeitTag(int t,int m,int j) // 1..1204935
{return gibJahrTag(t,m,j--)+j*365+j/4-j/100+j/400;}
static String gibWochTag(int t,int m,int j) // Mo .. So
{switch ((gibZeitTag(t,m,j)-1)%7)
{case 0: return "Montag" ;
case 1: return "Dienstag" ;
case 2: return "Mittwoch" ;
case 3: return "Donnerstag";
case 4: return "Freitag" ;
case 5: return "Samstag" ;
} return "Sonntag" ;
}
public static void main(String[] args)//args[0]..args[2] genutzt
{int t=parseInt(args[0]),
m=parseInt(args[1]),
j=parseInt(args[2]);
out.print ((schalt(j)==1?"":"kein ")+"Schaltjahr"+"\r\n"
+gibZeitTag(t,m,j)+"-ter Tag in Zeit"+"\r\n"
+gibJahrTag(t,m,j)+"-ter Tag im Jahr"+"\r\n"
+gibWochTag(t,m,j)+"\r\n");
} }
//****************************************************************
Command
-------------------------
java WochenTag 31 12 2007
Output
----------------------
kein Schaltjahr
733041-ter Tag in Zeit
365-ter Tag im Jahr
Montag
Eine Schleife (loop) mit vorangesetzter (pre) Prüfung (check)
prüft jeweils vorher (precheck) , ob die Schleifen-Anweisung
(action) noch einmal ausgeführt werden soll :
--------------------------------
--------------------------
_______
/ \
--------
-
-
| check |-
action
-
\_______/
--------
--------------------------------
Fig. 5.3: precheck
Die for-Schleife (5.3.1) und die while-Schleife (5.3.2) sind
beide als precheck zu deuten, die do-Schleife (5.3.2) ist ein
postcheck, d.h. der check wird erst nach der action durchgefürt.
Einen incheck erhält man z.B. durch Setzen einer if-Verzweigung
(5.2.1) mit Heraus-Sprung (5.4) zwischen zwei Aktionen action1/2.
----------------------------------
VVVVVVVVVVVVVVV
for-Schleife (Zielvorstellungen)
VVVVVVVVVVVVVVV
VV
----------------------------------
VV
VV
so schnell wie möglich (vorberechnete Laufgrenze,Krement), VV
VV schlecht:for(int i=0;i<max(0,3);i=i+1) VV
VV out.print(i*i); //014 VV
VV effektiv:int m=max(0,3); VV
VV for(int i=0;i<m;i++) {out.print(i*i);} //014 VV
VV VV
VV
so lokal wie möglich (lokale Laufparameter, Block), VV
VV schlecht:int i=0;for(;i<3;) out.print(i*i++); //014 VV
VV effektiv:for(int i=0;i<3;i++) {out.print(i*i);} //014 VV
VV VV
VV
so übersichtlich wie möglich (trickfrei, Lauf erkennbar). VV
VV schlecht:for(those();who();like())trick17(); // empty VV
VV mit public static boolean those() {return false;} VV
VV public static boolean who() {return false;} VV
VV public static boolean like() {return false;} VV
VV public static boolean trick17() {return false;} VV
VV mit int[] a={0,1,2}; //014 VV
VV schlecht:for(int i=0;i<a.length;)out.print(a[i]*a[i++]); VV
VV effektiv:for(int each:a) {out.print(each*each);} VV
VV //014 VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Eine for-Anweisung (ForStatement) ist nach Syntaxdiagramm 066
(für ForControl) und Syntaxdiagramm 069 (für Statement, hier zusammengefasst zu 069°) von der Form
069ø:ForStatement ForAnweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H H
H -
for -
H
H
-------
H
H
F o r E a c h C o n t r o l H
H
---------------------
H
H
----------------
H
H
-
-
VariableModifier
-
ArrayType or H
H
----------------
ClassType H
H
implementing H
H
Iterator Iterable H
H
----
----------
----------
H
H


Type
-----
Identifier
--
: -
Expression
H
H
----
----------
----------
H
H
H
H
B a s i c F o r C o n t r o l
H
H
-------
------------
---------
H
H 
( 

ForInit
; -
ForCondition
; -
ForUpdate
-
-
) -
H
H
-------
------------
---------
H
H
H
H
F o r E v e r C o n t r o l
H
H
----------
; ----------------
; --------------
H
H
----------------
H
H
-----------
H
H
-
Statement
-
H
H
-----------
H
H besser Block H
H H
H Iterators or variables decla- In der ForKontrolle verein- H
H red in the ForControl are lo- barte Iteratoren oder Variab- H
H cal to the right and in the len sind lokal nach rechts H
H following Statement. und in der nachfolgenden An- H
H weisung. H
H Iterators or variables in nes- Iteratoren oder Variablen in H
H ted ForStatement(s) must be geschachtelten ForAnweisung H
H different. (en) müssen verschieden sein. H
H H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
z.B. int[] a={0,1,2};
ForEachControl: for(int each:a) {out.print(each);} // 012
BasicForControl: for(int i=0;i<3;i++){out.print(a[i]);} // 012
ForEverControl: for(;;) {out.print( 0 );} // 0...
Die ForEachControl erlaubt nicht nur das Durchlaufen von Komponenten einer Reihung, sondern auch das Durchlaufen von Objekten,
die in einer Klasse zusammengefasst sind, welche die Schnittstelle
Iterable des Pakets java.lang implementiert. Wir verweisen auf die
Klasse java.util.Vector im Beispiel Net (13.3.2). Der unendliche
Lauf einer for-Schleife mit ForEverControl for(;;){...} kann z.B.
mit einer if-Verzweigung (5.2.1) und Sprung (5.4) gestoppt werden.
-----------------------------------------------------
VVVVV
Gewöhnliche for-Schleife (BasicForControl, Prinzip)
VVVVVV
VV
-----------------------------------------------------
VV
VV VV
VV
ForInit (for-Initialisierung) nur einmal zu Anfang: VV
VV Wird ein Laufparameter lokal in der for-Schleife verein- VV
VV bart (siehe Syntax.066), dann darf global unter gleichem VV
VV Namen keine andere Größe vereinbart sein (Einschränkung VV
VV der Namensfreiheit 5.5.3). Dem Laufparameter wird sein VV
VV Anfangswert zugewiesen (siehe Syntax.066). Weiter mit VV
VV ForCondition. VV
VV VV
VV
ForCondition (for-Bedingung) vor jedem Block-Durchgang: VV
VV Die ForCondition wird ausgewertet (siehe Syntax.066), VV
VV bei true folgt ein neuer Block-Durchgang, bei false VV
VV brichtdie Schleife ab. VV
VV VV
VV
ForUpdate (for-Weiterzählung) nach jedem Block-Durchgang: VV
VV Das ForUpdate weist (siehe Syntax.066) dem Laufparameter VV
VV den nächsten Wert zu. Weiter mit ForCondition. VV
VV VV
VV z.B. for(int i=0;i<3;i++){out.print(i+",");} // 0,1,2, VV
VV VV
VV
InCheck (Abbruchprüfung aus dem for-Block heraus): VV
VV Schleifen jeder Art können aus dem Block heraus z.B. VV
VV durch if-Verzweigung (5.2.1) und Sprünge continue, break VV
VV (5.4.1), exit, return, assert (5.4.2) oder Auswerfen VV
VV throw (11.1.1) von Ausnahmen abgebrochen werden, VV
VV VV
VV z.B. for(int i=0;i<10;i++) VV
VV {out.print(i); if(i>=2){break;} out.print(",");} VV
VV // 0,1,2 VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Im folgenden Beispiel PrimZahl wird die größte int Primzahl
bestimmt. Man könnte das Beispiel erweitern auf long Primzahlen
oder mit BigInteger Zahlen aus dem Paket java.math rechnen, die in
der Kryptographie beim Verfahren von Rivest, Shamir, Adleman verwendet werden.
Zur Prüfung einer ganzen Zahl i>0 auf Primzahl-Eigenschaft untersucht man, ob i durch Divisoren div=2..(i-1) teilbar ist, d.h.
i%div==0. Zur Beschleunigung des Verfahrens beschränkt man sich
auf div=2 und sonst div ungerade.
Auch braucht man nicht bis zu div=i-1 , sondern nur bis zu
div=(int)sqrt(i) zu suchen:
Gäbe es oberhalb der Wurzel aus i einen Teiler divOben, dann
müsste es bereits unterhalb der Wurzel aus i einen Teiler divUnten
geben mit divUnten*divOben=i.
Die Methode sqrt(double) zum Ziehen der Quadratwurzel ist static
vereinbart in der Klasse Math des Standard-Pakets java.lang.
//************************* PrimZahl.java ************************
// Prueft natuerliche (pos. ganze) Zahl auf Primzahl-Eigenschaft *
// Command: java PrimZahl NatZahl *
//****************************************************************
// java.lang. Object
import static java.lang.System .out; // ||`System
import static java.lang.Integer.parseInt; // |`Integer
import static java.lang.Math .sqrt; // `Math
class PrimZahl
{static boolean istPrim(int i) // i>0
{if (i!=2 && i%2==0) {return false;}
if (i<=7) {return true; }
final int SQRT=(int)sqrt(i);
for(int div=3;div<=SQRT;div+=2)
if (i%div==0) {return false;}
return true;
}
public static void main(String[] args) // args[0] genutzt
{out.println((istPrim(parseInt(args[0]))?"":"nicht ")+"prim");
}
}
//****************************************************************
Command Kommentar:
------------------------
java PrimZahl 2147483647 Integer.MAX_VALUE
Output
-------
prim ist eine Primzahl
5.3.2 while-Schleife, do-Schleife
Eine while-Anweisung (WhileStatement) ist nach Syntaxdiagramm 069
(für Statement, hier ein Auszug 069°) von der Form
069°:WhileStatement WhileAnweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H H
H boolean or Boolean H
H
------------
-----------
H
H -
while -
( -
Expression
-
) -
Statement
-
H
H
------------
-----------
H
H besser Block H
H H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
z.B. int i=0; while(i<3){out.print(i);i++;} // 012
Die while-Schleife entspricht einer for-Schleife (5.3.1) mit
ForEverControl und Prüfung vor ihrem Statement (precheck):
for(;;) { if(!Expression){break;} Statement }
d.h. solange der Expression den Wert true ergibt, wird das
Statement wiederholt.
Eine do-Anweisung (DoStatement) ist nach Syntaxdiagramm 069
(für Statement, hier ein Auszug 069°) von der Form
069°:DoStatement DoAnweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H boolean or Boolean H
H
-----------
----------
H
H -
do -
Statement
-
while -
( -
Expression
-
) -
; -
H
H
-----------
----------
H
H ggf. Block H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
z.B. int i=0; do{out.print(i);i++;}while(i<3); // 012
Die do-Schleife entspricht einer for-Schleife (5.3.1) mit
ForEverControl und postcheck am Ende ihrer BlockStatements:
for(;;) { BlockStatements if(!Expression){break;} }
d.h. die BlockStatements werden einmal (ungeprüft) ausgeführt und
danach solange (while) wiederholt, wie der Expression den Wert
true ergibt.
while-Schleifen und do-Schleifen sind geeignet für die Abfrage
von Ereignissen, die nicht durch einen Parameterlauf, wie in for
-Schleifen, bestimmt werden, z.B. Einlesen einer Datei bis zum
Datei-Ende (8.2)
int chr; while((chr=inread())!=-1){...}
5.4 Strukturierte Sprünge
Bereits 1960 warnte Dijkstra: 'goto considered harmful', aber es
sollte mehr als 30 Jahre dauern, bis Java als erste Programmiersprache auf goto-Sprünge verzichten konnte.
An die Stelle expliziter Sprünge (Spaghetti-Programme) treten
strukturierte Sprünge.
Gesprungen werden kann nur aus einem switch-Block oder aus einer
Schleife. Anspringbare Marken (label) können nur vor einer Schleife stehen,
z.B. loop:for(int a=1;a<10;a++)
for(int b=1;b<10;b++)
for(int c=1;c<10;c++)
check:if(a*a+b*b==c*c)
{out.print(a+" "+b+" "+c);break loop;} // 3 4 5
Nicht anspringbare Marken, wie z.B. check: im obigen Beispiel,
können als Kommentar dienen.
5.4.1 break, continue, ggf. labeled
Eine break-Anweisung (BreakStatement) oder eine continue-Anweisung (ContinueStatement) ist nach Syntaxdiagramm 069 (für Statement, hier ein Auszug 069°) von der Form
069°:BreakOrContinueStatement BreakOderContinueAnweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H H
H -
-
break ------
-
H
H
for,while,do
surrounding
- Break- H
H
switch
label-
Statement H
H
------------
-
H
H
-
continue ---
-
Identifier
-
- Continue- H
H for,while,do
------------
Statement H
H
-----------------
-
; -
-
-
H
H H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
------------------------------
VVVVVVVVVVVVVVVVV
break und continue (Prinzip)
VVVVVVVVVVVVVVVVV
VV
------------------------------
VV
VV
break VV
VV VV
VV ohne Label in einer Schleife oder einem switch zulässig, VV
VV springt über den Rest der Schleife bzw. des switch VV
VV zum Abbruch (ohne Bedingung), VV
VV z.B. for(int i=0;i<3;i++) VV
VV {if(i%2!=0){out.print(i);break;}} // 1 VV
VV VV
VV mit Label in einer Schleife zulässig, VV
VV springt über den Rest aller inneren Schleifen zum Ab- VV
VV bruch (ohne Bedingung) der äußeren umgebenden Schleife, VV
VV die mit diesem Label markiert ist, VV
VV z.B. loop:for(int a=1;a<10;a++) VV
VV for(int b=1;b<10;b++) VV
VV for(int c=1;c<10;c++) VV
VV if(a*a+b*b==c*c) VV
VV {out.println(a+" "+b+" "+c);break loop;} // 3 4 5 VV
VV VV
VV
continue VV
VV VV
VV ohne Label in einer Schleife zulässig, VV
VV springt über den Rest der Schleife zur Bedingung dieser VV
VV Schleife, bei for-Schleife zunächst zum Update, VV
VV z.B. for(int i=0;i<3;i++) VV
VV {if(i%2!=0){continue;};out.print(i);} // 02 VV
VV VV
VV mit Label in einer Schleife zulässig, VV
VV springt über den Rest aller inneren Schleifen zur VV
VV Bedingung der äußeren umgebenden Schleife, die mit die- VV
VV sem Label markiert ist, bei for-Schleife zunächst zum VV
VV Update, VV
VV z.B. loop:for(int i=0;i<3;i++) VV
VV for(int j=0;j<3;j++) VV
VV {if(i==j){continue loop;};out.print(i+""+j+",");} VV
VV // 10,20,21, VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Es ist nicht möglich, aus einem switch-Block heraus mit break an
das Abbruch-Ende eines umgebenden Blocks zu springen. Der switch
-block (5.2.2, Syntax.069) benötigt selbst den break zum Ausbrechen aus seiner case-Folge.
5.4.2 exit, return, assert
Die Methode exit(int) der Klasse System kann in Anlehnung an C
-Konventionen mit Parameter 0 (in C status 'normal termination')
oder Parameter ungleich 0 (in C status 'abnormal termination')
aufgerufen werden, terminiert jedoch in Java niemals normal und
kann SecurityException werfen, wenn ein SecurityManager existiert,
dessen checkExit Methode den exit-Aufruf mit dem spezifizierten
Status nicht erlaubt.
z.B. if(args.length!=2) // vergleiche UmsatzSteuer 3.1
{out.println("java UmsatzSteuer USt umsatz");exit(1);}
Eine return-Anweisung (ReturnStatement) ist nach Syntaxdiagramm
069 (für Statement, hier ein Auszug 069°) von der Form
069°:ReturnStatement ReturnAnweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H Type H
H
------------
H
H -
return -----
-
Expression
-
H
H from method
------------
H
H
H
H
void
H
H
----------------
-
; -
H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
Das englische Wort 'return' beschreibt in seiner Zweideutigkeit
"zurückkehren" (return from London) und "zurückbringen" (return
to sender) die zwei Bedeutungen der return-Anweisung:
------------------
VVVVVVVVVVVVVVVVVVVVVVVV
return (Prinzip)
VVVVVVVVVVVVVVVVVVVVVV
VV
------------------
VV
VV VV
VV
allgemein bei allen Methoden (void or nonvoid method) VV
VV Rücksprung zum Methoden-Aufruf (MethodInvocation), VV
VV z.B. if(args.length!=2) // siehe UmsatzSteuer 3.1 VV
VV {out.println("java UmsatzSteuer USt umsatz");return;} VV
VV VV
VV
zusätzlich speziell bei Funktionen (nonvoid method) VV
VV Vor dem Rücksprung Kopie des Funktionswerts (Expression, VV
VV siehe Syntax oben) auf den Methoden-Aufruf (MethodInvo- VV
VV cation), VV
VV z.B. static double hebSteuer // siehe UmsatzSteuer 3.1 VV
VV (final double prozent,final double betrag) VV
VV {return prozent*betrag/100.0;} VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Die return-Anweisung kann als BlockStatement an jeder Stelle der
Folge der Blockstatements eines Methoden-Rumpfs (Syntax.083) gesetzt werden, auch in der Methode main(String[]) als normaler Abbruch an Stelle eines abnormalen Abbruchs mit exit(1).
Eine assert-Anweisung (AssertStatement) ist nach Syntaxdiagramm
069 (für Statement, hier ein Auszug 069°) von der Form
069°:AssertStatement AssertAnweisung
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
H H
H loader of top-level boolean or Boolean H
H enables/disables
------------
H
H -------
assert -------
Expression
-
H
H
------------
H
H if false: throws
H
H AssertionError
H
H
H
H
----------------------
H
H
H
H
non void
H
H
------------
H
H
-
: -
Expression
-
-
; -
H
H
------------
H
H converted to H
H String detail message H
H of AssertionError H
H H
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
Auch eine assert-Anweisung kann als normaler Abbruch an Stelle
eines abnormalen Abbruchs mit exit(1) gesetzt werden,
z.B. assert(args.length==2):"java UmsatzSteuer USt umsatz";
// vergleiche UmsatzSteuer 3.1
Allerdings kann ein Programm mit assert ("absichern") nicht wie
gewohnt mit dem Kommando javac übersetzt werden, dann wird '1 error, 1 warning' gemeldet, sondern verlangt die Option 'source 1.n'
mit n>=4, die auf die Installation von Java in Version 1.4 oder
höher hinweist:
java -source 1.5 AssertTest.java
Ausserdem kann ein so übersetztes Programm nicht wie gewohnt mit
dem Kommando java gestartet werden, dann ist assert nicht aktiviert, sondern verlangt eine Option 'ea' (enable assert), die
assert aktiviert:
Vorteile bieten assert-Anweisungen bei der Fehlersuche (debugging) in neu zu erstellenden oder weiter zu entwickelnden Programmen.
Java gehört als ALGOL-Familienmitglied zu den blockstrukturierten Programmiersprachen. Die Blockschachtelung von ALGOL ist im
Laufe der Entwicklung der Programmiersprachen erweitert worden zur
Bereichsschachtelung. Ein Bereich (englisch region oder space)
kann im einzelnen sein:

Block (3, Syntax.068),

Methode / Konstuktor (7, Syntax.083 / Syntax.089),

Klasse / Schnittstelle (9, Syntax.101),

Paket (9, Syntax.102),

Übersetzungseinheit (9, Syntax.104).
Bereiche können ineinander verschachtelt (nested) sein
--------------------------------
A
ist B übergeordnet
--------------------------
B
ist A untergeordnet
--------------------------
--------------------------------
bzw. nicht ineinander verschachtelt sein
--------------------------------
--------------------------
A
ist B parallelgeordnet
--------------------------
--------------------------
B
ist A parallelgeordnet
--------------------------
--------------------------------
5.5.1 vereinbart / sichtbar
Der innerste Bereich, in dem die Vereinbarung einer Größe unmittelbar vorkommt, ist dieser Größe als ihr "Vereinbarungsbereich"
(declarative region or namespace) zugeordnet. In ihrem Vereinbarungsbereich heißt eine Größe "vereinbart".
Die interne Belegung von Speicher für Bereichs-Größen erfolgt
dynamisch konsekutiv zur Laufzeit bei der Vereinbarung der Größe,
ausgenommen non-static Klassen, die erst bei Vereinbarung eines
Objekts dieser Klasse Speicher belegen und non-final / non-static
Mitglieder von Schnittstellen, die erst bei Implementaion der
Schnittstelle Speicher belegen. Beim Verlassen des Vereinbarungsbereichs wird der gesamte Speicher-Keller aller in diesem Vereinbarungsbereich vereinbarten Größen wieder freigegeben.
Der Name "Keller" (englisch stack) soll an einen Kellerschacht
erinnern, in dem das zuerst gespeicherte Objekt unten liegt und
das zuletzt gespeicherte Objekt oben als erstes wieder zugreifbar
ist ("first in, last out").
-----------------------------------------------
VVVV
Bereichsschachtelung spart Speicher (Prinzip)
VVVV
VV
-----------------------------------------------
VV
VV VV
VV Eine nicht mehr vereinbarte Größe VV
VV verliert ihren Namen und ihren Wert. VV
VV Ihr Speicher wird wieder freigegeben. VV
VV VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Einer Bereichs-Größe, die in einem Block oder in einer Methode/
Konstruktor vereinbart ist, wird der Teil ihres Vereinbarungsbereichs, der nach ihrer Vereinbarung liegt, als ihr "Sichtbarkeitsbereich" (scope) zugeordnet. In ihrem Sichtbarkeitsbereich heißt
eine Größe "sichtbar". Nur dort ist sie im Programmtext verfügbar
(available).
Einer Bereichs-Größe, die in einer Klasse / Schnittstelle oder
in einem Paket vereinbart ist, wird ihr gesamter Vereinbarungsbereich als Sichtbarkeitsbereich zugeordnet, d.h. man benötigt keine
forward (Pascal) oder prototype (C, C++) Vereinbarungen in Java.
Nur in Variablen-Initialisierern (Syntax.063) von Datenfeld-Verein-
barungen (Syntax.073) dürfen derartige Größen erst nach ihrer Ver-
einbarung verwendet werden.
Neben Bereichs-Größen gibt es new-Größen, d.h. mit new erzeugte
Objekte, auf die Referentyp-Größen (6, 8, Typ Syntax.030) verweisen.
Diese new-Objekte werden in einem nicht an den Bereich ihrer Erzeugung gebundenen zentralen Halden-Speicher gehalten und sind
bis zum Ende des Programmlaufs "unsterblich", sofern sie nicht von
der automatischen Speicherbereinigung (garbage collection) eliminiert werden, wenn festgestellt wird, dass keine Referenz (Zeiger)
mehr auf das new-Objekt verweist. Die Zeiger selbst sind "sterbliche" Bereichs-Größen.
Der Name "Halde" (englisch heap) soll an eine Sand-Halde erinnern, die bei Entnahme von Sand aus der Halde an beliebiger Stelle wieder lückenlos zu einer neuen Sand-Halde zusammenfließt.
5.5.2 lokal / global / verdeckt
Ein "Lokalbereich" (local decalarative region) entsteht aus einem Vereinbarungsbereich (5.5.1) durch Ausschluß aller ihm untergeordneten Bereiche. In ihrem Lokalbereich heißt eine Größe
"lokal". In einem Lokalbereich dürfen nicht zwei verschiedene Größen gleichen Namens lokal sein,
z.B. inkorrekt int inkorrekt;double inkorrekt;
ausgenommen Überladen (7.3) von Methoden-Namen, z.B. println(),
z.B. korrekt int i=1 ;out.println(i); // 1
double x=3.14;out.println(x); // 3.14
Auch Überladen von Namen durch Unterscheidung nach Variable,
Datenfeld, Methode, Klasse/Schnittstelle oder Paket (8.3) ist möglich, sollte aber gemäß Namenskonventionen (1.3.3) vermieden werden.
Marken (label) sind keine Größen im Sinne dieses Abschnitts,
sondern mit Kommentar vergleichbar. Bei strukturierten Sprüngen
(5.4) hat nur das innerste umgebende von mehreren gleichnamigen
Sprungzielen Bedeutung.
Eine Bereichs-Größe heißt "global" in jedem untergeordneten Be-
reich ihres Vereinbarungsbereichs,
z.B. class Klasse
{int global=2; // global ist "global" in method()
void method()
{double local=3.14;out.print(local*global); // 6.28
}
}
Eine globale Größe heißt "verdeckt" (hidden) in einem untergeordneten Bereich ihres Vereinbarungsbereichs, wenn sie dort sichtbar wäre, aber dort eine Größe gleichen Namens lokal vereinbart
ist. Der Name der verdeckten Größe ist in diesem untergeordneten
Bereich nicht zugänglich. Statt dessen ist der gleichlautende Name
der sie verdeckenden Größe zugänglich. Name und Wert der verdeckten Größe bleiben erhalten und sind wieder verfügbar, wenn der dynamische Fluß des Programms den Unterbereich verläßt, in dem die
Größe verdeckt war.
----------------------------------------------
VVVVV
Bereichsschachtelung schützt Namen (Prinzip)
VVVVV
VV
----------------------------------------------
VV
VV VV
VV Eine (vorübergehend) verdeckte Größe behält ihren VV
VV während der Verdeckung unzugänglichen Namen und Wert.VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Jede verdeckte Größe ist global, aber nicht jede globale Größe
ist verdeckt.
Die Verdeckung einer Größe kann durch zusätzliche Qualifikation
des Namens der Größe, d.h. durch Auflösung der Namens-Mehrdeutigkeiten (scope resolution), wieder aufgehoben werden,
z.B. class Klasse
{ int i; // i global verdeckt im Konstruktor
Klasse(int i) // i lokal im Konstruktor
{this.i=i;} // i sichtbar, this.i sichtbar
}
5.5.3 Einschränkung der Namensfreiheit
Während man in ALGOL noch Wert darauf legte, durch Blockschachtelung den gleichen Namen in inneren Blöcken wieder neu verwenden
zu können ("Namensfreiheit"), wird dies in modularen Programmiersprachen wegen der Vielfalt der Namen nicht mehr als erstrebenswert angesehen ('name confusion considered harmful') und deshalb
eingeschränkt:
--------------------------------------------
VVVVVVV
Einschränkung der Namensfreiheit (Prinzip)
VVVVVVV
VV
--------------------------------------------
VV
VV VV
VV
Bereichs-Größen in einem übergeordneten Block, VV
VV
Type-Parameter in einem übergeordneten ForBlock VV
VV
und Parameter in einem übergeordneten CatchBlock VV
VV können nicht verdeckt werden, d.h. es muss VV
VV lokal ein anderer Name gewählt werden. VV
VV VV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
z.B. class AnotherName
{public static void main(String[] args) // args ungenutzt
{ int x=0; // übergeordneter Block
for( int xfor=0;xfor<10;xfor++) // ForBlock
{try{if(xfor==5){throw new RuntimeException("");}}
catch(RuntimeException xcatch) // CatchBlock
{{int xlocal=5;out.print(xlocal);}} // 5
}
}
} // x, xfor, xcatch, xlocal sind verschiedene Namen
zu Frage
abdeckbare Antwort
---------------------------------------------
--------------------
5.1 Kann im AssignmentStatement L=E;
ja, z.B. i=j=4; von
E wieder ein AssignmentExpression sein?
rechts abgearbeitet
5.1 Welche Werte haben a,b ?
a hat den Wert 'a'
a='b';b=a;a='a';
b hat den Wert 'b'
Welche der folgenden sind korrekte
Anweisungen?
4.2.5 sign=(x<0?-1:(x==0?0:1));
beide
5.2.1 if(x< 0) {sign=-1;} else
if(x==0) {sign= 0;} else {sign=1;}
5.2.1 Bestimme den Wert von i in
i=0;if(1<2){}else if(3<4){}else{i=5}
i==0
i=0;if(1>2){}else if(3>4){}else{i=5}
i==5
5.3 Was wird ausgedruckt?
for(int i=1;i<3;i++)
while(i%2!=0){out.print(i);}
111...
i=1;while(i%2!=0)
for(;;){out.print(i++);}
123...
5.3.1 Berechne mit einer for-Schleife die
Näherungssumme für e:
double e=1.0;
1 1 1
long fak=1;
e = 1 + --- + --- + ... + --- + ...
for(int
1! 2! 12!
i=1;i<13;i++)
{e+=1.0/(fak*=i);}
5.4 Kann man mit break; aus einer Metho-
nein, eine Methode
de herausspringen?
ist kein switch-
Block und keine
Schleife
5.5 Können folgende Bereiche direkt (!)
ineinander geschachtelt sein?
Block in Block
alle
Klasse in Klasse
Paket in Paket
Methode in Methode
keine
Methode in Block
5.5 Wo z.B. können aufeinanderfolgen?
zulässig:
{{
Block im Block
}}
Block im Block
{}
leerer Block
;;
freie for-Schleife
;}
Anweisung im Block
nicht empfohlen:
{;
leere Anweisung
};
Anweisung mit };
5.5.2 Sind Type Parameter von for-Schlei-
ja
fen lokal im ForInit/Condition/Update
und im Block der for-Schleife?
5.5.2 Überschreibt die verdeckende Größe
den Wert der von ihr verdeckten Größe?
nein
5.5.3 Welche der folgenden sind korrekte
Bereiche?
{int i=1;{int i=1;out.print(i);}}
keiner
for(int i=1;i<2;i++)
{{int i=1;out.print(i);}}
try{throw RuntimeException("");}
catch(RuntimeException i)
{{int i=1;out.print(i);}}
void method(int i)
{{int i=1;out.print(i);}}
class C{C(int i){this.i=i}int i;}
korrekt