Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 10 Präprozessor-Direktiven
Pfeil 10.1 Einkopieren von Dateien mittels »#include«
Pfeil 10.2 Makros und Konstanten – »#define«
Pfeil 10.2.1 Symbolische Konstanten mit »#define«
Pfeil 10.2.2 Makros mit »#define«
Pfeil 10.3 Bedingte Kompilierung
Pfeil 10.4 Vordefinierte Präprozessor-Direktiven (ANSI C)
Pfeil 10.5 Ersetzung eines Makroparameters durch einen String
Pfeil 10.6 »#undef« – Makronamen wieder aufheben
Pfeil 10.7 Ausgeben von Fehlermeldungen – »#error«
Pfeil 10.8 »#pragma«


Rheinwerk Computing - Zum Seitenanfang

10.3 Bedingte Kompilierung topZur vorigen Überschrift

Zu diesem Unterkapitel muss erwähnt werden, dass viele der beschriebenen Vorgehensweisen nicht dem ANSI-C-Standard entsprechen. Da aber Programmierer oft ihre Programme auch auf andere Systeme portieren wollen, gehe ich hier dennoch näher auf die Thematik ein. Hierzu betrachten wir die Syntax zur bedingten Übersetzung:

#ifdef   symbol
#ifdef ( symbol )

#elif   symbol
#elif ( symbol )

#else

#endif

Diese Direktiven werden eingesetzt, um zu überprüfen, ob ein Symbol zuvor schon mit #define definiert wurde. Ist symbol definiert, liefern diese Direktiven 1 zurück, ansonsten 0. Abgeschlossen wird eine bedingte Übersetzung mit der Direktive #endif.

Sie haben im vorangegangenen Kapitel (bei der selbst geschriebenen Headerdatei) schon einen kurzen Einblick in die bedingte Kompilierung erhalten. Hierzu ein einfaches Beispiel:

/* clrscr.c */
#include <stdio.h>
#include <stdlib.h>
#ifdef __unix__
   #define clrscr() printf("\x1B[2J")
#elif __BORLANDC__ && __MSDOS__
   #include <conio.h>
#elif __WIN32__ || _MSC_VER
   #define clrscr() system("cls")
#else
   #define clrscr() printf("clrscr() - Fehler!!\n")
#endif

int main(void) {
   /* universale Routine zum Löschen des Bildschirms */
   clrscr();
   return EXIT_SUCCESS;
}

Hier wird vor der Übersetzung festgelegt, welche Routine zum Löschen des Bildschirms benutzt werden soll. Mit

#ifdef __unix__

überprüft der Präprozessor, ob das Programm auf einem UNIX-artigen System läuft. Wenn das der Fall ist, dann wird mit

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

die Routine zum Löschen des Bildschirms definiert, da diese eben nur unter UNIX/Linux funktioniert. Falls es sich nicht um ein UNIX-System handelt, wird mit

#elif __BORLANDC__ && __MSDOS__

überprüft, ob das Programm mit einem Borland-Compiler und unter MS-DOS übersetzt wird. Ist das der Fall, dann wird das Löschen des Bildschirms durch eine in der Headerdatei #include <conio.h> definierte Funktion mit demselbem Namen vorgenommen. Anschließend wird überprüft, ob das Programm in einem Win32-Fenster läuft oder mit dem Visual C++-Compiler übersetzt wird.

#elif __WIN32__ || _MSC_VER
   #define clrscr() system("cls")

Trifft keiner der geprüften Fälle zu, wird eine entsprechende Ausgabe erzeugt:

#else
   #define clrscr() printf("clrscr()-Fehler!!\n")

Abgeschlossen wird diese bedingte Kompilierung mit:

#endif

Durch die bedingte Kompilierung besteht die Möglichkeit, Programme einfacher auf andere Systeme zu portieren. Die bedingte Kompilierung lässt sich auch anders verwenden:

/* t_system.c */
#include <stdio.h>
#include <stdlib.h>

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

#elif __WIN32__ || _MSC_VER
int main(void) {
   printf("Programm läuft unter Win32\n");
   return EXIT_SUCCESS;
}

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

#else
int main(void) {
   printf("Unbekanntes Betriebssystem!!\n");
   return EXIT_SUCCESS;
}
#endif

Hier wurden mehrere main()-Funktionen verwendet. Auf dem System, für das die bedingte Kompilierung gilt, wird die entsprechende main-Funktion auch ausgeführt.

Abbildung 10.2 Bedingte Kompilierung – das Programm läuft unter Win32.

Abbildung 10.3 Bedingte Kompilierung – das Programm läuft unter Linux/UNIX.

Sie können die bedingte Kompilierung mit if else-Abfragen vergleichen. Um compiler-spezifische Abfragen zu tätigen, gibt es folgende Compiler-Konstanten:


Tabelle 10.3 Konstanten für bestimmte Compiler

Konstante Compiler
_MSC_VER

Microsoft C ab Version 6.0

_QC

Microsoft Quick C ab Version 2.51

_TURBOC_

Borland Turbo C, Turbo C++ und BC++

_BORLANDC_

Borland C++

_ZTC_

Zortech C und C++

_SC_

Symantec C++

_WATCOMC_

WATCOM C

_GNUC_

Gnu C

_EMX_

Emx Gnu C


Denken Sie daran, dass diese Konstanten nicht vom ANSI-C-Gremium vorgeschrieben sind!

Für die bedingte Kompilierung mit Betriebssystemen finden sich folgende Konstanten:


Tabelle 10.4 Konstanten für bestimmte Betriebssysteme

Konstante Betriebssystem
__unix__ oder __unix

UNIX-System

__MS_DOS__

MS-DOS

__WIN32__

Windows ab 95

__OS2__

OS2

_Windows

Zielsystem Windows

__NT__

Windows NT

__linux__

Linux

__FreeBSD__

FreeBSD

OpenBSD

OpenBSD

_SGI_SOURCE

SGI-IRIX mit Extension *.sgi

_MIPS_ISA

SGI-IRIX

_hpux

HP-UX


Es gibt sicherlich noch weitere Konstanten. Die hier genannten zählen zu den gängigsten. Sehen Sie sich ein anderes Programmbeispiel dazu an:

/* sektor.c */
#include <stdio.h>
#include <stdlib.h>
#ifdef __unix__ || linux
   #define SEKTORSIZE 4096
#elif __MSDOS__ || __WIN32__ || _MSC_VER
   #define SEKTORSIZE 512
#else
#define SEKTORSIZE 0
#endif

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

   if(s == 0)
      printf("Unbekanntes System\n");
   else if(s==4096)
      printf("UNIXsystem : ");
   else
     printf("DOS/Win32 : ");
   kb = size * s;
   printf("%ld Sektoren = %ld B\n", size, kb);
}

int main(void) {
   long sector;

   printf("Wie viele Sektoren: ");
   scanf("%ld",&sector);
   sect(sector);
   return EXIT_SUCCESS;
}

Dies ist ein Beispiel zum Thema Portabilität. Auf MS-DOS/Win32 beträgt die Größe eines Sektors auf der Festplatte 512 KB. Auf UNIX-Systemen hingegen beträgt sie meist 4096 KB (unter BSD für gewöhnlich 1024 KB) pro Sektor. Sie müssen nur am Anfang des Programms dem Präprozessor die Anweisung geben, für welches System er die Größe einer bestimmten Anzahl von Sektoren ausgeben soll.

Folgende Schreibweisen sind im Übrigen identisch:

#ifdef MAKRO
/* ist identisch mit */
#if defined MAKRO

Des Weiteren gibt es eine Direktive, die es Ihnen ermöglicht, zu überprüfen, ob etwas nicht definiert wurde:

#ifndef __STDIO_H
   #define __STDIO_H
#endif

Hier überprüft der Präprozessor, ob er die Headerdatei <stdio.h> noch nicht eingebunden hat.

Das ist zum Beispiel erforderlich, wenn mehrere Headerdateien und Module benutzt werden, die <stdio.h> benötigen. Somit würden alle Makros in der Headerdatei <stdio.h> mehrmals definiert werden, was im schlimmsten Fall sogar einen Fehler auslösen kann. Mit der eben geschriebenen Struktur wird dies vermieden.

Auch zu dieser Direktive gibt es eine alternative Schreibweise:

#ifndef MAKRO
/* ist dasselbe wie */
#if !defined MAKRO


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: C/C++






 C/C++


Zum Rheinwerk-Shop: Einstieg in C






 Einstieg in C


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: C++ Handbuch






 C++ Handbuch


Zum Rheinwerk-Shop: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern