Die ersten Artikel dieser Reihe haben sich sich mit den allgemeinen Konzepten von Funktionen und Variablen beschäftigt. Wir haben gesehen, wie man neue Funktionen definiert, Variablen deklariert, ihnen Werte zuweist, sie an Funktionen übergibt und ihren Wert als Ergebnis einer Funktion zurückgibt. Heute wollen wir uns mit einem weiteren wichtigen Konzept beschäftigen: den Kontrollstrukturen.
Funktionsaufrufe sind eine Form, den Kontrollfluss im Programm, den Programmablauf, zu beeinflussen; hierbei wird von einer Stelle innerhalb einer Funktion zu einer anderen Funktion gesprungen, diese ausgeführt, und dann zum ursprünglichen Ort der Ausführung zurückgesprungen und dort fortgefahren. Funktionsaufrufe sind in ihrer ursprünglichen Form streng linear und eindeutig: beim Funktionsaufruf ist bekannt, an welche Stelle im Programm gesprungen werden und welcher Code dort ausgeführt werden soll (das gilt nicht für die objektorientierte Programmierung – aber dazu in einem späteren Artikel mehr).
Für komplexere Programme werden aber auch andere Formen der Beeinflussung des Kontrollflusses benötigt; hierfür werden die sogenannten Kontrollstrukturen verwendet. Besonders häufig benötigte Kontrollstrukturen sind Verzweigungen und Wiederholungen. Bei einer Verzweigung wird abhängig von einer Bedingung eine von 2 Anweisungen oder Anweisungsfolgen ausgeführt, wohingegen bei einer Wiederholung eine Anweisungsfolge so lange wiederholt wird, bis eine bestimmte Bedingung nicht mehr gilt. Aber im Detail.
Verzweigungen
Eine Verzweigung teilt den Programmfluss in 2 mögliche Pfade auf. Je nach dem, ob eine angegebene Bedingung erfüllt ist, wird entweder eine oder der andere Anweisungspfad ausgeführt. In C++ lassen sich Verzweigungen in der folgenden Art (an einem Beispiel) definieren:
int abs( int n ) { if ( n > 0 ) return n; else return -n; }
Gut, was sehen wir hier? Als erstes einmal die Definition einer Funktion abs
, welche eine ganze Zahl als Parameter verlangt und eine ebensolche als Rückgabewert zurückliefert. Die Verzweigung innerhalb der Funktion besagt nun folgendes: Wenn der Parameter n größer als 0 ist, dann soll er direkt zurückgegeben werden; ansonsten (sprich, wenn er kleiner oder gleich 0 ist) soll er negiert zurückgegeben werden – die klassische Definition des Absolutwertes. Anders gesagt: ist die Bedingung der Verzweigung erfüllt, wird die Anweisung hinter dem if
ausgeführt, ansonsten die hinter dem else
(englisch für “sonst”).
In den beiden Zweigen können natürlich nicht nur einzelne Anweisungen, sondern ganze Anweisungsblöcke stehen, die, ebenso wie bei einer Funktion, in geschweifte Klammern eingefasst sind. In diesen Anweisungsblöcken können auch neue Variablen definiert werden, die dann nur innerhalb dieses Blocks gültig sind; der folgende Code würde zu einem Fehler führen, da die Variable m
hinter der Anweisung nicht bekannt ist:
int abs( int n ) { if ( n > 0 ) { int m; m = n; } else { int m; m = -n; } return m; }
Gültig wäre dagegen der folgende Code (an welchem man auch gleich sieht, dass man die geschweiften Klammern bei Anweisungsfolgen mit nur einer Anweisung auch weglassen kann; das ganze auch gemischt innerhalb einer Verzweigung):
int abs( int n ) { int m; if ( n > 0 ) { m = n; } else m = -n; return m; }
Die Angabe des else
-Zweiges ist übrigens nicht obligatorisch; wird er weggelassen, wird einfach kein Code in der Verzweigung ausgeführt, wenn die Bedingung nicht zutrifft (man spricht dann lediglich von einer bedingten Anweisung), etwa wie in dem folgenden Beispiel; das ist wieder die Funktion zur Berechnung des Absolutwertes, nur etwas anders formuliert:
int abs( int n ) { if ( n < 0 ) n = -n; return n; }
Lässt sich eine Bedingung nicht in lediglich 2 Zweige aufbrechen, so können auch mehrere Verzweigungen hintereinander geschaltet werden, etwa so (zur Definition einer mathematischen Funktion; deren Nutzen sei einmal egal):
Kommentare (23)