ein Kapitel zurück                                           ein Kapitel weiter

Sie haben im Kapitel zuvor schon kuren Einblick bei unserer Headerdatei über die Bedingte Kompilierung erhalten. Hierzu mal schnell ein ganz primitives aber verständliches Beispiel....

/*Download:clrscr.c*/
#include <stdio.h>
#ifdef __unix__
#define clrscr() printf("\x1B[2J"
)
#elif __BORLANDC__ && __MSDOS__
#include <conio.h>

#else
#define clrscr() system("cls"
)
#endif

int main()
{
/*Universale Routine zum löschen des Bildschirmes*/
clrscr();
}

Hiermit wird bevor Compiliert wird festgelegt welche Routine zum löschen des Bildschirms benutzt wird. Mit....

#ifdef __unix__

...überprüft der Präprozessor ob unser Programm auf einem Unix-Artigen System läuft. Falls ja dann wird mit...

#define clrscr() printf("\x1B[2J")

...die Routine zum Löschen des Bildschirmes definiert die eben nur unter Unix/Linux funktioniert. Falls es aber kein Unix-System war wir überprüft.....

#elif __BORLANDC__ && __MSDOS__

....ob unser Programm mit einem Borland-Compiler und unter MS-DOS Übersetzt wird. Falls ja dann wird das Löschen des Bildschirmes durch eine in der Headerdatei #include <conio.h

#else
    #define clrscr() system("cls")


Abschließen müssen wir die Bedingte Complierung durch....

#endif

Noch ein etwas kürzeres und einfacheres Beispiel.......

/*Download:os.c*/
#include <stdio.h>


#ifdef __MSDOS__
int main()
{
printf("Programm läuft unter MSDOS \n");
return 0;
}

#elif __MACINTOSH__
int main()
{
printf("Programm läuft unter MACINTOSH\n");
return 0;
}

#elif __unix__
int main()
{
printf("Programm läuft unter UNIX/LINUX\n");
return 0;
}

#else
int main()
{
printf("Konnt das Betriebssystem nicht lokalisieren!!!\n");
return 0;
}
#endif

Hier haben wie ein Beispiel das festlegt welche main()-Funktion benutzt werden soll. Der Programmablauf ist der selbe wie schon oben. Zuerst überprüft der Präprocessor ob das Programm auf einem MS-DOS System läuft.....

#ifdef __MSDOS__

...falls ja wird die darauffolgende main()-Funktion für MS-DOS ausgeführt. Mit...

#elif __MACINTOSH__

...überprüfen wir ob unser Programm auf dem iMac laufen soll. Die nächste Überprüfung...

#elif __unix__

...ist die main-Funktion für Unix/Linux Artige Systeme. Falls der Präprozessor keins dieser System ausmachen kann kommt unser #else zum Einsatz.
Man kann die Bedingte Compilierung mit if - if else - else Abfragen vergleichen. Um Compiler - Spezifische Abfragen zu machen gibt es folgende Konstanten der Compiler....

Konstante Compiler
_MSC_VER Microsoft C 6.0 and later
_QC Microsoft Quick C 2.51 and later
__TURBOC__ Borland Turbo C, Turbo C++ and BC++
__BORLANDC__ Borland C++
__ZTC__ Zortech C and C++
__SC__ Symantec C++
__WATCOMC__ WATCOM C
__GNUC__ Gnu C
__EMX__ Emx Gnu C


Für die Bedingte Compilierung von Betriebssystem konnte ich folgende Konstanten herausfinden...


Konstante Betriebssystem
__unix__ Unix/Linux Systeme
__MS-DOS__ MS-Dos
__WIN32__ Windows ab 95
__OS2__ OS2


Dies nur so am Rande falls sie Ihre Programme portabel halten müssen. Sollten sie noch mehr Konstanten kennen (dies sind leider nicht alle) lassen sie mir diese bitte wissen.

Jetzt aber mal mein praktisches Beispiel mit Sinn......

/*Download:sektor.c*/
#include <stdio.h>



#ifdef UNIX
#define SEKTORSIZE 1024
#endif

#ifdef MSDOS
#define SEKTORSIZE 512
#endif

void sect(long size)
{
long kb,s=SEKTORSIZE;

if(s==1024)
printf("Unixsystem : ");
else
printf("DOS : ");

kb=size*s;
printf(" %ld Sektoren = %ldKB\n",size,kb);
}


int main()
{
long sector;
printf("Wie viele Sektoren: ");
scanf("%ld",&sector);
sect(sector);
return 0;
}

Hier sehen ein Beispiel von Portabilität. Auf 'Dos' beträgt die Größe eines Sektor auf der Festplatte 512KB. Auf Unixsystem hingegen meist 1024KB pro Sector. In dem Fall brauchen sie nur am Anfang unseres Programms den Präprozessor die Anweisung geben für welches System er die Größe einer Bestimmten Anzahl von Sektoren ausgeben soll. Jetzt wird es mal wieder Zeit für eine kleine Prüfung ob wir alles Verstanden haben.

Folgende Schreibweisen sind im Übrigen identisch....

#ifdef MAKRO
ist identisch mit
#if defined MAKRO


Des weiteren gibt eine Direktive mit der es möglich ist zu Überprüfen ob etwas nicht definiert wurde....

#ifndef __STDIO_H
  #define __STDIO_H
#endif


Solch ein Schreibweise werden sie noch öfters sehen. Hier überprüft der Präprozessor ob die Headerdatei <stdio.h> noch nicht eingebunden hat. Dies ist zum Beispiel nötig wenn sie mehrer Headerdateien benutzen die <stdio.h> benötigen. Und somit würden alle Makros die in der Headerdatei <stdio.h> mehrmals definiert werden was schlimmsten Fall sogar einen Fehler auslösen kann. Mit dieser eben geschriebenen Struktur vermeiden sie dies.
Auch zu dieser Direktive gibt es eine andere Schreibweise....

#ifndef MAKRO
ist Daselbe wie
#if !defined MAKRO


Aufgabe 1:
Schreiben sie ein Programm das uns Auffordert eine Eingabe von Tastatur zu machen und überprüft ob es eine Nummer von 1-9, ein Buchstabe des Alphabetes oder ein Leerzeichen wie z.B. Space oder '\n' oder '\t' war. Benutzen sie dazu die '#define Anweisung'. Es darf außer '#include <stdio.h

Aufgabe 2: Wem das zu leicht war, der kann ja mal versuchen diese Aufgabe zu lösen. Schreiben sie ein Makro Namens ASSERT(bedienung) das überprüft ob die Bedienung wahr ist. Z.B (x<100). Sollte sie nicht wahr sein soll das Programm die Bedienung die falsch ist auf dem Bildschirm ausgeben mit dem Programmnamen. Der Programmname wird mit....

printf("Datei : %s\n",__FILE__);

...auf dem Bildschirm ausgegeben. Versuchen sie wenigstens sich vorzustellen wie es etwa aussehen könnte. Und benuten sie nicht die Headerdatei <ASSERT.H

Hier geht's zu den Lösungen!

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf