Kapitel 3: Imperative Programmierung in Java

Werbung
Imperative Programmierung in Java
Algorithmen und Datenstrukturen II
1
Mini-Java
Ein Mini-Java Programm besteht aus genau einer Klasse. In dieser Klasse gibt es
genau eine main-Methode. Folgende Konstrukte sind Anweisungen (statements
gemäß Mini-Java-Syntax, vgl. Beispiel ??):
Algorithmen und Datenstrukturen II
2
Mini-Java
Ein Mini-Java Programm besteht aus genau einer Klasse. In dieser Klasse gibt es
genau eine main-Methode. Folgende Konstrukte sind Anweisungen (statements
gemäß Mini-Java-Syntax, vgl. Beispiel ??):
1. Die Deklaration einer Variablen vom Typ int mit sofortiger Initialisierung:
int ident = expression;
Jeder Bezeichner (ident) darf in höchstens einer Variablendeklaration
vorkommen. Diese kontextsensitive Bedingung lässt sich nicht in der
EBNF-Definition formulieren.
Algorithmen und Datenstrukturen II
2
Mini-Java
Ein Mini-Java Programm besteht aus genau einer Klasse. In dieser Klasse gibt es
genau eine main-Methode. Folgende Konstrukte sind Anweisungen (statements
gemäß Mini-Java-Syntax, vgl. Beispiel ??):
1. Die Deklaration einer Variablen vom Typ int mit sofortiger Initialisierung:
int ident = expression;
Jeder Bezeichner (ident) darf in höchstens einer Variablendeklaration
vorkommen. Diese kontextsensitive Bedingung lässt sich nicht in der
EBNF-Definition formulieren.
Algorithmen und Datenstrukturen II
2
2. Die Zuweisung eines Wertes an eine Variable:
ident = expression;
Diese Variable muss vorher deklariert worden sein und den gleichen Typ wie der
Ausdruck haben. Diese Nebenbedingung ist ebenfalls nicht in der
EBNF-Definition ausgedrückt.
Algorithmen und Datenstrukturen II
3
2. Die Zuweisung eines Wertes an eine Variable:
ident = expression;
Diese Variable muss vorher deklariert worden sein und den gleichen Typ wie der
Ausdruck haben. Diese Nebenbedingung ist ebenfalls nicht in der
EBNF-Definition ausgedrückt.
3. Eine bedingte Anweisung (if-then Anweisung):
if(condition) statement
Der Bool’sche Ausdruck (condition) wird ausgewertet; ist er true, so wird die
Anweisung (statement) ausgeführt. Ist er false, so wird die Anweisung nicht
ausgeführt und die Programmausführung mit der nächsten Anweisung hinter
der if-then Anweisung fortgesetzt.
Algorithmen und Datenstrukturen II
3
2. Die Zuweisung eines Wertes an eine Variable:
ident = expression;
Diese Variable muss vorher deklariert worden sein und den gleichen Typ wie der
Ausdruck haben. Diese Nebenbedingung ist ebenfalls nicht in der
EBNF-Definition ausgedrückt.
3. Eine bedingte Anweisung (if-then Anweisung):
if(condition) statement
Der Bool’sche Ausdruck (condition) wird ausgewertet; ist er true, so wird die
Anweisung (statement) ausgeführt. Ist er false, so wird die Anweisung nicht
ausgeführt und die Programmausführung mit der nächsten Anweisung hinter
der if-then Anweisung fortgesetzt.
4. Eine abweisende Schleife (while-Schleife):
Algorithmen und Datenstrukturen II
3
while(condition) statement
Der Bool’sche Ausdruck wird ausgewertet; ist er true, so wird die Anweisung
so lange ausgeführt, bis der Bool’sche Ausdruck false wird.
Algorithmen und Datenstrukturen II
4
while(condition) statement
Der Bool’sche Ausdruck wird ausgewertet; ist er true, so wird die Anweisung
so lange ausgeführt, bis der Bool’sche Ausdruck false wird.
5. Ein Block.
{ statement1; statement2; . . . }
Die Statements in der geschweiften Klammer werden von links nach rechts
nacheinander abgearbeitet.
Algorithmen und Datenstrukturen II
4
while(condition) statement
Der Bool’sche Ausdruck wird ausgewertet; ist er true, so wird die Anweisung
so lange ausgeführt, bis der Bool’sche Ausdruck false wird.
5. Ein Block.
{ statement1; statement2; . . . }
Die Statements in der geschweiften Klammer werden von links nach rechts
nacheinander abgearbeitet.
6. Eine Anweisung zum Schreiben auf der Standardausgabe:
System.out.println(...);
System ist eine Klasse, die klassenbezogene Methoden zur Darstellung des
Zustandes des Systems bereitstellt. out ist eine Klassenvariable der Klasse
System, ihr Inhalt ist der Standardausgabestrom. Die Methode println wird
Algorithmen und Datenstrukturen II
4
also auf das klassenbezogene Datenfeld out angewendet – es wird ein String
mit abschließendem Zeilenvorschub auf dem Standardausgabestrom
ausgegeben.
Algorithmen und Datenstrukturen II
5
also auf das klassenbezogene Datenfeld out angewendet – es wird ein String
mit abschließendem Zeilenvorschub auf dem Standardausgabestrom
ausgegeben.
7. Die leere Anweisung.
;
Es geschieht nichts.
Algorithmen und Datenstrukturen II
5
also auf das klassenbezogene Datenfeld out angewendet – es wird ein String
mit abschließendem Zeilenvorschub auf dem Standardausgabestrom
ausgegeben.
7. Die leere Anweisung.
;
Es geschieht nichts.
8. Die Deklaration eines eindimensionalen Feldes (Arrays) mit sofortiger
Initialisierung:
int[] array = new int[3];
deklariert ein Feld namens array, erzeugt ein Feld mit drei int-Komponenten
und weist dieses der Feldvariablen array zu. Beachte, dass die Dimension (3)
einer Feldvariablen nicht bei der Deklaration (int[] array) angegeben wird,
Algorithmen und Datenstrukturen II
5
sondern nur bei der Erzeugung (new int[3]). Die erste Komponente eines
Feldes hat den Index 0. Die Länge des Feldes kann aus dessen Datenfeld
length ausgelesen werden (array.length).
Algorithmen und Datenstrukturen II
6
sondern nur bei der Erzeugung (new int[3]). Die erste Komponente eines
Feldes hat den Index 0. Die Länge des Feldes kann aus dessen Datenfeld
length ausgelesen werden (array.length).
9. Die Zuweisung eines Wertes an die i-te Komponente eines Feldes, wobei
0 ≤ i ≤ array.length−1:
array[i] = expression;
Algorithmen und Datenstrukturen II
6
class Echo {
public static void main(String[] args) {
int i = 0;
while(i < args.length) {
System.out.println(args[i]);
i = i+1;
}
}
}
Algorithmen und Datenstrukturen II
7
class Echo {
public static void main(String[] args) {
int i = 0;
while(i < args.length) {
System.out.println(args[i]);
i = i+1;
}
}
}
> java Echo 10 2
10
2
>
Algorithmen und Datenstrukturen II
7
class BadAddOne {
public static void main(String[] args) {
int i = 0;
while(i < args.length) {
int wert = args[i];
wert = wert+1;
System.out.println(wert);
i = i+1;
}
}
}
Algorithmen und Datenstrukturen II
8
class BadAddOne {
public static void main(String[] args) {
int i = 0;
while(i < args.length) {
int wert = args[i];
wert = wert+1;
System.out.println(wert);
i = i+1;
}
}
}
Algorithmen und Datenstrukturen II
8
> javac BadAddOne.java
BadAddOne.java:6: Incompatible type for declaration.
Can’t convert java.lang.String to int.
int wert = args[i];
>
Algorithmen und Datenstrukturen II
9
class AddOne {
public static void main(String[] args) {
int i = 0;
while(i < args.length) {
int wert = Integer.parseInt(args[i]);
wert = wert+1;
System.out.println(wert);
i = i+1;
}
}
}
Algorithmen und Datenstrukturen II
10
class AddOne {
public static void main(String[] args) {
int i = 0;
while(i < args.length) {
int wert = Integer.parseInt(args[i]);
wert = wert+1;
System.out.println(wert);
i = i+1;
}
}
}
Algorithmen und Datenstrukturen II
10
> java AddOne 6 3 20
7
4
21
>
Algorithmen und Datenstrukturen II
11
Von Mini-Java zu Java
Jedes Mini-Java Programm ist ein Java Programm. In diesem Abschnitt werden die
Datentypen und imperativen Konstrukte von Java erläutert, die nicht bereits in
Mini-Java vorhanden sind.
Algorithmen und Datenstrukturen II
12
Elementare Datentypen
Algorithmen und Datenstrukturen II
13
Elementare Datentypen
Unicode: Java, als Sprache für das World Wide Web, benutzt einen 16-Bit
Zeichensatz, genannt Unicode. Die ersten 256 Zeichen von Unicode sind
identisch mit dem 8-Bit Zeichensatz Latin-1, wobei wiederum die ersten 128
Zeichen von Latin-1 mit dem 7-Bit ASCII Zeichensatz übereinstimmen.
Algorithmen und Datenstrukturen II
13
Elementare Datentypen
Unicode: Java, als Sprache für das World Wide Web, benutzt einen 16-Bit
Zeichensatz, genannt Unicode. Die ersten 256 Zeichen von Unicode sind
identisch mit dem 8-Bit Zeichensatz Latin-1, wobei wiederum die ersten 128
Zeichen von Latin-1 mit dem 7-Bit ASCII Zeichensatz übereinstimmen.
Algorithmen und Datenstrukturen II
13
Elementare Datentypen und deren Literale:
Algorithmen und Datenstrukturen II
14
Typ boolean
true und false
Typ int
29 (Dezimalzahl) oder
035 (Oktaldarstellung wegen führender 0) oder
0x1D (Hexadezimaldarstellung wegen führendem 0x) oder
0X1d (Hexadezimaldarstellung wegen führendem 0X)
Typ long
29L (wegen angehängtem l oder L)
Typ short
short i = 29; (Zuweisung, es gibt kein short-Literal)
Typ byte
byte i = 29; (Zuweisung, es gibt kein byte-Literal)
Typ double
18.0 oder 18. oder 1.8e1 oder .18E2
Typ float
18.0f (wegen angehängtem f oder F)
Typ char
’Q’, ’\u0022’, ’\u0b87’
Typ String
"Hallo" (String ist kein elementarer Datentyp; s. Kapitel ??)
Algorithmen und Datenstrukturen II
15
Typ boolean
true und false
Typ int
29 (Dezimalzahl) oder
035 (Oktaldarstellung wegen führender 0) oder
0x1D (Hexadezimaldarstellung wegen führendem 0x) oder
0X1d (Hexadezimaldarstellung wegen führendem 0X)
Typ long
29L (wegen angehängtem l oder L)
Typ short
short i = 29; (Zuweisung, es gibt kein short-Literal)
Typ byte
byte i = 29; (Zuweisung, es gibt kein byte-Literal)
Typ double
18.0 oder 18. oder 1.8e1 oder .18E2
Typ float
18.0f (wegen angehängtem f oder F)
Typ char
’Q’, ’\u0022’, ’\u0b87’
Typ String
"Hallo" (String ist kein elementarer Datentyp; s. Kapitel ??)
Algorithmen und Datenstrukturen II
15
Initialbelegungen: Während ihrer Deklaration kann eine Variable wie in Mini-Java
initialisiert werden.
final double PI = 3.141592654;
float radius = 1.0f;
Sind für Datenfelder einer Klasse keine Anfangswerte angegeben, so belegt
Java sie mit voreingestellten Anfangswerten. Der Anfangswert hängt vom Typ
des Datenfeldes ab:
Feld-Typ
Anfangswert
boolean
false
char
’\u0000’
Ganzzahl (byte, short, int, long)
0
Gleitkommazahl
+0.0f oder +0.0d
andere Referenzen
null
Algorithmen und Datenstrukturen II
16
Lokale Variablen
Lokale Variablen in einer Methode (oder einem Konstruktor oder einem
klassenbezogenen Initialisierungsblock) werden von Java nicht mit einem
Anfangswert initialisiert. Vor ihrer ersten Benutzung muss einer lokalen Variablen
ein Wert zugewiesen werden (ein fehlender Anfangswert ist ein Fehler).
Algorithmen und Datenstrukturen II
17
Kommentare
// Kommentar bis zum Ende der Zeile
/* Kommentar
zwischen */
Algorithmen und Datenstrukturen II
18
Kommentare
// Kommentar bis zum Ende der Zeile
/* Kommentar
zwischen */
Achtung: /* */ können nicht geschachtelt werden!
/* falsch
/* geschachtelter Kommentar */
*/
Algorithmen und Datenstrukturen II
18
Bool’sche Operatoren
&&
logisches und
||
logisches oder
!
logisches nicht
Algorithmen und Datenstrukturen II
19
Bool’sche Operatoren
&&
logisches und
||
logisches oder
!
logisches nicht
Die Auswertung eines Bool’schen Ausdrucks erfolgt von links nach rechts, bis der
Wert eindeutig feststeht. Folgender Ausdruck ist deshalb robust:
if(index>=0 && index<array.length && array[index]!=0) ...
Algorithmen und Datenstrukturen II
19
Bitoperatoren
Die Bitoperatoren & (und) und | (oder) sind definiert durch:
& 0
1
| 0 1
0
0
0
0
0 1
1
0
1
1
1 1
int-Zahlen werden durch diese Operatoren bitweise behandelt.
Algorithmen und Datenstrukturen II
20
Bitoperatoren
Die Bitoperatoren & (und) und | (oder) sind definiert durch:
& 0
1
| 0 1
0
0
0
0
0 1
1
0
1
1
1 1
int-Zahlen werden durch diese Operatoren bitweise behandelt.
Algorithmen und Datenstrukturen II
20
Beispiel 0.1 Es seien x und y folgendermaßen gewählt: x = 60 (in
Binärdarstellung 00111100) und y = 15 (binär: 00001111). In diesem Fall ist
x&y = 12 und x|y = 63:
x & y
x | y
00111100 (60)
00111100 (60)
& 00001111 (15)
| 00001111 (15)
00001100 (12)
00111111 (63)
Algorithmen und Datenstrukturen II
21
Inkrement und Dekrement
Man kann den Wert einer Variablen x (nicht den eines Ausdrucks) durch den
Operator ++ um 1 erhöhen bzw. durch - um 1 erniedrigen. Es gibt Präfix- und
Postfixschreibweisen, die unterschiedliche Wirkungen haben: Bei der
Präfixschreibweise wird der Wert zuerst modifiziert und danach der veränderte Wert
zurückgeliefert. Bei der Postfixschreibweise wird zuerst der Wert der Variablen
zurückgeliefert, dann wird sie modifiziert.
Algorithmen und Datenstrukturen II
22
int i = 10;
int j = i++;
System.out.println(j);
int i = 10;
int j = ++i;
System.out.println(j);
>
10
>
11
Der Ausdruck i++ ist gleichbedeutend mit i = i+1, jedoch wird i nur einmal
ausgewertet!
Algorithmen und Datenstrukturen II
23
Beispiel 0.2
(A)
arr[where()]++;
Die Methode where() wird einmal aufgerufen.
(B)
arr[where()] = arr[where()]+1;
Hierbei wird die Methode where() jedoch zweimal aufgerufen.
Algorithmen und Datenstrukturen II
24
Seiteneffekte
Seiteneffekte können hier sogar das Ergebnis beeinflussen: In dem Kontext arr[0]
= 0; arr[1] = 1; arr[2] = 2; und
private static int zaehler = 0;
private static int where() {
zaehler = zaehler+1;
return zaehler;
}
liefert (A) arr[1] = 2 bzw. (B) arr[1] = 3.
Algorithmen und Datenstrukturen II
25
Zuweisungsoperatoren
i += 2; ist gleichbedeutend mit i = i+2; außer, dass der Ausdruck auf der linken
Seite von i += 2; nur einmal ausgewertet wird (vgl. Inkrement und Dekrement).
Entsprechend sind -=, &= und |= definiert.
Algorithmen und Datenstrukturen II
26
Die nichtabweisende Schleife
Zusätzlich zur abweisenden Schleife gibt es eine nichtabweisende Schleife in Java:
do
statement
while(condition);
Die condition wird erst nach der Ausführung von statement ausgewertet. Solange
sie true ist, wird statement wiederholt.
Algorithmen und Datenstrukturen II
27
for-Schleife
for(init-statement; condition; increment-statement)
statement
Algorithmen und Datenstrukturen II
28
for-Schleife
for(init-statement; condition; increment-statement)
statement
ist gleichbedeutend mit (mit Ausnahme vom Verhalten bei continue):
{
init-statement
while(condition) {
statement
increment-statement
}
}
Algorithmen und Datenstrukturen II
28
Übliche Verwendung der for-Schleife:
for(int i=0; i<=10; i++) {
System.out.println(i);
}
Der Gültigkeitsbereich der (Lauf-)Variablen i beschränkt sich auf die for-Schleife!
Algorithmen und Datenstrukturen II
29
Übliche Verwendung der for-Schleife:
for(int i=0; i<=10; i++) {
System.out.println(i);
}
Der Gültigkeitsbereich der (Lauf-)Variablen i beschränkt sich auf die for-Schleife!
int i = 0;
for(int i=0; i<=10; i++) {
System.out.println(i);
}
ist jedoch nicht möglich, da die Variable i vorher schon deklariert wurde.
Algorithmen und Datenstrukturen II
29
Die Initialisierungs- bzw. Inkrementanweisung einer for-Schleife kann eine durch
Kommata getrennte Liste von Ausdrücken sein. Diese werden von links nach rechts
ausgewertet.
Beispiel 0.3 (Arnold & Gosling [?], S. 144)
public static int zehnerPotenz(int wert) {
int exp, v;
for(exp=0,v=wert; v>0; exp++, v=v/10)
; // leere Anweisung
return exp;
}
Algorithmen und Datenstrukturen II
30
Alle Ausdrücke dürfen auch leer sein; dies ergibt eine Endlosschleife:
for(;;) {
System.out.println("Hallo");
}
Algorithmen und Datenstrukturen II
31
if-then-else Anweisung
if(condition)
statement1
else
statement2
Algorithmen und Datenstrukturen II
32
If-else-Zuordnung
public double positiveSumme(double[] werte) {
double sum = 0.0;
if(werte.length > 1)
for(int i=0; i<werte.length; i++)
if(werte[i] > 0)
sum += werte[i];
else // hoppla!
sum = werte[0];
return sum;
}
Algorithmen und Datenstrukturen II
33
public double positiveSumme(double[] werte) {
double sum = 0.0;
if(werte.length > 1)
for(int i=0; i<werte.length; i++)
if(werte[i] > 0)
sum += werte[i];
else // hoppla!
sum = werte[0];
return sum;
}
Algorithmen und Datenstrukturen II
34
public double positiveSumme(double[] werte) {
double sum = 0.0;
if(werte.length > 1) {
for(int i=0; i<werte.length; i++)
if(werte[i] > 0)
sum += werte[i];
}
else {
sum = werte[0];
}
return sum;
}
Algorithmen und Datenstrukturen II
35
Mehrdimensionale Felder
Mehrdimensionale Felder werden in Java durch Felder von Feldern realisiert.
Beispiel 0.4 (Jobst [?], S. 37)
Algorithmen und Datenstrukturen II
36
public class Array2Dim {
public static void main(String[] args) {
int[][] feld = new int[3][3];
//Weise feld[i][j] den Wert (i+1)*10+j zu
for(int i=0; i<feld.length; i++) {
for(int j=0; j<feld[i].length; j++) {
feld[i][j] = (i+1)*10+j;
System.out.print(feld[i][j]+" ");
}
System.out.println();
}
}
}
Algorithmen und Datenstrukturen II
37
> java Array2Dim
10 11 12
20 21 22
30 31 32
Algorithmen und Datenstrukturen II
38
Beispiel 0.5 (Jobst [?], S. 38)
Algorithmen und Datenstrukturen II
39
public class DemoArray {
public static void main(String[] args) {
int[][] feld = new int[3][];
for(int i=0; i<feld.length; i++) {
feld[i] = new int[i+1];
for(int j=0; j<feld[i].length; j++) {
feld[i][j] = (i+1)*10+j;
System.out.print(feld[i][j]+" ");
}
System.out.println();
}
}
}
Algorithmen und Datenstrukturen II
40
> java DemoArray
10
20 21
30 31 32
Algorithmen und Datenstrukturen II
41
Felder können bei ihrer Deklaration sofort initialisiert werden:
Algorithmen und Datenstrukturen II
42
Beispiel 0.6 (Jobst [?] S. 39)
public class DemoFeldInitial {
public static void main(String[] args) {
int[][] feld = {{1,2,3},{4,5},{7,8,9,10}};
//Ausgabe des Feldes
for(int i=0; i<feld.length; i++) {
for(int j=0; j<feld[i].length; j++)
System.out.print(feld[i][j]+" ");
System.out.println();
}
}
}
Algorithmen und Datenstrukturen II
> java DemoFeldInitial
43
switch-Anweisung
switch(expression) {
case const1: statement1 break;
case const2: statement2 break;
...
default: statement
}
Algorithmen und Datenstrukturen II
44
Beispiel 0.7 (Jobst [?], S. 15)
Algorithmen und Datenstrukturen II
45
public class DemoFuerSwitch {
public static void main (String[] args) {
for(int i=0; i<=10; i++)
switch(i) {
case 1:
case 2:
System.out.println(i+" Fall 1,2");
case 3:
System.out.println(i+" Fall 3");
case 7:
System.out.println(i+" Fall 7");
break;
default:
System.out.println(i+" sonst");
}
}
Algorithmen und Datenstrukturen II
// Weiter bei Fall 3
// Weiter bei Fall 7
46
}
Algorithmen und Datenstrukturen II
47
Algorithmen und Datenstrukturen II
48
>
0
1
1
1
2
2
2
3
3
4
5
6
7
8
9
java DemoFuerSwitch
sonst
Fall 1,2
Fall 3
Fall 7
Fall 1,2
Fall 3
Fall 7
Fall 3
Fall 7
sonst
sonst
sonst
Fall 7
sonst
sonst
Algorithmen und Datenstrukturen II
49
10 sonst
>
Algorithmen und Datenstrukturen II
50
Herunterladen