peace software
  Berndt Wischnewski  Richard-Wagner-Str. 49  10585 Berlin 
  Tel.: 030 - 3429075  FAX : 030 34704037  email: webmaster@peacesoftware.de  Ust-ID: DE135577379 

 

 

<= Previous

 

C Kurs - if I was a rich man, düdeldüdeldüdeldideldum

Bis jetzt haben Sie gelernt was eine Variable ist und welche Typen von Variablen es gibt und wie man Variablen deklariert und wie man sie verändert. In diesem Kapitel geht es darum sie zu vergleichen. Es gibt in C drei verschiedene conditional statements nämlich if, den ? Operator und switch. In diesem Kapitel wird die if Abfrage behandelt, ? und switch kommt im nächsten.

1. if Abfragen allgemein

If Abfragen
funktionieren folgendermaßen:

if(Abfrage)
  Anweisung1
else
 Anweisung2

Jetzt mal ausführlich, man stellt eine Frage, z.B. if(x   >  42), ist die Antwort ja, dann wird Anweisung1 ausgeführt, wenn nicht dann erstaunlicher Weise der else Teil mit Anweisung2. Sind mehrere Anweisungen auszuführen, bildet man einen Block mit geschweiften Klammern:

if(Abfrage)
{
  Anweisung1
  Anweisung2
  Anweisung3
}
else
{
  Anweisung4;
  Anweisung5;
}

Der Teil mit else, also die Behandlung der nicht wahren if Abfrage, ist natürlich optional:

if(Abfrage)
  Anweisung1;

Anweisung2; // keine else Teil

Hier jetzt mal ein kleines Beispielprogramm:

#include <stdio.h>
int main(void)
{
   int magic = 42;
   int guess;

   printf("Finde die magische Zahl:\n");

   scanf("%d", &guess);  // einlesen über die Tastatur, wird später erklärt
   if(guess  == magic) // == sind zwei hintereinander stehende Gleichheitszeichen
   {
      printf("OK, Du hast es!\n");
   }
   else
   {
      if(guess < magic)
      {
         printf("zu klein\n";
      }

      if(guess > magic)
         printf("zu groß\n";
  }

  return 0;
}

Einrückungen und neue Zeilen sind auch optional, erhöhen die Lesbarkeit des Codes immens. Einige Programmierer bezweifeln dass, etwa mit dem bewußten oder unbewußten Argument: bei meinem IQ kann ich es mir leisten, sloppy formatierten Code zu schreiben, ich blick da schon noch durch. Ich weiß auch nicht, aber die guten Programmierer liefern immer sauber bis penibel formatierte Programme ab. Also als Tip, gewöhnen Sie gleich an, Ihre Programme mit Leerzeichen, Einrückungen und Zeilenumbrüchen möglichst einheitlich und gut lesbar zu gestalten. Man kann das Programm auch in eine 2 Zeilen quetschen:

int main(void){int magic = 42;int guess;printf("Finde die magische Zahl:\n");scanf("%d", &guess);
if(guess  = =  magic)
{printf("Du hast es!\n");}else{if(guess < magic){printf("zu klein\n";}else{printf("zu groß\n";}}}

Dem C Compiler ist dass egal, er ist ja schließlich nur ein Computerprogramm, aber wenn ein Mensch das bearbeiten soll... Es gibt jedes Jahr einen internationalen Wettbewerb für das unverständlichste C Programm "The International Obfuscated C Code Contest", wenn Sie meinen auf Neuzeilen und Einrückungen verzichten zu können, dann machen Sie dort doch mal mit.

2. Vergleichsoperatoren

Einige Vergleiche hatten wir in dem Beispiel schon gesehen:

den Vergleich auf Gleichheit: == (zwei hintereinander stehende Gleichheitszeichen) Dieser Vergleich ergibt wahr, wenn beide Seiten gleich sind. Einige Beispiele:

if(x == y) ...// wenn x gleich y ...
if(z + 100 == 666) ... // wenn z + 100 gleich 666 ...
if(c == 'A') ... // wenn c gleich 'A'
if(hansi) ... // wenn hansi nicht Null ist ergibt es wahr, wenn hansi Null ist falsch
if(! hansi) ... // wenn hansi falsch( Null) ist, dann ergibt nicht hansi, ! hansi, wahr -> if wird ausgeführt
                    // ist hansi wahr dann ergibt nicht hansi falsch -> else wird ausgeführt
if(var == MyFunction(a, 68) ) // hier wird var mit dem Rückgabewert der Funktion MyFunction verglichen
if( AnotherFunction() ) ... // Hier wird nur abgefragt, ob der Rückgabewert der Funktion AnotherFunction nicht Null ist.

Ein sehr populärer Fehler von C Anfängern ist folgender, statt:

if(x == y)

schreibt man gerne versehentlich:

if(x = y) // nur ein Gleichheitszeichen

der Compiler interpretiert dies als Zuweisung, so steht es ja auch da, es wird also erst x = y; ausgeführt, dann wird geguckt ob x denn nicht Null ist, in diesem Fall ergibt die Abfrage wahr, oder x ist Null dann ergibt die Abfrage falsch. Meistens ist dies nicht das, was Sie eigentlich tun wollten, deshalb gibt es auch bei den meisten C Compilern eine Warnung beim kompilieren. Wenn es sich um den Vergleich einer Variablen mit einer Zahl handelt, kann man sich folgenden kleinen Trick angewöhnen:

statt if(x == 1)
schreibt man if(1 == x) das gibt auf jeden Fall eine Fehlermeldung vom Compiler, wenn man nur ein Gleichheitszeichen tippt.

Eine weitere Falle ist der Vergleich von reellen Zahlen, kompilieren Sie doch bitte mal folgendes Programm:

#include<stdio.h>
#include<stdlib.h>

void main(void)
{
   if(18.61 + 2.01 == 20.62)
      printf("Alles OK\n");
   else
      printf("Hier ist was faul, im Staate Dänemark\n");
}
und raten Sie mal welche Meldung angezeigt wird? Genau, hier ist was faul... Warum eigentlich - 18.61 + 2.01 ist doch gleich 20.62 ??? Nun, das ganze hängt damit zusammen, dass reelle Zahlen von C Compilern in der Form Mantisse - Exponent gespeichert werden.18.61 + 2.01 ergibt bei meinem Compiler 20.620000839233, das ist zwar fast 20.62 aber leider nicht ganz genau gleich. Beim Vergleich reller Zahlen, egal ob sie vom Typ float, double oder long double sind, muß man deshalb immer auf Gleichheit innerhalb eines sehr kleinen Intevalles, meist epsilon genannt, prüfen, hier ein Beispiel:

#include<stdio.h>
#include<stdlib.h>

void main(void)
{
   float epsi;

   epsi = 10e-18; // sehr kleiner Wert

   if( abs(18.61 + 2.01 - 20.62) < epsi )
      printf("Alles OK\n");
   else
      printf("Hier ist immer noch was faul\n");
}

Jetzt sollte "Alles OK" als Antwort kommen. Die Funktion abs ist in der StandardLibrary stdlib.h definiert, sie gibt den Absolutwert der Eingabe zurück z.B. bei abs(-1) wird 1 zurückgegeben. Dies ist nötig, da niemand voraussehen kann ob 8.61 + 2.01 = 20.620000839233 ergibt oder etwa 8.61 + 2.01 = 20.6199999993472

 

Außer == gibt es noch folgende andere Vergleiche die genauso funktionieren, deshalb nur in Kürze:

if(a < b) ... // wenn a kleiner b ist dann ...
if(a > b) ... // wenn a größer b ist dann ...
if(a <= b) ... // wenn a kleiner oder gleich b ist dann ...
if(a >= b) ... // wenn a größer oder gleich b ist dann ...
if(a != b) ... // wenn a ungleich b ist dann ...


3. komplexe Abfragen

Die Abfrage kann mit den im vorigen Kapitel beschriebenen logischen Operatoren && - AND, || - OR und ! - NOT beliebig komplex gestaltet werden. Hier mal ein Beispiel über mehrere Zeilen, wie man sieht stören Zeilenumbrüche nicht:

if( ( (a == b) && (a > 0) ) ||
    ( (a == c) && (a > 42) ) ||
    ( (a == 42) && (b && c) ) )
{
   Anweisung;
}

Dies bedeutet

wenn a gleich b ist und a größer Null ist oder
wenn a gleich c ist und a größer 42 ist oder
a gleich 42 ist und sowohl b als auch c nicht Null sind, dann führe Anweisung aus.


3. verschachtelte Abfragen

If Abfragen können natürlich auch veschachtelt sein. Hiermit ist gemeint, daß if Abfragen weitere if Abfragen enthalten dürfen. Das nennt man dann eine if - else Leiter. Hier ein Beispiel:

if(a && x)
   if(b > 42)
     if(c == 'X')
        var1 = 666;
     else
        if(! c)
           var2 = 666;
        else
           var1 = 999;

Hier sieht man auch wie sinnvoll es ist,seinen Kode durch Einrückungen und Neuzeilen gut lesbar zu formatieren, sonst überlegt man ständig, bei welcher if Abfrage man eigentlich ist. Die selbe if Abfrage wird durch das einfügen geschweifter Klammer noch mal klarer, obwohl sie nicht zwingend sind:

if(a && x)
{
    if(b > 42)
   {
       if(c == 'X')
      {
          var1 = 666;
      }
      else
      {
          if(! c)
              var2 = 666;
          else
              var1 = 999;
      } //if(c == 'X') else ...
   } // if(b > 42)
} // if(a && x)

Ja welche else gehört eigentlich zu welchem if? Die Antwort ist: immer zum nächstdrüberliegenden. Bei diesem bewusst schlecht formatierten Beispiel gehört der else Abzweig zu der darüberliegende if Abfrage, if(b)... :

if(a)
if(b)
Anweisung1;
else
Anweisung2;

Will man das ändern, muß man geschweifte Klammern einsetzen. Jetzt bezieht sich else auf das obere if, if(a) ... :

if(a)
{
if(b)
Anweisung1;
}
else
Anweisung2;



<= Previous





C Lattenzaun oder C-Sharp - wer das scharf findet sollte hier zugreifen: