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