Programmiersprache C/C++
3.5 Sprünge
Sprünge existieren in Programmiersprachen in zwei Grundformen:
-
direkte Sprünge
innerhalb einer Programmeinheit kann zu einer (fast) beliebigen
ausführbaren Anweisung verzweigt werden
Direkte Sprünge (GOTO-Befehle) widersprechen den Regeln des
strukturierten Programmierens.
-
kontrollierte Sprünge
eine bestimmte Ablaufstruktur (Programm, Unterprogramm, Zyklus)
kann unmittelbar verlassen werden
es kann nicht zu einer beliebigen Anweisung verzweigt werden,
sondern nur zur nächsten Ablaufstruktur
Einige moderne Programmiersprachen (Modula, Oberon) lassen direkte
Sprünge nicht zu.
Kontrollierte Sprünge
Es gibt folgende Möglichkeiten:
-
break
Beenden der laufenden Iteration bzw. Aussprung aus einer Fallauswahl
(switch)
Befindet sich break innerhalb mehrerer ineinander
geschachtelter Schleifen, so wird nur die innerste Schleife verlassen.
-
continue
Übergehen der nachfolgenden Anweisungen innerhalb der Iteration
Fortsetzung der Iteration mit dem nächsten Iterationsschritt
Befindet sich continue innerhalb mehrerer ineinander
geschachtelter Schleifen, so bezieht sich die Wirkung nur die innerste
Schleife.
-
return
Rücksprung aus einer Funktion in die rufende Programmeinheit
im Hauptprogramm führt return zur Beendigung des Programms
-
exit(rueckkehrcode)
Programmbeendigung und Setzen eines Rückkehrcodes
Der Rückkehrcode 0 signalisiert erfolgreiche Programmausführung,
von Null verschiedene, ganzzahlige Werte weisen auf eine abnormale
Programmbeendigung hin. Der Wert sollte auf die Ursache des
Programmabbruchs hinweisen.
Eventuell geöffnete Dateien werden geschlossen, vom Programm
mit tmpfile angelegte Dateien werden gelöscht.
-
abort
abnormale Programmbeendigung
Direkte Sprungbefehle
C erlaubt - entgegen den Regeln des strukturierten Programmierens -
die Ausführung direkter Sprungbefehle.
Dazu sind zwei syntaktische Konstruktionen erforderlich:
-
Marke (Label)
Markierung des Befehls, mit dem Programmabarbeitung fortgesetzt werden
soll
Marken müssen in C nicht deklariert werden.
-
Sprungbefehl (goto)
Veranlassung, daß die Programmabarbeitung mit dem Befehl fortgesetzt
wird, der als Sprungziel mit Hilfe einer Marke beschrieben wird.
Marken
Marken sind Bezeichner, die keiner Deklarationspflicht unterliegen.
Ein Bezeichner kann mit einem Buchstaben beginnen, gefolgt von weiteren
Buchstaben oder von Ziffern. Auch das Unterstreichungssysmbol ist
zulässig.
Eine Marke kann beliebigen Befehlen - getrennt durch einen Doppelpunkt -
vorangestellt werden:
marke : anweisung;
Sprungbefehl
goto marke;
Die Programmabarbeitung wird nicht mit dem nachfolgenden Befehl fortgesetzt,
sondern mit dem Befehl, der durch marke markiert wird.
Sprungziel
marke: befehl;
Das Sprungziel darf nur innerhalb des Gültigkeitsbereiches der Marke
liegen, d.h. der jeweiligen Funktion liegen.
Beispiel:
#define OKAY 1
...
while ( OKAY ) {
aktionsfolge_1;
if ( bedingung ) goto weiter;
aktionsfolge_2;
}
weiter: aktionsfolge_3;
...
Das obige Beispiel kann ohne goto realisiert werden:
while ( OKAY ) {
aktionsfolge_1;
if ( bedingung ) break;
aktionsfolge_2;
}
aktionsfolge_3;
...
Beispiel 2:
for(...) {
for(...) {
...
if ( ... ) goto error;
...
}
...
}
...
error : ...
Mit break wäre in dieser Situation nur das Verlassen des
innersten Zyklus auf direktem Wege möglich gewesen.
Es gibt folgende Regeln für die Anwendung des goto-Befehls:
-
Es sollte nicht von außerhalb in einen Zweig (THEN-Zweig oder
ELSE-Zweig) eines if-Konstrukts hineingesprungen werden.
-
Innerhalb eines if-Konstrukts sollte nicht vom THEN-Zweig in den
ELSE-Zweig gesprungen werden (und umgekehrt).
-
Von außerhalb sollte nicht in den Körper eines
switch-Konstrukts gesprungen werden.
Dies gilt ebenso für alle Zyklen (for, while, do).
-
Es sollte nicht von außerhalb in einen Anweisungsblock
(compound statement) gesprungen werden.
Verstöße gegen diese Regeln werden von C-Systemen meist
toleriert. Es kann aber zu systemabhängigem Verhalten kommen,
z.B. wenn in einen Anweisungsblock gesprungen wird, der lokale Variablen
besitzt.
Beispiel:
#include <stdio.h>
int main(void)
{
int x = 1, y = 2, z;
do {
z = x + y;
if ( z < 8 )
goto label;
else {
int x, y, z;
x = 1; y = 2;
z = x + y;
label:
printf("* %d\n", z);
}
printf("+ %d\n", z);
x++;
}
while ( x < 10 );
return 0;
}
Ein Test des Programms brachte für den Fall z < 8 bei
Einsatz von vier verschiedenen Compilern vier verschiedene Ergebnisse.
Fehlermeldungen oder Warnungen gab es in keinem Fall.
Das C-Laufzeitsystem stellt Funktionen bereit, um
nichtlokale Sprünge
ausführen zu können. Mit Hilfe dieser Funktionen lassen sich
Coroutinen realisieren.
Ein "normaler" Gebrauch dieser Funktionen ist nicht zu empfehlen.
Zurück zum Menü
Zurück zur vorigen Seite
Weiter zur nächsten Seite
P. Böhme, 12.01.1996