next up previous contents
Next: Objektorientierte Programmierkonzepte Up: No Title Previous: Grundlagen

Subsections

Allgemeine Programmierkonzepte

Erzeugen, Compilieren und Ausführen von Java-Programmen

Der Java-Compiler

Der Java-Compiler übersetzt Java-Quelltexte in Java-Byte-Code. Der Aufruf erfolgt nach der Syntax:

javac {Optionen} Dateiname

Dabei muß der Dateiname mit dem Suffix .java enden und das Präfix muß gleich dem Klassennamen der (Haupt-)Klasse sein, die in der Datei definiert wird.

Optionen sind zur Zeit allerdings noch nicht erforderlich.

Der Java-Interpreter

Der Java-Interpreter führt Java-Byte-Code aus. Er ist für eigenständige Programme (keine Applets) gedacht. Sie müssen eine statische Methode mit der Signatur

public static void main(String[] arg)

enthalten. Der Aufruf genügt folgender Syntax:

java {Optionen} Klassenname {Argumente}.

Optionen sind zur Zeit allerdings noch nicht erforderlich.

Die Environment-Variable CLASSPATH

Die Environment-Variable CLASSPATH gibt eine Menge von Pfaden an, in denen der Compiler und der Interpreter nach bestimmten vordefinierten Informationen suchen. Auf den ALPHA-Cluster der ARBI sollte die Variable zur Zeit folgenden Wert haben:

.:/usr/local/lib/jdk-1.0.2

Beispiel

1.
Tippen Sie mit Hilfe eines Editors folgendes Java-Programm ein und speichern Sie es in einer Datei namens World.java ab:
import java.io.*;

public class World {
  public static void main(String[] arg) {
    try {
      System.out.println("Hello world!");
    }
    catch (Exception e) {}
  }
}
2.
Compilieren Sie das Programm mit dem Befehl: javac World.java.

3.
Führen Sie das Programm mit dem Interpretere aus: java World

4.
Auf Ihrem Bildschirm müßte die Ausgabe Hello world! erscheinen.

Symbole des Java-Vokabulars

Zeichensätze

Java ist in Unicode geschrieben. Wir werden aber zunächst so tun, als wenn nur der ASCII-Code verwendet werden dürfte.

Kommentare

In Java gibt es drei Arten von Kommentaren:

Token

Die Token einer Sprache, auch Lexeme genannt, sind die Wörter, auf denen sie basiert.

Token in Java sind:

In Java haben die Wortzwischenräume - dazu zählen Leerzeichen, Tabulatoren, Zeilenvorschub- und Seitenvorschubzeichen - keine Bedeutung. Sie werden nicht als Token betrachtet sondern dienen lediglich zur Trennung von Token.

Wortzwischenräume sind zur Trennung von Token untereinander notwendig.

Schlüsselwörter

Schlüsselwörter der Programmiersprache Java sind reserviert, d.h. sie dürfen nicht als Bezeichner verwendet werden. Folgende Wörter sind Schlüsselwörter:

Bezeichner  

Bezeichner werden zur Benennung von deklarierten Einheiten (wie Variablen oder Methoden) und Labeln verwendet. Bezeichner müssen in Java mit einem Buchstaben, einem Unterstrich (_) oder einen Dollarzeichen ($) beginnen, dem weitere Buchstaben und Ziffern folgen können.

Groß- und Kleinschreibung sind in Java von Bedeutung.

Einfache Typen  

Vordefinierte Datentypen in Java sind:

Literale  

Literale sind Konstanten für bestimmte Typen.

boolean

Boolsche Literale sind true und false.

int

Zunächst werden wir nur Dezimalzahlen betrachten. Diese bestehen aus Ziffern, wobei die erste Ziffer ungleich 0 sein muß (Ausnahme ist die Konstante 0). Beispiele: 0, 23, 21212, 359203230

long

Ist einer int-Konstanten ein L oder ein l nachgestellt, so ist sie vom Typ long. Beispiele: 23L, 3233434l, 439484908430L, 0L.

double

Gleitkommazahlen werden durch Dezimalpunkt mit einem optionalen Dezimalpunkt dargestellt, denen ein Exponent folgen kann. Es muß mindestens eine Ziffer vorhanden sein. Beispiele: 18., 1.8e1, 0.18E2

float

Gleitkommazahlen, denen ein F oder ein f angehängt wird, sind vom Typ float. Beispiele: 3.4f, 34.0E3F

char

Zeichenliterale werden zwischen zwei Apostrophen geschrieben. Beispiele: 'a', 'Q'

Sonderzeichen können durch eine Escape-Sequenz ausgedrückt werden:

Zeichenketten

In Java gibt es keinen Standardtyp string. Zeichenketten werden durch die Klasse String repräsentiert. Zeichenketten-Literale werden zwischen zwei Anführungszeichen geschrieben.

Zeichenvorschubzeichen sind innerhalb von Zeichenketten-Literalen nicht erlaubt.

Variablen und Werte

Motivation

Variablen dienen zum Speichern von Werten.

Beispiel: int anzahl = 0;

Notwendig sind:

Variablendeklaration

Durch eine Variablendeklaration wird dem Speicher ein Name (Bezeichner) (siehe Abschnitt 5.5) und ein Datentyp zugewiesen. Des weiteren wird Platz im Hauptspeicher für die Variable reserviert. Namen müssen (in einem bestimmten Programmbereich) eindeutig sein.

Datentypen

Daten können unterschiedliche Eigenschaften haben (ganze Zahlen, reelle Zahlen, Zeichen, ...), die unterschiedlich viel Speicherplatz benötigen.

Es macht keinen Sinn bswp. folgende Operation durchzuführen: 3-'d'. Ein Compiler muß überprüfen, ob solche Anweisungen sinnvoll sind.

Aus diesen Gründen werden unterschiedliche Datentypen durch Java bereitgestellt (siehe Abschnitt 5.6).

Initialisierung

Die Initialisierung von Variablen ist in Java im allgemeinen erforderlich. Es existieren für lokale Variablen keine Default-Werte. Explizit können Variablen mit Hilfe von Literalen (siehe Abschnitt 5.7) oder (anderen) Ausdrücken (siehe Abschnitt 9) initialisiert werden. Dabei müssen die Datentypen übereinstimmen. (Ausnahme: implizite Typkonversionen)

Wertebereiche

Für Variablen werden im Hauptspeicher eine bestimmte Anzahl an Bytes reserviert. Damit lassen sich nur endlich viele Zustände repräsentieren. Somit ist bspw. der Wertebereich vom Datentyp int eingeschränkt auf die Werte zwischen -(2 hoch 31) und ((2 hoch 31)-1).
int i = 2147483647; // (2 hoch 31) - 1
i = i + 1; // danach hat i den Wert -(2 hoch 31)

Elementare Datentypen

siehe zunächst Abschnitt 5.6.

boolean

char

byte

short

int

long

float

double

Operatoren

Operationen bestehen aus Operatoren und Operanden. Hiermit können aus alten Werten neue Werte berechnet werden.

Operatoren

Die Operanden der verschiendenen Operatoren müssen vom Typ her zueinander passen (im allgemeinen sollten sie identisch sein).

Integerarithmetik

Die wichtigsten arithmetischen Operatoren (Datentypen short, int long) sind:

Diese Operatoren sind binär. Außerdem gibt es noch die unären Operatoren - und + für die Negation bzw. ihr Gegenteil.

Gleitkommaarithmetik

Bei der Gleitkommaarithmetik fällt gegenüber der Integerarithmetik der Modulo-Rest-Operator weg.

Boolsche Arithmetik

Boolsche Operatoren sind:

Es wird nur solange ausgewertet, bis der boolsche Wert feststeht:

if (bA1 && bA2) ...

Falls bA1 schon false ist, wird bA2 nicht mehr ausgewertet.

Vergleichs- und Bedingungsoperatoren

Vergleichs- bzw. Bedingungsoperatoren liefern boolsche Werte:

Der Zuweisungsoperator

Der Zuweisungsoperator ist das =. Der linke Operand muß eine Variable sein. Der rechte Operand muß ein dazu typkonformer Ausdruck sein.

Präzedenzen

siehe diverse Tabellen in Java-Büchern.

Assoziativität

Die Operatoren sind (im allgemeinen) linksassoziativ. Der Zuweisungsoperator ist rechtsassoziativ. siehe auch diverse Tabellen in Java-Büchern.

Typumwandlungen

Java ist streng typisiert, d.h. Verhinderung inkompatibler Zuweisungen durch den Compiler.

Implizite Typumwandlungen

Beispiele:

  short s = 3;
  int i = s;
  long l = i = s;

  float f = 3.12f;
  double d = f;

  float f = 3;
  return f/2 * i; (float)
  int i = f/2; // Fehler

  int i = 'a';

Explizite Typumwandlungen

Beispiele:

  double d = 7.99;
  long l = (long)d;  // l == 7

  long orig = 91513...1;
  long verloren = (long)((float)orig); // == 91513...2

Rechnen mit Buchstaben:

  char zahl = (char)('0' + 7);  // zahl == '7'

Ausdrücke  

Ein Ausdruck ist eine Verarbeitungsvorschrift, deren Ausführung einen Wert liefert. Ausdrücke entstehen, indem Operanden mit Operatoren verknüpft werden. Arithmetische Ausdrücke liefern Zahlenwerte. Boolsche Ausdrücke liefern Wahrheitswerte.

Werte

Linkswerte

Rechtswerte

Deklarationen

siehe oben

Variablen

Konstanten

Typen

Anweisungen  

Eine Anweisung (Statement) ist eine Vorschrift zur Verarbeitung von Daten.

Elementare Anweisungen sind nicht weiter in der Sprache zerlegbare Anweisungen (Befehle).

Anweisungen lassen sich zusammensetzen (zusammengesetzte Anweisungen).

Imperative Programmierung bedeutet sequentielles Abarbeiten von Anweisungen einer Programmiersprache.

Leeranweisung

Die Anweisung, die nur aus dem Semikolon besteht (tut nichts). Beispiel:

int i = 0;;;;;;;;;  // semantisch dasselbe wie int i = 0;

Deklaration

Eine (Variablen-)Deklaration ist eine Anweisung der Art:
<datentyp> <bezeichner> = <ausdruck> ;
Der Typ der Variablen und der Typ des Ausdruck müssen zueinander konform sein.

Beispiel:

boolean richtig;
int i = 0;
float x = 7.1;
float y = 9.0;
float wert = x + y;

Zuweisung

Eine Zuweisungsanweisung ist eine Anweisung der Art:
<variable> = <ausdruck> ;
Dabei muß die Variable vorher deklariert worden sein. Des weiteren müssen der Typ der Variablen und der Typ des Ausdruck zueinander konform sein.

Beispiel:

int i = 0; // Deklaration
int j = i; // Deklaration
i = i + j - 3; // Zuweisung

Ergänzung: Zuweisung

Zuweisungen sind auch Ausdrücke; sie liefern den Wert der Variablen!

Beispiel

int i=3;
int j=4;
int k=5;
i = j = k; // alle Variablen haben den Wert 5

Abkürzungen

  i = i <op> <ausdruck>; (op: +, -, *, /, %)
    entspricht
  i <op>= <ausdruck>

  und:

  i = i + 1; entspricht: i++; bzw. ++i;  Inkrement-Operator
  i = i - 1; entspricht: i--; bzw. --i;  Dekrement-Operator

  Bsp: 

    i = i + 3; enstspricht: i += 3;
    a *= b+1; entspricht: a = a * (b+1);

    int i = 3;
    System.out.println(++i);  // druckt 4
    System.out.println(i++);  // druckt 4
    System.out.println(i);    // druckt 5

Ausdrucksberechnung

kommt später

Block

Anweisungen lassen sich durch geschweifte Klammern zu einem Block zusammensetzen.

Beispiel:

{
  int anzahl = 3;
  {
    int i = 5;
    anzahl = 3 * i;
    anzahl = 3 * anzahl;
  }
  anzahl = anzahl + anzahl;
  System.out.println(anzahl);
}

Auswahlanweisungen

Zu den Auswahlanweisungen gehören die Einfachauswahl und die Alternativauswahl (if-Anweisung, bedingte Auswahl) sowie die Mehrfachauswahl (switch-Anweisung, Fallunterscheidung).

if-Anweisung

Die if-Anweisung hat die Gestalt
  if ( <boolscher Ausdruck> )
    <Anweisung1>
  else
    <Anweisung2>
Dabei wird zuerst der boolsche Ausdruck ausgewertet. Ist sein Wert true, wird Anweisung1 ausgeführt; im anderen Fall wird bei Vorliegen eines else-Teils die Anweisung2 ausgeführt. Die Angabe eines else-Teils ist optional.

Bei der Verschachtelung von if-Anweisungen gehört der else-Teil immer zur innersten möglichen.

Beispiel:

if (i<j) {
  System.out.println("i ist kleiner");
} else if (j<i) {
  System.out.println("j ist kleiner");
} else {
  System.out.println("i und j sind gleich");
}

if (i>1) 
  if (i>5)
    System.out.println("groesser 5");
  else
    System.out.println("zwischen 2 und 5");

switch-Anweisung  

Eine switch=Anweisung wertet einen Ausdruck vom Typ char, byte, short oder int aus, um damit aus dem sich anschließenden Block von case-Labeln ein passendes case-Label auszusuchen. Wird ein entsprechendes Label gefunden, so wrid mit der ersten ihr folgenden Anweisung fortgefahren. Ist kein passendes Label vorhanden, so wird mit der Anweisung fortgefahren, die einem default-Label folgt. Gibt es kein default-Label, dann wird die ganze switch-Anweisung übersprungen.

Label müssen eindeutig sein. Bei Labeln handelt es sich um Literale bzw. Konstanten.

Beispiel:

int i = 0;
...
switch (i) {
  case 1:  System.out.println("i ist 1");
  case 2:  System.out.println("i ist 1 oder 2");
           break;
  case 3:  System.out.println("i ist 3");
           break;
  default: System.out.println("i ist weder 1,2 noch 3");
}

Wiederholungsanweisungen

Bei den Wiederholungsanweisungen unterscheidet man zwischen der while-, der do- und der for-Schleife.

while-Schleife

Eine while-Schleife hat folgende Gestalt:
while ( <boolscher Ausdruck> )
  <Anweisung>
Der boolsche Ausdruck wird ausgewertet, ist er true, wird die Anweisung (die i.a. ein Block ist) so lange ausgeführt, bis der boolsche Ausdruck false wird.

Beispiel:

int zahl = 6;
int fak = 1;
int i = 2;
while (i <= zahl) {
  fak = fak * i;
  i = i + 1;
}

Beispiel:

    boolean gefunden = false;
    int radius = 1;

    while (!gefunden) {

      // teste_einen_kreis
      int richtungen = 0;
      while ((!gefunden) && (richtungen < 4)) {

        // teste_eine_richtung
        int anzahl_felder = 0;
        while ((!gefunden) && (anzahl_felder < radius)) {
          vor();
          if (korn_da()) {
            gefunden = true;
          } else {
            anzahl_felder = anzahl_felder + 1;
          }
        }  
        if (!gefunden) links_um();
        // ende teste_eine_richtung

        richtungen = richtungen + 1;
      }
      // ende teste_einen_kreis

      radius = radius + 1;
    }

do-Schleife

Eine do-Schleife hat folgende Gestalt:
do 
  <Anweisung>
while ( <boolscher Ausdruck> ) ;
Im Unterschied zur while-Schleife wird die Anweisung einer do-Schleife mindestens einmal ausgeführt.

Es sind semantisch äquivalent:

do
  <Anweisung>
while ( <boolscher Ausdruck> ) ;
und
<Anweisung>
while ( <boolscher Ausdruck> )
  <Anweisung>

for-Schleife

Die for-Anweisung wird verwendet, um einen bestimmten Wertebreich von Anfang bis Ende zu durchlaufen[*] Sie hat die Gestalt:
  for (<Initialisierung-Ausdruck> ;
       <Boolscher Ausdruck> ;
       <Inkrement-Ausdruck>
      )
    <Anweisung>
was i.a. äquivalent ist zu:
<Initialisierung-Ausdruck> ;
while ( <Boolscher Ausdruck> ) {
  <Anweisung>
  <Inkrement-Ausdruck> ;
}
Im Initialisierungsausdruck wird i.a. eine Schleifenvariable deklariert oder einer bereits deklarierten ein Wert zugewiesen. Im Inkrement-Ausdruck wird die Schleifenvariable i.a. verändert. Der Initialisierungsausdruck wird genau einmal beim ersten Betreten der for-Schleife ausgewertet. Dann wird der boolsche Asudruck überprüft und falls er true ist die Anweisung ausgeführt. Anschließend wird jeweils der Inkrement-Ausdruck ausgewertet.

Beispiel:

int zahl = 6;
int fak = 1;
for (int i = 2; i<zahl; i=i+1) {
  fak = fak * i;
}

Beispiel:

    boolean gefunden = false;
    int radius = 1;

    while (!gefunden) {

      // teste_einen_kreis
      for (int richtungen = 0;
           !gefunden && (richtungen < 4);
           richtungen = richtungen + 1
          ) {

        // teste_eine_richtung
        for (int anzahl_felder = 0;
             !gefunden && (anzahl_felder < radius);
             anzahl_felder = anzahl_felder + 1
            ) {
          vor();
          if (korn_da()) {
            gefunden = true;
          }
        }  
        if (!gefunden) links_um();
        // ende teste_eine_richtung

      }
      // ende teste_einen_kreis

      radius = radius + 1;
    }

Fehlt der boolsche Asudruck, wird er als true angenommen.

Endlosschleife

Endlosschleifen sind Schleifen der Gestalt:
  while (true) {
    <anweisung>
  }
und
  for (;;) {
    <anweisung>
  }
Die Schleifenabbruchbedingung ist hierbei immer true.

Sprungmarkierung

Anweisungen können mit Labeln (Bezeichner) versehen werden. Ein Label geht einer Anweisung voran:
  <label> : <anweisung>

Sprunganweisungen (break-Anweisung)

Mit einer break-Anweisung können Wiederholungsanweisungen als auch eine switch-Anweisung unterbrochen werden. Wird break ohne Argument angewendet, beendet das Programm die innerste umgebende (Block-)Anweisung und setzt bei der folgenden äußeren fort (siehe auch Abschnitt 11.7.2).

Eine Marke (Label) als Argument veranlaßt das Programm zu einem Sprung an das Ende der entsprechenden markierten umgebenden Anweisung.

Der Sprung an beliebige Stellen des Programmes (goto) ist in Java nicht erlaubt.

Beispiel:

  int radius = 1;

  hauptprogramm:
    while (true) {

      // teste_einen_kreis
      for (int richtungen = 0;
           richtungen < 4;
           richtungen = richtungen + 1
          ) {

        // teste_eine_richtung
        for (int anzahl_felder = 0;
             anzahl_felder < radius;
             anzahl_felder = anzahl_felder + 1
            ) {
          vor();
          if (korn_da()) {
            break hauptprogramm;  // springt nach Punkt 1
          }
        }  
        links_um();
        // ende teste_eine_richtung

      }
      // ende teste_einen_kreis

      radius = radius + 1;
    }
// Punkt 1: die break-Anweisung springt hierhin

Fortsetzungsanweisung (continue-Anweisung)

continue-Anweisungen können innerhalb einer Schleifenanweisung verwendet werden. Trifft der Interpreter auf eine continue-Anweisung, so beginnt er sofort mit dem nächsten Schleifendurchlauf der markierten oder direkt umgebenden Schleife.

Beispiel:

int x = 0;
while (x<10) {
  x = x+1;
  if (x<10) continue;
  System.out.println("x ist 10");

Synchronisationsanweisung

kommt erst später

Ausnahmeanweisung

kommt erst später

Kontrollstrukturen

siehe Kapitel 11

Auswahlanweisungen

if-then-else-Anweisung

switch-Anweisung

Wiederholungsanweisungen

while-Schleife

do-Schleife

for-Schleife

Unterprogramme

Eigentlich gibt es in Java keine Prozeduren und Funktionen. Sie werden hier Methoden genannt und gehören zu bestimmten Klassen (siehe auch [*]).

Motivation

Prozeduren

Prozedurdefinition

Prozeduraufruf

Beispiel 1

import java.io.*;

public class proz1 {

  public static void ich_bin_eine_prozedur() {
    System.out.println("in der Prozedur");
  }

  public static void main(String[] args) {
    try {
      System.out.println("vor der Prozedur");

      ich_bin_eine_prozedur();

      System.out.println("nach der Prozedur");
    } catch (Exception e) {}
  }
}

Beispiel 2

import java.io.*;

public class proz2 {

  public static void ich_bin_auch_eine_prozedur() {
    System.out.println("in der auch-Prozedur");
  }

  public static void ich_bin_eine_prozedur() {
    System.out.println("in der Prozedur");
    System.out.println("vor der auch-Prozedur");
    ich_bin_auch_eine_prozedur();
    System.out.println("nach der auch-Prozedur");
  }

  public static void main(String[] args) {
    try {
      System.out.println("vor der Prozedur");
      ich_bin_eine_prozedur();
      System.out.println("nach der Prozedur");
      ich_bin_auch_eine_prozedur();
    } catch (Exception e) {}
  }
}

return-Anweisung

Beispiel

import dibo.*;

public class ret1 {

  public static void division() {
    Terminal.out.println("Zaehler eingeben: ");
    int zaehler = Terminal.readInt();
    Terminal.out.println("Nenner eingeben: ");
    int nenner = Terminal.readInt();

    if (nenner == 0) {
      Terminal.out.println("Nenner darf nicht 0 sein");
      return;
    }

    Terminal.out.println("Ergebnis: ");
    Terminal.out.println(zaehler/nenner);
  }

  public static void main(String[] args) {
    try {

      System.out.println("vor der Prozedur");

      division();

      System.out.println("nach der Prozedur");

    } catch (Exception e) {}
  }
}

Funktionen

Motivation

Funktionsdefinition

Funktionsaufruf

Beispiel 1  

import dibo.*;

public class bin1 {

  public static int fak2() {
    int zahl = 2;
    int fak = 1;
    for (int naechste = 2; naechste <= zahl; naechste = naechste + 1) {
      fak = fak * naechste;
    }
    return fak;
  }

  public static int fak3() {
    int zahl = 3;
    int fak = 1;
    for (int naechste = 2; naechste <= zahl; naechste = naechste + 1) {
      fak = fak * naechste;
    }
    return fak;
  }

  public static int fak5() {
    int zahl = 5;
    int fak = 1;
    for (int naechste = 2; naechste <= zahl; naechste = naechste + 1) {
      fak = fak * naechste;
    }
    return fak;
  }

  public static void main(String[] args) {
    try {

      Terminal.out.println("5 ueber 3 = ");
      Terminal.out.println( fak5() / (fak3() * fak2()) );

    } catch (Exception e) {}
  }
}

Parameter

Motivation

Parameterdeklaration

Parameterübergabe

Beispiel 1

import dibo.*;

public class bin2 {

  public static int fak(int zahl) {
    int fak = 1;
    for (int naechste = 2; naechste <= zahl; naechste = naechste + 1) {
      fak = fak * naechste;
    }
    return fak;
  }

  public static void main(String[] args) {
    try {

      Terminal.out.println("n eingeben: ");
      int n = Terminal.readInt();
      Terminal.out.println("m eingeben: ");
      int m = Terminal.readInt();
      Terminal.out.println(n + " ueber " + m + " = ");
      Terminal.out.println( fak(n) / (fak(m) * fak(n-m)) );

    } catch (Exception e) {}
  }
}

Beispiel 2

import dibo.*;

public class bin3 {

  public static int fak(int zahl) {
    int fak = 1;
    for (int naechste = 2; naechste <= zahl; naechste = naechste + 1) {
      fak = fak * naechste;
    }
    return fak;
  }

  public static void main(String[] args) {
    try {

      Terminal.out.println("n eingeben: ");
      int n = Terminal.readInt();
      Terminal.out.println("m eingeben: ");
      int m = Terminal.readInt();

      if ((0 <= m) && (m <= n)) {

        Terminal.out.println(n + " ueber " + m + " = ");
        Terminal.out.println( fak(n) / (fak(m) * fak(n-m)) );

      } else {

        Terminal.out.println("Eingabefehler: Es muss gelten 0 <= m <= n");

      }  

    } catch (Exception e) {}
  }
}

Beispiel 3

import dibo.*;

public class bin4 {

  public static int fak(int zahl) {
    int fak = 1;
    for (int naechste = 2; naechste <= zahl; naechste = naechste + 1) {
      fak = fak * naechste;
    }
    return fak;
  }

  public static int binominalkoeffizient(int n, int m) {
    return fak(n) / (fak(m) * fak(n-m));
  }

  public static void main(String[] args) {
    try {

      Terminal.out.println("n eingeben: ");
      int n = Terminal.readInt();
      Terminal.out.println("m eingeben: ");
      int m = Terminal.readInt();

      if ((0 <= m) && (m <= n)) {

        Terminal.out.println(n + " ueber " + m + " = ");
        Terminal.out.println(binominalkoeffizient(n, m));

      } else {

        Terminal.out.println("Eingabefehler: Es muss gelten 0 <= m <= n");

      }  

    } catch (Exception e) {}
  }
}

Gültigkeitsbereich

Beispiel

import dibo.*;

public class guelt {

  public static void P(int x) {
    int y = 0;
    int i = 0;

    ...
  }

  public static void Q(int x) {
    int y = 0;
    int w = 0;

    ...
  }

  public static void main(String[] args) {
    int i = 0;
    ...
    int j = 0;
    ...
    {  
      ...
      int v = i;
      ...
      i = v;
      ...
      P(i);
    }
    ...
    j = i;
    ...
    {  
      ...
      int w = 0;
      int v = w;
      ...
      w = 4;
      ...
    }    
    ...
  }
}

Inkarnation

Bei Aufruf einer Prozedur/Funktion f (bzw. bei Eintritt in einen Block) entsteht eine Inkarnation von f. Dazu gehört: Die Inkarnation wird vernichtet, wenn die Funktion verlassen wird.

Lebensdauer

Rekursion

Beispiel 1

public static int fak(int n) {
  if (n == 0) 
    return 1;
  else 
    return n * fak(n-1);

Beispiel 1

/*
           |              |             |
           #              |             |
          ###             |             |
         #####            |             |
        #######           |             |
      ----------------------------------------------
           1              2             3

  Gegeben: 3 Pfosten mit n Scheiben
  Ziel: Lege alle n Scheiben von 1 nach 3
  Restriktion: Immer nur eine Scheibe bewegen
  Restriktion: Niemals groessere auf kleinere Scheibe legen
*/

import dibo.*;

public class Hanoi {

  public static void main(String[] args) {
    char zahl = (char)('0'+7);
    Terminal.out.println(zahl);
    int hoehe = Terminal.readInt();
    verlegeTurm(hoehe, 1, 3, 2);
  }

  public static void verlegeTurm(int hoehe,
                                 int von,
                                 int nach,
                                 int ueber
                                ) {
    if (hoehe > 0) {
      verlegeTurm(hoehe-1, von, ueber, nach);
      Terminal.out.println(von + "-" + nach);
      verlegeTurm(hoehe-1, ueber, nach, von);
    }
  }  
}

/* Ausgabe fuer hoehe=4:
  1-2 1-3 2-3 1-2 3-1 3-2 1-2 1-3 2-3 2-1 3-1 2-3 1-2 1-3 2-3
*/

Zusammengesetzte Datentypen

fehlt noch


next up previous contents
Next: Objektorientierte Programmierkonzepte Up: No Title Previous: Grundlagen
Dietrich Boles
11/12/1997