• Keine Ergebnisse gefunden

252-0027 Einführung in die Programmierung I 10.0 Systema=sches Programmieren

N/A
N/A
Protected

Academic year: 2022

Aktie "252-0027 Einführung in die Programmierung I 10.0 Systema=sches Programmieren"

Copied!
48
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

252-0027

Einführung in die Programmierung I 10.0 Systema=sches Programmieren

Thomas R. Gross

Department Informa=k ETH Zürich

Copyright (c) Pearson 2013 and Thomas Gross 2016 All rights reserved.

(2)

Uebersicht

!  10.0 Beispiel

!  10.1 Darstellung von Variablen und Objekten

!  10.1 AsserIons

!  10.2 Pre/Post CondiIons (für Statement)

!  10.3 Pre/Post CondiIons (für Folgen von Statements)

2

(3)

RaIonale Zahlen

!  Beispiel einer sinnvollen Klasse

!  Idee: Klasse Rational für die Darstellung von raIonalen Zahlen

!  Reelle Zahl die als Verhältnis zweier ganzer Zahlen dargestellt wird

!  Warum: Die double Darstellung ist nur eine ApproximaIon

double x = (1.0 / 2.0) + (1.0/3.0) + (1.0/6.0);

System.out.println(x);

(4)

RaIonale Zahlen

!  Beispiel einer sinnvollen Klasse

!  Idee: Klasse Rational für die Darstellung von raIonalen Zahlen

!  Reelle Zahl die als Verhältnis zweier ganzer Zahlen dargestellt wird

!  Warum: Die double Darstellung ist nur eine ApproximaIon

double x = (1.0 / 2.0) + (1.0/3.0) + (1.0/6.0);

System.out.println(x);

Output: 0.9999999999999999

(5)

RaIonale Zahlen

!  Exakte Darstellung

!  0.1 == 1 / 10

!  Klasse RaIonal unterstützt die üblichen arithmeIschen OperaIonen

5 ab + c

d = ad +bc bd

abc

d = ad – bc bd

ab x c

d = ac

ab c d = . .

bd

ad bc Addition:"

Subtraction:"

Multiplication:"

Division:"

(6)

ImplementaIon von RaIonal

!  Vorschau auf die nächsten Seiten

!  Verschiedene Konstruktoren

!  Overloading

!  Default: 0, ein Argument: ganze Zahl; zwei Argumente: QuoIent

!  Die Konstruktoren stellen sicher dass Zähler und Nenner auf die kleinst möglichen Werte “gekürzt” werden

!  Da sich die Instanzen der Klasse nie ändern bleibt diese Eigenschae

bestehen

(7)

ImplementaIon von Rational

!  Die OperaIonen (add, subtract, mulIply, und divide) für die vier GrundoperaIonen verwenden die dot-NotaIon –

!  Einer der Operanden ist der implizite Parameter, der andere der in der DefiniIon aufgeführte Parameter

!  Auf den impliziten Parameter wird durch this zugegriffen.

(8)

/**

* The Rational class is used to represent rational numbers, which * are defined to be the quotient of two integers.

*/

public class Rational {

/** Creates a new Rational initialized to zero. */

public Rational() { this(0);

} /**

* Creates a new Rational from the integer argument.

* @param n The initial value */

public Rational(int n) { this(n, 1);

}

Klasse RaIonal

skip code

(9)

/**

* The Rational class is used to represent rational numbers, which * are defined to be the quotient of two integers.

*/

public class Rational {

/** Creates a new Rational initialized to zero. */

public Rational() { this(0);

} /**

* Creates a new Rational from the integer argument.

* @param n The initial value */

public Rational(int n) { this(n, 1);

} /**

* Creates a new Rational with the value x / y.

* @param x The numerator of the rational number * @param y The denominator of the rational number */

public Rational(int x, int y) {

int g = gcd(Math.abs(x), Math.abs(y));

num = x / g;

den = Math.abs(y) / g;

if (y < 0) num = -num;

} /**

* Adds the rational number r to this one and returns the sum.

* @param r The rational number to be added * @return The sum of the current number and r */

public Rational add(Rational r) {

return new Rational(this.num * r.den + r.num * this.den, this.den * r.den);

}

Klasse Rational

(10)

/**

* Creates a new Rational with the value x / y.

* @param x The numerator of the rational number * @param y The denominator of the rational number */

public Rational(int x, int y) {

int g = gcd(Math.abs(x), Math.abs(y));

num = x / g;

den = Math.abs(y) / g;

if (y < 0) num = -num;

} /**

* Adds the rational number r to this one and returns the sum.

* @param r The rational number to be added * @return The sum of the current number and r */

public Rational add(Rational r) {

return new Rational(this.num * r.den + r.num * this.den, this.den * r.den);

} /**

* Subtracts the rational number r from this one.

* @param r The rational number to be subtracted

* @return The result of subtracting r from the current number */

public Rational subtract(Rational r) {

return new Rational(this.num * r.den - r.num * this.den, this.den * r.den);

} /**

* Multiplies this number by the rational number r.

* @param r The rational number used as a multiplier

* @return The result of multiplying the current number by r */

public Rational multiply(Rational r) {

return new Rational(this.num * r.num, this.den * r.den);

}

Klasse Rational

skip code

(11)

/**

* Subtracts the rational number r from this one.

* @param r The rational number to be subtracted

* @return The result of subtracting r from the current number */

public Rational subtract(Rational r) {

return new Rational(this.num * r.den - r.num * this.den, this.den * r.den);

} /**

* Multiplies this number by the rational number r.

* @param r The rational number used as a multiplier

* @return The result of multiplying the current number by r */

public Rational multiply(Rational r) {

return new Rational(this.num * r.num, this.den * r.den);

} /**

* Divides this number by the rational number r.

* @param r The rational number used as a divisor

* @return The result of dividing the current number by r */

public Rational divide(Rational r) {

return new Rational(this.num * r.den, this.den * r.num);

} /**

* Creates a string representation of this rational number.

* @return The string representation of this rational number */

public String toString() { if (den == 1) {

return "" + num;

} else {

return num + "/" + den;

}

Klasse Rational

skip code

(12)

/**

* Divides this number by the rational number r.

* @param r The rational number used as a divisor

* @return The result of dividing the current number by r */

public Rational divide(Rational r) {

return new Rational(this.num * r.den, this.den * r.num);

} /**

* Creates a string representation of this rational number.

* @return The string representation of this rational number */

public String toString() { if (den == 1) {

return "" + num;

} else {

return num + "/" + den;

} } /**

* Calculates the greatest common divisor using Euclid's algorithm.

* @param x First integer * @param y Second integer

* @return The greatest common divisor of x and y */

private int gcd(int x, int y) { int r = x % y;

while (r != 0) { x = y;

y = r;

r = x % y;

}

return y;

}

/* Private instance variables */

private int num; /* The numerator of this Rational */

private int den; /* The denominator of this Rational */

}

Klasse Rational

skip code

(13)

SimulaIon

!  Wir wollen sehen wie ein einfaches Programm drei raIonale Zahlen addiert

!  Danach werfen wir einen Blick hinter die Kulissen

!  Das Ergebnis dieser Berechnung soll(te) exakt sein 1 sein

!  Im Gegensatz zur Rechnung mit double

1 2

1 3

1

+ + 6

(14)

c sum b

a public void run(){

Rational a = new Rational(1, 2);

Rational b = new Rational(1, 3);

Rational c = new Rational(1, 6);

Rational sum = a.add(b).add(c);

println(a + " + " + b + " + " + c + " = " + sum);

}

TestRational

5 6

1 2

1 3

1 6

1 1

temporary result

1/2 + 1/3 + 1/6 = 1

skip simula9on

public Rational(int x, int y) {

int g = gcd(Math.abs(x), Math.abs(y));

num = x / g;

den = Math.abs(y) / g;

if (y < 0) num = -num;

}

y g

x this

num

den 1 2 1

1 2

public Rational(int x, int y) {

int g = gcd(Math.abs(x), Math.abs(y));

num = x / g;

den = Math.abs(y) / g;

if (y < 0) num = -num;

}

y g

x this

num

den 1 3 1

1 3

public Rational(int x, int y) {

int g = gcd(Math.abs(x), Math.abs(y));

num = x / g;

den = Math.abs(y) / g;

if (y < 0) num = -num;

}

y g

x this

num

den 1 6 1

1 6

public Rational add(Rational r) {

return new Rational( this.num * r.den + r.num * this.den , this.den * r.den );

}

this

num den

1 2

r

num den

1 3 6

5 public Rational(int x, int y) {

int g = gcd(Math.abs(x), Math.abs(y));

num = x / g;

den = Math.abs(y) / g;

if (y < 0) num = -num;

}

y g

x this

num

den 5 6 1

5 6

public Rational add(Rational r) {

return new Rational( this.num * r.den + r.num * this.den , this.den * r.den );

}

this

num den

5 6

r

num den

1 6 36

36 public Rational(int x, int y) {

int g = gcd(Math.abs(x), Math.abs(y));

num = x / g;

den = Math.abs(y) / g;

if (y < 0) num = -num;

}

y g

x this

num

den 36 36 36

1 1

c sum

b a

public void run(){

Rational a = new Rational(1, 2);

Rational b = new Rational(1, 3);

Rational c = new Rational(1, 6);

Rational sum = a.add(b).add(c);

System.out.println(a + " + " + b + " + " + c + " = " + sum);

}

1 2

1 3

1 6

1 1

Based on Eric Roberts, The Art and Science of Java

(15)

Darstellungsfragen

!  Warum ergibt eigentlich

double x = (1.0 / 2.0) + (1.0/3.0) + (1.0/6.0);

System.out.println(x);

Output: 0.9999999999999999

!  Werte müssen im Speicher des Computers dargestellt werden

!  Speicher organisiert als eine Gruppe von Bits

!  Bit: binary digit

20

(16)

Darstellungsfragen

!  Ein Bit hat zwei Zustände: normalerweise mit 0 und 1 bezeichnet

!  Gruppen von 8 Bits bilden ein Byte

!  Nur zur Vereinfachung der ImplementaIon des Rechners

!  (Ganze und reelle) Zahlen werden in einer Folge von Bytes gespeichert

!  Eine Folge von Bytes heisst ein Word. Computer können oe ein Word schnell verarbeiten (schneller als 4 beliebige aufeinanderfolgende Bytes)

21

0 0 1 0 1 0 1 0

(17)

Darstellungsfragen

!  Eine ganze Zahl wird oe in einem Word aus vier Bytes gespeichert

!  Manche Computer bezeichnenals ein Word als Folge von 8 Bytes

!  Und speichern dann eine ganze Zahl in 64 Bits

22

(18)

Binärdarstellung

!  Wenn wir die Bits eines Bytes als Binärzahl interpreIeren so können wir in einem Byte eine ganze Zahl darstellen

!  Binärzahlen sind wie Dezimalzahlen aber verwenden eine andere Basis

!  Dezimalzahlen Basis == 10

!  Das Gewicht einer Ziffer ist das 10-fache des Gewichts der Ziffer zur Rechten

!  Binärzahlen Basis == 2

!  Das Gewicht einer Ziffer ist das Doppelte des Gewichts der Ziffer

zur Rechten

(19)

Binärdarstellung

0 0 1 0 1 0 1 0

0 × 1 0

1 × 2 2

0 × 4 0

1 × 8 8

0 × 16 0

1 × 32 32

0 × 64 0

0 × 128 0

42

(20)

Darstellungen einer Zahl

!  Die Binärdarstellung 00101010 ist äquivalent zur Dezimaldarstellung 42

!  Wenn die Basis wichIg ist, dann wird sie als Iefgestellt

!  00101010

2

= 42

10

!  Aber es ist immer dieselbe Zahl

!  Zahlen haben keine Basis, nur Darstellungen

25

(21)

Oktal- und Hexadezimalschreibweise

!  8 Bits sind mühsam zu schreiben

!  Leicht etwas zu übersehen (00101010 oder 00101011)

!  InformaIker verwenden daher oe die Oktalschreibweise (oder die Hexadezimalschreibweise)

!  Oktal: Ziffern 0 … 7

!  Hexadezimal: Ziffern 0 …. 9 A B C D E F

26

(22)

Oktal- und Hexadezimalschreibweise

!  Die Zahl 00101010 in Oktal- und Hexadezimalschreibweise

!  Der Vorteil dieser Darstellungen ist dass sie leicht in die Binärdarstellung umgewandelt werden können

!  Jede Ziffer kann einzeln umgewandelt werden

28 2 x 1 2

5 x 8 40

5 2

42

octal

10 x 1 10 02 x16 32

2 A

42

hexadecimal

(23)

Uebung: Zahlendarstellungen

!  Was ist die Dezimaldarstellung für diese Zahlen

100012 1778

AD

16

1 x 1 1 0 x 2 0 0 x 4 0 0 x 8 0 1 x 16 1

1 0 0 0 1

17 17

(24)

Uebung: Zahlendarstellungen

!  Was ist die Dezimaldarstellung für diese Zahlen

100012 1778

AD

16

7 x 1 7 7 x 8 56

7 7

127

1

1 x 64 64 127

(25)

Uebung: Zahlendarstellungen

!  Was ist die Dezimaldarstellung für diese Zahlen

100012 1778

AD

16

13 x 1 13 10 x16 160

A D

173 173

(26)

!  Dies sind die ersten 16 Bits jeder .class file

!  Was ist diese Zahl in HexadezimalnotaIon?

1 1 0 0 1 0 1 0 1 1 1 1 1 1 1 0

1 1 0 0 1 0 1 0 1 1 1 1 1 1 1 0 F

CAFE

16

1 1 0 0 1 0 1 0 1 1 1 1 1 1 1 0

Start jeder .class File

od –t x1 Foo.class

[Linux]

(27)

Speicher und Addressen

•  Jedes Byte im Speicher hat eine Adresse – eine Zahl zwischen 0 und einer Obergrenze

•  Im Beispiel sind Adressen in Hexadezimal- notaIon mit 4 Stellen angezeigt

•  Im Java System sind die Adressen unsichtbar und das Bespiel zeigt willkürliche Werte

•  IllustraIonen mit Bytes sind unübersichtlich daher fassen wir 4 Bytes zu einem Wort zusammen und zeigen immer Wortadressen (die dann in 4-er Schrixen ansteigen)

0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B

FFF4 FFF5 FFF6 FFF7 FFF8 FFF9 FFFA FFFB FFFC FFFD FFFE FFFF 0000 0004 0008 000C 0010 0014 0018 001C 0020 0024 0028 002C

FFD0 FFD4 FFD8 FFDC FFE0 FFE4 FFE8 FFEC FFF0 FFF4 FFF8 FFFC . . . . . .

(28)

Speicherplatz für Variable

!  Für eine deklarierte Variable muss das Laufzeitsystem Speicherplatz finden

!  Der Speicher des Computers ist in verschiedene Bereiche unterteilt

!  Genauer: der Teil des Speichers den unser Java Programm nutzen darf

!  Ein Bereich ist reserviert für die Variablen die immer

exisiteren (während der gesamten Laufzeit des Programms)

!  Dazu gehörten Konstanten, InformaIonen über Klassen, etc.

!  Dieser Bereich heisst “staIc data”

(29)

Speicherplatz für Variable

!  Objekte die durch den new Operator erschaffen werden, werden im “heap” (Halde) abgelegt.

!  Für jede aufgerufene Methode stellt das Laufzeitsystem einen neuen Bereich zur Verfügung

!  Dieser heisst “Stack Frame”

!  Alle Stack Frames werden in einem Stack organisiert

!  Variable, die in einer Methode deklariert wurden, finden Platz im Stack Frame

!  Parameter überigens auch …

36

(30)

staIc data

0000

stack

heap

(31)

!  Manchmal sind Stack und Heap so angeordnet, dass sie gegeneinander wachsen

!  Jede Region kann so gross wie möglich werden

staIc data

0000

stack

FFFF

heap

(32)

Stack und Heap

!  Ein einfaches Modell dieser Bereiche hile, verschiedene Aspekte von Java zu verstehen

!  Da Programme oe in einer Methode Variable deklarieren, die auf Instanzen verweisen, müssen wir sowohl den Heap als auch den Stack im Auge behalten

!  In den folgenden Folien zeigen wir links den Heap und rechts den Stack

!  Getrennt durch Linie

!  Stack-Heap Diagramm

39

(33)

Stack und Heap

!  Wenn eine Methode aufgerufen wird, dann muss das neue Stack Frame genug Platz für alle (lokalen) Variablen haben

!  Wenn eine Methode ferIg ist, dann kann ihr Stack Frame wiederverwendet werden

!  Wenn eine ObjekInstanz geschaffen wird, dann brauchen wir Speicherplatz für alle Axribute (Zustandsvariablen)

!  Dazu brauchen wir extra Platz für Java-interne Zwecke – Overhead den

wir nicht kontrollieren können

40

(34)

Verweise (References) auf Objekte

!  Für jede Instanz hält das Java System die Adresse der Instanz fest

!  Diese Adresse (ggf. mit weiteren InformaIonen) wird in einer Variable gespeichert (wir sagen dazu auch “Reference variable” – die Variable enthält den Verweis, d.h. die Reference, auf ein Objekt).

!  Nehmen wir an, eine Methode enthält die DeklaraIon

Rational r1 = new Rational(1, 2);

für die Klasse Rational (wie vorher eingeführt)

41

(35)

Verweise (References) auf Objekte

!  Wenn die DeklaraIon

Rational r1 = new Rational(1, 2);

ausgeführt wird, brauchen wir Platz für eine neue Rational Instanz.

!  Nehmen wir an diesen finden wir mit der Adresse 1000

42

(36)

Verweise (References) auf Objekte

!  Wenn die DeklaraIon

Rational r1 = new Rational(1, 2);

ausgeführt wird, brauchen wir Platz für eine neue Rational Instanz.

!  Nehmen wir an diesen finden wir mit der Adresse 1000

!  Die Variable r1 wird im Stack Frame gespeichert und erhält den Wert 1000 – die Adresse der neuen Instanz

45

heap

den 2 num 1

1008 1004 1000

stack

1000

r1 FFFC

(37)

In Zeitlupe

skip simulation a

b c sum

FFFC FFF8 FFF4 FFF0 FFEC

1000 100C 1018 1030

TestRa=onal

stack

This object is a temporary value used only during the calculation.

1/2 + 1/3 + 1/6 = 1

public void run(){

Rational a = new Rational(1, 2);

Rational b = new Rational(1, 3);

Rational c = new Rational(1, 6);

Rational sum = a.add(b).add(c);

println(a + " + " + b + " + " + c + " = " + sum);

}

den 1 num 1 den 6 num 5 den 6 num 1 den 3 num 1 den 2 num 1

public Rational add(Rational r) {

return new Rational( this.num * r.den + r.num * this.den , this.den * r.den );

} 6

5

1 3 1 2

public Rational add(Rational r) {

return new Rational( this.num * r.den + r.num * this.den , this.den * r.den );

} 36

36

heap

1038 1034 1030 102C 1028 1024 1020 101C 1018 1014 1010 100C 1008 1004 1000

1000 100C this

r

FFE8 FFE4 FFE0 1000

100C 1024 1018

This stack frame is created for the run method.

This stack frame is created for the add method.

All objects are created in the heap.

TestRa=onal 1/2 + 1/3 + 1/6 = 1

public void run(){

Rational a = new Rational(1, 2);

Rational b = new Rational(1, 3);

Rational c = new Rational(1, 6);

Rational sum = a.add(b).add(c);

System.out.println(a + " + " + b + " + " + c + " = " + sum);

}

den 1 num 1 den 6 num 5 den 6 num 1 den 3 num 1 den 2 num 1

heap stack

a b c sum

FFFC FFF8 FFF4 FFF0 FFEC

1000 100C 1018 1030

1038 1034 1030 102C 1028 1024 1020 101C 1018 1014 1010 100C 1008 1004 1000

(38)

Explizite Pointer

den 1 num 1 den 6 num 5 den 6 num 1 den 3 num 1 den 2 num 1

heap stack

a b c sum

FFFC FFF8 FFF4 FFF0 FFEC

1000 100C 1018 1030

1038 1034 1030 102C 1028 1024 1020 101C 1018 1014 1010 100C 1008 1004 1000

!  Die Skizze links zeigt den Zustand des Speichers am Ende der Methode run aus TestRational .

!  Das Bild rechts zeigt den selben Zustand mit einem Pfeil (“Pointer”) anstelle der Adresse (Pointer Modell)

den 1 num 1 den 6 num 5 den 6 num 1 den 3 num 1 den 2 num 1

a b c sum

heap stack

(39)

Adressen vs. Pointer

den 1 num 1 den 6 num 5 den 6 num 1 den 3 num 1 den 2 num 1

heap stack

a b c sum

FFFC FFF8 FFF4 FFF0 FFEC

1000 100C 1018 1030

1038 1034 1030 102C 1028 1024 1020 101C 1018 1014 1010 100C 1008 1004 1000

Beide Skizzen (mit Adressen oder Pointern) zeigen den selben Zustand aber betonen unterschiedliche Aspekte.

–  Adressen verdeutlichen dass Verweise (References) eine Zahl enthalten.

den 1 num 1 den 6 num 5 den 6 num 1 den 3 num 1 den 2 num 1

a b c sum

heap stack

–  Das Pointer Modell betont die Beziehung zwischen Referenz(variable)

und Objekt(instanz).

(40)

Nicht-erreichbare Objekte

Das Pointer Modell macht klar das es keinen Verweis auf die Rational Instanz 5/6 gibt. Dieser Wert ist jetzt “Garbage”.

Das Java Laufzeitsystem führt von Zeit zu Zeit eine Speicherbereini- gung durch (“garbage collec9on”) – automaIsch

den 1 num 1 den 6 num 5 den 6 num 1 den 3 num 1 den 2 num 1

a b c sum

heap stack

Instanz die temporär gebraucht wurde aber jetzt unerreichbar ist.

(41)

Uebung: Stack-Heap Diagramm

public void run() {

Point p1 = new Point(0, 0);

Point p2 = new Point(200, 200);

Line line = new Line(p1, p2);

}

public class Point {

public Point(int x, int y) { cx = x;

cy = y;

}

. . . other methods appear here . . . private int cx;

private int cy;

}

Gegeben sind Klassen Point und Line wie folgt

public class Line {

public Line(Point p1, Point p2) { start = p1;

finish = p2;

}

. . . other methods appear here . . . private Point start;

private Point finish;

}

Zeichnen Sie ein Stack-Heap Diagramm für den Zustand

des Speichers bevor die Methode run auyört.

(42)

Lösung

100C finish

1000 start

cy 200 cx 200 cy 0 cx 0

heap stack

p1 p2 line

FFFC FFF8 FFF4 FFF0 1000

100C 1018

1020 101C 1018 1014 1010 100C 1008 1004 1000

finish start cy 200 cx 200 cy 0 cx 0

p1 p2 line

heap stack

Address Model Pointer Model

(43)

Basistypen vs Objekte

!  Ein Basistyp Parameter wird nach den Regeln der Value Seman9cs übergeben.

!  Ein Parameter für eine Referenzvariable folgt den Regeln der Reference Seman9cs.

!  Nur auf den ersten Blick scheint es, dass Basistypen und Referenztypen unterschiedlich behandelt werden.

52

(44)

!  Wenn wir eine Basistyp Variable als Parameter übergeben, dann kopieren wir den Wert der Variable

!  Veränderungen in der Methode haben daher keine Wirkung

!  Wenn wir ein Referenzvariable als Parameter übergeben, so kopieren wir die Referenz (mit der Adresse)

!  Daher können wir die Instanz, die wir über die Adresse erreichen, verändern

!  Entweder über Accessor/Mutator Methoden oder durch direkten Zugriff auf ein Axribut

53

(45)

Verantwortlichkeiten

!  Sehen wir uns nochmal die Methode gcd (in Rational ) an:

/**

* Calculates the greatest common divisor * using Euclid's algorithm.

* @param x First integer * @param y Second integer

* @return The greatest common divisor of x and y */

int gcd(int x, int y) { int r = x % y;

while (r != 0) { x = y;

y = r;

r = x % y;

}

return y;

}

54

(46)

int gcd(int x, int y) { int r = x % y;

while (r != 0) { x = y;

y = r;

r = x % y;

}

return y;

}

!  Was für Annahmen macht diese Methode?

!  Liefert sie immer das gewünschte Ergebnis?

!  Was für Fälle sollten wir untersuchen?

!  Schreiben Sie die Fälle auf, die Sie für "interesssant" halten

!  Simulieren Sie die Ausführung

55

(47)

Verantwortlichkeiten

!  Diese ImplementaIon des ggT erwartet

!  x ≥ 0

!  y > 0

!  Wer ist dafür "verantwortlich"?

!  Klient?

!  (OK, hier ist der Klient die selbe Klasse Rational)

!  Die Methode?

56

(48)

Verantwortlichkeiten

!  (Teil)Lösung hier

gcd(Math.abs(x), Math.abs(y));

!  Kommentar wäre nicht verfehlt

!  gcd kann davon ausgehen dass x ≥ 0

!  "x ≥ 0" ist eine Aussage die hier immer gilt

!  Nicht gelöst ist dass y ≠ 0 sein muss

!  Beispiel soll nicht überladen werden

57

Referenzen

ÄHNLICHE DOKUMENTE

§ Programm: Folge von Anweisungen, die von einem Computer ausgeführt werden (können).. § Programm realisiert

§ Wenn zwei Operatoren die selbe Rang Ordnung haben, dann entscheidet die Assoziativität.. § Wenn zwei Operatoren die selbe Rang

§ Eine Aussage gilt für den Zustand eines Programms wenn die Auswertung der Aussage (des Ausdrucks) mit dem Zustand das Ergebnis true ergibt. § Die Auswertung jedes Variable ergibt

§ Eine Aussage gilt für den Zustand eines Programms wenn die Auswertung der Aussage (des Ausdrucks) mit dem Zustand das Ergebnis true ergibt.. § Die Auswertung jedes Variable

§ Wenn eine Methode einen Parameter erwartet dann muss dieser auch übergeben werden. printPunkte(); // ERROR: parameter value

§ Invariante und der Schleifen Test (wenn er wahr ist) müssen stark genug sein um zu zeigen dass die Postcondition des Rumpfs auch die Invariante impliziert.. § Invariante und

§ Wenn eine Methode aufgerufen wird, dann muss das neue Stack Frame genug Platz für alle (lokalen) Variablen haben. § Wenn eine Methode fertig ist, dann kann ihr Stack Frame

!  Schiedsrichter entscheidet ob das Symbol legal ist oder nicht (für diese EBNF Beschreibung).?. !  Genaue