Anweisungsblock {}

Kontrollstrukturen legen anhand von Entscheidungen und Schleifen fest, ob und wie oft ein bestimmter Code-Teil ausgeführt werden soll. Die if-else Struktur, die while Schleife, die do-while Schleife und die for Schleife erwarten somit nach der Bedingung eine Anweisung oder mehrere Anweisungen, welche ausgeführt werden sollen.

Wenn mehrere Anweisungen aufgrund der Bediungung ausgeführt werden sollen, werden ebendiese in geschweifte Klammern {} geschrieben. Dies wird als als Anweisungsblock (auch Code-Block, oder kurz: Block) bezeichnet.


Single Statement


Block Statement 1
Block Statement 2
if(number > 10)
  printf("Single Statement");

if(number > 10){
  printf("Block Statement 1");
  printf("Block Statement 2");
}

Ein Codeblock bildet einen neuen Bereich, in welchem Symbole definiert werden können:



New variable: 5
if(number > 10){
  int myNewVariable = 5;
  printf("New variable: %d\n", myNewVariable);
}

Details

Die Zeilen, welche zu einem Codeblock gehören, werden üblicherweise um einen Tab-Schritt eingerückt. Dies hat für den Compiler keinerlei Relevanz, dient jedoch als visuelle Hilfe. Dies wird insbesondere dann nützlich, wenn mehrere Kontrollstrukturen ineinander verschachtelt auftreten:








1, 1, 0
1, 0, 1
0, 1, 1
#include <stdio.h>

int main(){
  for(int z = 0; z < 2; ++z)
    for(int y = 0; y < 2; ++y)
      for(int x = 0; x < 2; ++x)
        if(x + y + z == 2){
          printf("%d, ", x);
          printf("%d, ", y);
          printf("%d\n", z);
        }
  return 0;
}

Die Notation ohne geschweifte Klammern ist für kleine Strukturen nach wie vor üblich, birgt jedoch ein Fehlerpotential, wenn der Code erweitert wird. Folgendes Beispiel sollte alle Zahlen positiv machen, leider wurde vor die Vorzeichenumkehr eine Debug-Zeile eingefügt, welche nun bewirkt, dass die ursprünglich positiven Zahlen negativ werden.








-42 is positive
#include <stdio.h>

int main(){
  int number = 42;
  if(number < 0)
    printf("%d is negative", number);
    number = -number;
  printf("%d is positive", number);
  return 0;
}

Definition von Symbolen

Durch die Definition eines Anweisungsblockes mit geschweiften Klammern {} wird ein neuer Bereich eingeleitet. Somit können lokal Symbole deklariert und definiert werden, welche ausserhalb des Blocks nicht sichtbar sind.




i has value 50.

'i' undeclared
int number = 42;
if(number > 10){
  int i = 50;
  printf("i has value %d.\n", i);
}
printf("i has value %d.\n", i);

In der Sprache C ist die Definition von Variablen nur innerhalb der geschweiften Klammern gültig. Die Definition von Variablen direkt in der Bedingung ist nicht möglich:


syntax error
int number = 42;
if(int half = number / 2){
  printf("half value: %d\n", half);
}

Definition von Variablen unter C90

Bei älteren C-Standards müssen sämtliche benötigten Symbol-Definitionen am Anfang des enthaltenen Bereiches definiert werden. Diese dem C90-Standard enstammende Restriktion gilt für beliebige Anweisungs-Blöcke, also auch dem Definitionsbereich einer Funktion). Ab C99 gilt diese Restriktion jedoch nicht mehr.

Der Grund für diese Restriktion war, dass ältere Compiler den Code mittels eines einzigen Durchlaufs abarbeiten (sogenannte Single-Pass-Compiler). Ausführbare Teile des Codes gehören im schlussendlichen Binary in das sogenannte text-segment, Variablen hingegen in das sogenannte data-segment. Single-Pass-Compiler können diese Aufteilung nicht vornehmen, wenn Variablendefinitionen und ausführbarer Code vermischt auftreten.

Diese Restriktionen des C90-Standards entsprechen nicht mehr dem heutigem Verständnis von gutem Programmierstil. Ab dem Standard C99 ist dies glücklicherweise nicht mehr der Fall. Da jedoch der C90-Standard lange Zeit noch einen Industriestandard darstellte und dieser Standard zur Kompatibilität zu älterem Code teilweise auch heute noch verwendet wird, müssen viele Implementationen sich diesen Herausvorderungen stellen.