edv1 - 04präprozessor der c-präprozessor. edv1 - 04präprozessor 2 der c-präprozessor bevor ein...

24
EDV1 - 04Präprozessor Der C-Präprozessor

Upload: uwe-anderman

Post on 05-Apr-2015

111 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

EDV1 - 04Präprozessor

Der C-Präprozessor

Page 2: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

2

Der C-Präprozessor

• Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird es vom C-Präprozessor bearbeitet. Dabei werden reine Textersetzungen durchgeführt. Der Präprozessor erzeugt den vom Compiler zu übersetzenden Quelltext.

C-Quelltext mitPräprozessor-anweisungen

C-Quelltext ohnePräprozessor-anweisungen

Objektmodule

AusführbaresProgramm Bibliotheken

Prä

proz

esso

r

Com

pile

rV

erbi

nder

Page 3: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

3

Die Präprozessoranweisungen

• Anweisungen für den Präprozessor beginnen immer mit # in der ersten Spalte.

• Es gibt folgende Präprozessoranweisungen:– #include : Einfügen einer Datei– #define : Definieren einer Konstanten oder eines Makros– #if (#ifdef, #ifndef) - #elif - #else – #endif :

bedingte Übersetzung

Page 4: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

4

Die include-Anweisung

• Die include-Anweisung fügt eine Datei in den Quelltext ein.• Es ist genau so als ob der Inhalt der eingefügten Datei statt der

include-Anweisung steht.

Datei „limits.h“ enthält:

char min_char=-128;

char max_char=127;

Datei „prog.c“ enthält:

#include "limits.h"

int main()

{

char c;

for (c=min_char;c<max_char;c++)

printf("char[%i]=%c\n",c,c);

printf("char[%i]=%c\n",c,c);

}

Page 5: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

5

• Compileraufruf:gcc –ansi prog.c –E –o prog.ierzeugt die Datei „prog.i“

# 1 "prog.c"# 1 "limits.h" 1char min_char=-128;char max_char=127;# 1 "prog.c" 2int main(){char c;for (c=min_char;c<max_char;c++)printf("char[%i]=%c\n",c,c);printf("char[%i]=%c\n",c,c);}

Page 6: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

6

• Zwei Formen der include-Anweisung– #include <filename>

sucht die Datei im Standarbibliothekspfad– #include "filename"

sucht die Datei im aktuellen Verzeichnis• Z.B.:

#include <stdio.h>

#include "limits.h"• Anwendungen der include-Anweisung:

– Einfügen von „header“-Dateien, die die Schnittstellendefinition von Prozeduren enthalten

– Einfügen von Definitionen von Konstanten und Typen

Page 7: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

7

Die define - Anweisung

• Mit der define-Anweisung werden Konstanten und Macros definiert. Allgemeine Form:#define <NAME> <ZEICHENKETTE>

• Nach dieser define-Anweisung wird jedes Auftreten von <NAME> als ganzes Wort im Text durch <ZEICHENKETTE> ersetzt.

Page 8: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

8

Beispiel

• limits.h#define MIN_CHAR –128#define MAX_CHAR 127

• prog.c#include "limits.h"int main(){char c;for (c=MIN_CHAR;c<MAX_CHAR;c++)printf("char[%i]=%c\n",c,c);printf("char[%i]=%c\n",c,c);}

Page 9: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

9

# 1 "prog.c"

# 1 "limits.h" 1

# 1 "prog.c" 2

int main()

{

char c;

for (c= -128 ;c< 127 ;c++)

printf("char[%i]=%c\n",c,c);

printf("char[%i]=%c\n",c,c);

}

Page 10: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

10

• Zusammen mit der include-Anweisung kann damit ein Programm sehr flexible geschrieben und dann durch geringe Änderungen an die Hardware angepasst werden.

• Beispiel:#define TEXT1 "Das ist ein ganz langer Text."#define TEXT2 "Das ist noch ein langer Text."#define TEXT3 "Das ist der dritte lange Text."printf(" %s\n %s\n %s\n",TEXT1,TEXT2,TEXT3);

• define-Anweisung wird genutzt, um Programme übersichtlicher zu gestalten und bestimmte möglicherweise öfter zu ändernde Programmteile an einer Stelle zu konzentrieren.

• define-Anweisungen können ersetzt werden durch die Angabe des D-Schalters beim Compilerauffruf. Z.B:gcc –DTRUE=1 hello.cbewirkt die Einfügung der Anweisung#define TRUE 1vor das Programm hello.c.

Page 11: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

11

Macros

• Macros dienen der parametrisierten Ersetzung von Zeichenketten durch Ausdrücke.

• Beispiel:#define MAX(A,B) (((A)>(B))?(A):(B))float a,b,c;c=MAX(a+b,a-b);wirkt wiec=(((a+b)>(a-b))?(a+b):(a-b));

• Achtung!– Immer ausreichend Klammern gebrauchen!– Trennzeichen in der define-Anweisung trennen den zu

definierenden Namen von der Definition, solange sie nicht in Klammern eingeschlossen sind. #define MAX(A,B) (((A)>(B))?(A):(B))#define MAX( A,B) (((A)>(B))?(A):(B))#define MAX (A,B) (((A)>(B))?(A):(B))sind zulässig haben aber z.T. unterschiedliche Bedeutung

Page 12: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

12

Beispiel

#define MAX(A,B) (((A)>(B))?(A):(B))

#define MIN(A,B) (((A)<(B))?(A):(B))

int main()

{

int i,j;

int max=MAX(i,j);

int min=MIN(i,j);

int m=MAX(i-j,j-i)*MIN(i-j,j-i);

}

Page 13: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

13

# 1 "prog.c"

int main()

{

int i,j;

int max= ((( i )>( j ))?( i ):( j )) ;

int min= ((( i )<( j ))?( i ):( j )) ;

int m= ((( i-j )>( j-i ))?( i-j ):( j-i )) * ((( i-j )<( j-i ))?( i-j ):( j-i )) ;

}

Page 14: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

14

Spezielle Operatoren in Macros• #<NAME> bewirkt, dass der Wert nach dem Ersetzen in "-" gesetzt

wird. • <NAME1>##<NAME2> bewirkt die direkte Verkettung der Werte von

<NAME1> und <NAME2>.

Page 15: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

15

Beispiel

#define PRINT(X) printf("Wert von %s = %i\n",#X,X)

#define INIT(A,B) A##B=(A)*100+(B)

int main()

{

int c=20;

int j=0;

int INIT(c,j);

PRINT(c);

PRINT(j);

PRINT(cj);

}

Page 16: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

16

# 1 "oper.c"

int main()

{

int c=20;

int j=0;

int cj =( c )*100+( j ) ;

printf("Wert von %s = %i\n","c", c ) ;

printf("Wert von %s = %i\n","j", j ) ;

printf("Wert von %s = %i\n","cj", cj ) ;

}

Page 17: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

17

Vordefinierte Macros - GNUC__LINE__

__FILE__

__DATE__

__TIME__

Weitere von Compilern abhängige Macros:

__STRICT_ANSI__ 1

_LANGUAGE_C 1

__GNUC__ 2

__GNUC_MINOR__ 7

__unix__ 1

Page 18: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

18

Beispielint main ()

{

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

printf("Date : %s\n",__DATE__);

printf("Time : %s\n",__TIME__);

printf("LineNr. : %i\n",__LINE__);

}

# 1 "vordef.c"

int main ()

{

printf("Filename : %s\n","vordef.c");

printf("Date : %s\n","May 1 2000");

printf("Time : %s\n","09:51:49");

printf("LineNr. : %i\n",6);

}

Page 19: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

19

Macros als Compiler-Schalter

• Durch Angabe des Compilerschalters "-D" können Macros nachträglich definiert werden. Z.B.:cc hello.c –Dname1 –Dname2=wertentspricht der Einfügung von#define name1#define name2 wertam Anfang des Quelltextes hello.c

• Wird häufig benutzt um spezielle Versionen aus einer Quelle zu erzeugen, z.B.:– Hardwareabhängigkeit– Genauigkeitsversionen (float, double)– Größenversionen– Unterschiedliche Interface (X11, Windows)

Page 20: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

20

Bedingte Übersetzung• #if (#ifdef, #ifndef) - #elif - #else – #endif• Mit Hilfe der Anweisungen zur bedingten Übersetzung können

bestimmte Teile des C-Programmes zur Übersetzung ausgewählt bzw. von der Übersetzung ausgenommen werden.

• Allgemeine Form:#if AUSDRUCK1text1#elif AUSDRUCK2text2#elif AUSDRUCK3text3#elsetext4#endif

• Es sind nur einfache logische Ausdrücke mit numerischen Werten erlaubt. FALSE==0, TRUE != 0.

Page 21: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

21

• Statt #if AUSDRUCK kann auch #ifdef MACRO bzw. #ifndef MACRO stehen. In diesen wird geprüft ob das Macro definiert bzw. nicht definiert ist.

Page 22: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

22

Beispiel

int main ()

{

#if BETA && DEMO

printf(

"Beta-Version %i\n%i - Tage Demo\n",BETA,DEMO);

#elif BETA

printf(

"Beta-Version %i\nunbegrenzte Lizenz\n",BETA);

#elif DEMO

printf("Final Release\n%i - Tage Demo\n",DEMO);

#else

printf("Final Release\nunbegrenzte Lizenz\n");

#endif

}

Page 23: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

23

• gcc –ansi bed.c –DBETA=2 –DDEMO=30 –E –o bed.iint main (){

printf("Beta-Version %i\n%i - Tage Demo\n",2 ,30 );}

• gcc –ansi bed.c –DBETA=0 –DDEMO=30 –E –o bed.iint main (){

printf("Final Release\n%i - Tage Demo\n",30 );}

• gcc –ansi bed.c –DBETA=2 –DDEMO=0 –E –o bed.iint main (){

printf("Beta-Version %i\nunbegrenzte Lizenz\n",2 );}

• gcc –ansi bed.c –DBETA=0 –DDEMO=0 –E –o bed.iint main (){

printf("Final Release\nunbegrenzte Lizenz\n");}

Page 24: EDV1 - 04Präprozessor Der C-Präprozessor. EDV1 - 04Präprozessor 2 Der C-Präprozessor Bevor ein Programm vom eigentlichen C-Compiler bearbeitet wird, wird

ED

V1 - 04P

räpro

zessor

24

Typisches Header-File

stdio.h

#ifndef _INC_STDIO

#define _INC_STDIO

...

#endif /* _INC_STDIO */