Blöcke und Einrückung

Code einzurücken ist immer von Vorteil, dazu schauen wir uns folgendes Beispiel an:

void funktion(int a)
{
while(1)
{
if(true)
{
macheIrgendwas();
macheIrgendwas();
macheIrgendwas();
macheIrgendwas();
macheIrgendwas();
}
}
ende();
}

Man verliert schnell den überblick wo etwas anfängt und wo wieder aufhört. Besser wäre:

void funktion(int a)
{
   while(1)
   {
      if(true)
      {
         macheIrgendwas();
         macheIrgendwas();
         macheIrgendwas();
         macheIrgendwas();
         macheIrgendwas();
      }
   }
   ende();
}

Man sieht schon besser wo etwas anfängt und wo wieder aufhört. Jezt kann man auch von einem „if-Block“ reden.

Damit das ganze sauber funktioniert sollte man immer die gleiche Anzahl von Zeichen einrücken. Früher war es üblich, mit Hilfe eines Tabs einzurücken. Somit ergab sich eine Laufweite von 8 Zeichen. Heutzutage ist es eher üblich Tabs zu vermeiden und weniger einzurücken. Heute übliche Größen sind 4 Leerzeichen oder 2 Leerzeichen:

void indent8()  // 8 Zeichen, 1 Tab
{
        /* Vorbereitung */
 
        {
                ...
                prepare();
                ...
        }
}
 
void indent4()  // 4 Zeichen, 1 Tab
{
    /* Vorbereitung */
 
    {
        ...
        prepare();
        ...
    }
}
 
void indent2()  // 2 Zeichen, 1 Tab
{
  /* Vorbereitung */
 
  {
    ...
    prepare();
    ...
  }
}

Häufig werden zurzeit 2 oder 4 Zeichen verwendet, 4 Zeichen sind auch die Voreinstellung bei VisualStudio. Wem zwei Zeichen reichen benötigt jedoch weniger Platz, ein aufwändigerer Algorithmus verteilt sich also nicht über den ganzen Bildschirm oder sogar darüber hinaus.

Möchte man einen Abschnitt einrücken, um ihn optisch zu markieren, so kann man die Klammern auch ohne einen Befehl verwenden:

void algorithmus()
{
  /* Vorbereitung */
 
  {
    ...
    prepare();
    ...
  }
 
  give_a_message_to_the_user( "bin dann soweit" );
 
  /* Algorithmus */
 
  {
    ...
    work_hard();
    ...
  }
 
  give_a_message_to_the_user( "fertig, jetzt nur noch aufräumen" );
 
  /* Aufräumen */
 
  {
    ...
    clean_up_the_mess();
    ...
  }
}

Klammersetzung und Ausrichtung

Wie man jetzt die Klammern setzt, ist nirgendwo vorgeschrieben, sie müssen nur der C-Syntax entsprechen. Das bedeutet, da alle Leerzeichen, Tabzeichen und Zeilenwechsel vom Compiler ignoriert werden, es keine Rolle spielt, wieviele Leerzeichen, Tabzeichen oder Zeilenwechsel zwischen dem Befehl und der Klammer stehen.

if(...){macheIrgendwas;}        // syntaktisch korrekt
if(...)
                              { // syntaktisch korrekt
}

Wenn man dies aber so anschaut, ist das unübersichtlich und unschön, besser ist es die Klammer unter die Anweisung zu setzen und den nächsten Befehl in der nächsten Zeile eingerückt schreibt:

for
{
  if(...)
  {
    macheIrgendwas();
  }
}

Die Klammern und der dazugehörige Befehl sind nun an einer Linie ausgerichtet.

Keine Regel ohne Ausnahme: Regelmäßig ergeben sich Fälle, in denen sich Programmcode wie eine Tabelle schreiben lässt. Und das sollte man dann auch nutzen. Das sind häufig Fallunterscheidungen:

char const * wert;
 
if(      value ==  1 ) { wert = "eins";   printf(   "Eins wird gesetzt\n" ); }
else if( value ==  2 ) { wert = "zwei";   printf(   "Zwei wird gesetzt\n" ); }
else if( value ==  3 ) { wert = "drei";   printf(   "Drei wird gesetzt\n" ); }
else if( value ==  4 ) { wert = "vier";   printf(   "Vier wird gesetzt\n" ); }
else if( value ==  5 ) { wert = "fünf";   printf(   "Fünf wird gesetzt\n" ); }
else if( value ==  6 ) { wert = "sechs";  printf(  "Sechs wird gesetzt\n" ); }
else if( value ==  7 ) { wert = "sieben"; printf( "Sieben wird gesetzt\n" ); }
else if( value ==  8 ) { wert = "acht";   printf(   "Acht wird gesetzt\n" ); }
else if( value ==  9 ) { wert = "neun";   printf(   "Neun wird gesetzt\n" ); }
else if( value == 10 ) { wert = "zehn";   printf(   "Zehn wird gesetzt\n" ); }

Beim Vergleich mit value wird die Zahl eingerückt, der printf()-Befehl wird eingerückt, so dass die printf()-Befehle untereinander stehen und der String wird so eingerückt, dass der in jeder Zeile identische Part „wird gesetzt“ ebenfalls untereinander stehen. So fällt der Blick direkt auf die Unterschiede der einzelnen Zeilen.

Schauen wir uns das ganze kurz ohne Einrückung an, es geht übersicht verloren.

char const * wert;
 
if( value == 1 ) { wert = "eins"; printf( "Eins wird gesetzt\n" ); }
else if( value == 2 ) { wert = "zwei"; printf( "Zwei wird gesetzt\n" ); }
else if( value == 3 ) { wert = "drei"; printf( "Drei wird gesetzt\n" ); }
else if( value == 4 ) { wert = "vier"; printf( "Vier wird gesetzt\n" ); }
else if( value == 5 ) { wert = "fünf"; printf( "Fünf wird gesetzt\n" ); }
else if( value == 6 ) { wert = "sechs"; printf( "Sechs wird gesetzt\n" ); }
else if( value == 7 ) { wert = "sieben"; printf( "Sieben wird gesetzt\n" ); }
else if( value == 8 ) { wert = "acht"; printf( "Acht wird gesetzt\n" ); }
else if( value == 9 ) { wert = "neun"; printf( "Neun wird gesetzt\n" ); }
else if( value == 10 ) { wert = "zehn"; printf( "Zehn wird gesetzt\n" ); }

Und nun schauen wir uns das ganze mal „anständig“ formatiert an:

if( value == 1 ) 
{ 
  wert = "eins"; 
  printf( "Eins wird gesetzt\n" ); 
}
else if( value == 2 ) 
{ 
  wert = "zwei"; 
  printf( "Zwei wird gesetzt\n" ); 
}
else if( value == 3 ) 
{ 
  wert = "drei"; 
  printf( "Drei wird gesetzt\n" ); 
}
else if( value == 4 ) 
{ 
  wert = "vier"; 
  printf( "Vier wird gesetzt\n" ); 
}
else if( value == 5 ) 
{ 
  wert = "fünf"; 
  printf( "Fünf wird gesetzt\n" ); 
}
else if( value == 6 ) 
{ 
  wert = "sechs"; 
  printf( "Sechs wird gesetzt\n" ); 
}
else if( value == 7 ) 
{ 
  wert = "sieben"; 
  printf( "Sieben wird gesetzt\n" ); 
}
else if( value == 8 ) 
{ 
  wert = "acht"; 
  printf( "Acht wird gesetzt\n" ); 
}
else if( value == 9 ) 
{ 
  wert = "neun"; 
  printf( "Neun wird gesetzt\n" ); 
}
else if( value == 10 ) 
{ 
  wert = "zehn"; 
  printf( "Zehn wird gesetzt\n" ); 
}

Der Code ist nun sauber formatiert, aber deutlich auseinandergezogen und der schnelle Blick auf's Wesentliche geht vollkommen verloren. Entsprechend kann das Beispiel mit switch aufgezogen werden - und führt zum gleichen Ergebnis: Nahezu Identische Codes gewinnen an Lesbarkeit, wenn sie tabellarisch formatiert werden.