Block

Aus EINI
Wechseln zu: Navigation, Suche

Blöcke gehören zu den sogenannten Kontrollstrukturen.

Ein Block fasst mehrere sequenzielle Anweisungen zu einer syntaktischen Einheit zusammen. Dies vereinfacht die syntaktische Überprüfung von Programmen für den Compiler und hilft bei der Strukturierung von Programmen.

In den meisten imperativen Programmiersprachen helfen Blöcke auch dabei, Variablen zu überdecken. Dabei können Namen von Variablen mehr als ein Mal verwendet werden. Jedoch sind dabei die überdeckten Variablen innerhalb des Blockes nicht mehr zu verwenden.

Syntaxdiagramm

Statement block.png

Verwendung

Ein Block wird durch eine sich öffnende und schließende geschweifte Klammer gekennzeichnet: { ... }. Alle Anweisungen innerhalb dieses Blockes werden dann in der Syntaxanalyse des Compilers als eine einzelne Anweisung behandelt. Somit kann man z.B. alle im Block verwendeten Anweisungen bedingt oder wiederholt ausführen lassen.

Überdeckung

Man kann innerhalb eines Blocks Variablennamen außerhalb des Blocks überdecken. Dies geschieht, indem der Name der äußeren Variablen innerhalb des Blocks neu deklariert wird. Damit hat der Name der Variablen innerhalb eines Blockes eine neue Bedeutung. Wird der Block jedoch verlassen, sind alle innerhalb des Blocks deklarierten Variablen nicht mehr sichtbar und damit praktisch gelöscht. Variablen, deren Namen innerhalb des Blocks überdeckt wurden, sind nun wieder sichtbar und haben ihre ursprüngliche Bedeutung außerhalb des Blocks.

Beispiele

[...]
    int x = 5;
    { /* modify x and print */
        x = x + 10;
        System.out.println(x);
    }
    System.out.println(x);
[...]

Das obere Codefragment deklariert eine Variable x und fasst das Erhöhen dieser Variablen und ihre Ausgabe auf der Konsole in einem Block zusammen. In diesem Beispiel hat der Block keinen weiteren Nutzen, als dem lesenden Programmierer die beiden Zeilen hervorzuheben. Die Ausgabe des Programms ist daher zwei Mal 15.

[...]
    int x = 5;
    { /* hide outer x and print */
        int x = 10;
        System.out.println(x);
    }
    System.out.println(x);
[...]

In diesem Beispiel wird die Variable x außerhalb des Blocks von der neu deklarierten Variablen gleichen Namens innerhalb des Blocks überdeckt (engl. shadow von "überschattet" oder hide von "versteckt"). Anders, als wenn man eine Variable innerhalb des gleichen Blocks mehrfach deklariert, ist dies kein Fehler.

Wird innerhalb des Blocks auf eine Variable mit dem Namen x zugegriffen, so wird zuerst nach einer Variablen gesucht, die im Block deklariert wurde. Findet sich eine solche nicht, so wird nach einer Variable außerhalb des Blocks mit diesem Namen gesucht. Da hier die Variable x innerhalb des Blocks mit dem Wert 10 deklariert und initialisiert wurde, ist die erste Ausgabe des Programmfragmentes 10. Die zweite Ausgabe des Programmfragmentes findet außerhalb des Blockes statt, wo die innere Variable des Blockes nicht mehr sichtbar[1] ist. Somit wird außerhalb des Blockes auf die Variable x mit dem Wert 5 zugegriffen und die zweite Ausgabe ist 5.

[...]
    int x = 1; // x deklarieren und setzen
    while(x < 8){
        int y = 2; // y deklarieren und setzen
        System.out.println("Value of x: "+x); // x ausgeben : Der Wert wird 1, 3, 5, 7 sein
        x = x + y++; // x um 2 erhöhen und dann y um 1 erhöhen
    } // Der Block wird verlassen. y ist nicht mehr sichtbar und wird beim Betreten des Blockes wenn die Schleife wiederholt wird neu deklariert und mit 2 initialisiert
    if(x > 8) x++; // Wenn x größer als 8 ist, x um eins erhöhen
    x++; // x immer um eins erhöhen

Dieses Beispiel soll verdeutlichen, dass eine Schleife bzw. bedingte Anweisung syntaktisch genau einen Befehl zum Wiederholen bzw. bedingten Ausführen erwartet. Die while-Schleife wiederholt den angegebenen Block, also alle drei Anweisungen, während die if-Anweisung nur das direkt dahinter stehende x++ ausführt. Das in der nächsten Zeile notierte x++ wird jedoch immer ausgeführt, da es nicht vom if betroffen ist.

Negativbeispiel

[...]
    { /* declare and print x */
        int x = 10;
        System.out.println(x);
    }
    System.out.println(x);
[...]

Dieses Codefragment würde nicht compilieren, da die Variable x außerhalb des Blocks nicht sichtbar ist. Sie müsste irgendwo außerhalb des Blocks, vor Aufruf der println()-Methode deklariert und initialisiert worden sein.

Fußnoten

  1. Tatsächlich sind diese Variablen dann praktisch auch nicht mehr existent. Auch wenn in Schleifen ein Block mehrmals betreten wird, werden alle Variablen bei Deklaration im Block erneut überdeckt. Möchte man also eine Variable über mehrere Durchlaufe durch den Block behalten, muss sie außerhalb des Blockes deklariert werden.