Preprocesor jezyka C: dyrektywy, makrodefinicje
Transkrypt
Preprocesor jezyka C: dyrektywy, makrodefinicje
Preprocesor j¦zyka C: dyrektywy,
makrode nicje
wer. 6 z drobnymi mody kacjami
Wojciech Myszka
2014-02-09 16:29:57 +0100
Preprocesor
1. Pierwszym krokiem kompilacji jest przetwarzanie
programu za pomoc¡ preprocesora.
Preprocesor
1. Pierwszym krokiem kompilacji jest przetwarzanie
programu za pomoc¡ preprocesora.
2. Najcz¦±ciej stosowanymi poleceniami preprocesora
s¡:
Preprocesor
1. Pierwszym krokiem kompilacji jest przetwarzanie
programu za pomoc¡ preprocesora.
2. Najcz¦±ciej stosowanymi poleceniami preprocesora
s¡:
I
#include
Preprocesor
1. Pierwszym krokiem kompilacji jest przetwarzanie
programu za pomoc¡ preprocesora.
2. Najcz¦±ciej stosowanymi poleceniami preprocesora
s¡:
I
I
#include
#de ne
Preprocesor
1. Pierwszym krokiem kompilacji jest przetwarzanie
programu za pomoc¡ preprocesora.
2. Najcz¦±ciej stosowanymi poleceniami preprocesora
s¡:
I
I
I
#include
#de ne
polecenia kompilacji warunkowej (#if, #ifdef,
#ifndef, #endif, #else, #elif)
Wstawianie plików
1. Kazdy wiersz programu o postaci:
jest zast¦powany zawarto±ci¡ pliku o wskazanej
nazwie.
Wstawianie plików
1. Kazdy wiersz programu o postaci:
I
#include "nazwa-pliku"
jest zast¦powany zawarto±ci¡ pliku o wskazanej
nazwie.
Wstawianie plików
1. Kazdy wiersz programu o postaci:
I
I
#include "nazwa-pliku"
#include <nazwa-pliku>
jest zast¦powany zawarto±ci¡ pliku o wskazanej
nazwie.
Wstawianie plików
1. Kazdy wiersz programu o postaci:
I
I
#include "nazwa-pliku"
#include <nazwa-pliku>
jest zast¦powany zawarto±ci¡ pliku o wskazanej
nazwie.
2. Je±li nazwa pliku ograniczona jest cudzysªowami
poszukiwanie pliku rozpoczyna si¦ tam gdzie znaleziono
plik ¹ródªowy.
Wstawianie plików
1. Kazdy wiersz programu o postaci:
I
I
#include "nazwa-pliku"
#include <nazwa-pliku>
jest zast¦powany zawarto±ci¡ pliku o wskazanej
nazwie.
2. Je±li nazwa pliku ograniczona jest cudzysªowami
poszukiwanie pliku rozpoczyna si¦ tam gdzie znaleziono
plik ¹ródªowy.
3. Je±li nazwa pliku ograniczona jest nawiasami k¡towymi
<, > plik szukany jest w±ród plików systemowych
(w miejscach zaleznych od implementacji).
Wstawianie plików
1. Kazdy wiersz programu o postaci:
I
I
#include "nazwa-pliku"
#include <nazwa-pliku>
jest zast¦powany zawarto±ci¡ pliku o wskazanej
nazwie.
2. Je±li nazwa pliku ograniczona jest cudzysªowami
poszukiwanie pliku rozpoczyna si¦ tam gdzie znaleziono
plik ¹ródªowy.
3. Je±li nazwa pliku ograniczona jest nawiasami k¡towymi
<, > plik szukany jest w±ród plików systemowych
(w miejscach zaleznych od implementacji).
4. Plik wª¡czany poleceniem #include moze zawiera¢
kolejne polecenia #include.
Standardowe pliki nagªówkowe I
ANSI C library header les
Wazne pliki nagªówkowe:
1. <assert.h> Contains the assert macro, used to assist
with detecting logical errors and other types of bug in
debugging versions of a program.
2. <complex.h> A set of functions for manipulating
complex numbers. (New with C99)
3. <ctype.h> Contains functions used to classify
characters by their types or to convert between upper
and lower case in a way that is independent of the
used character set (typically ASCII or one of its
extensions, although implementations utilizing
EBCDIC are also known).
Standardowe pliki nagªówkowe II
ANSI C library header les
4. <errno.h> For testing error codes reported by library
functions.
5. <fenv.h> For controlling oating-point environment.
(New with C99)
6. < oat.h> Contains de ned constants specifying the
implementation-speci c properties of the
oating-point library, such as the minimum difference
between two different oating-point numbers
(_EPSILON), the maximum number of digits of
accuracy (_DIG) and the range of numbers which can
be represented (_MIN, _MAX).
Standardowe pliki nagªówkowe III
ANSI C library header les
7. <inttypes.h> For precise conversion between integer
types. (New with C99)
8. <iso646.h> For programming in ISO 646 variant
character sets. (New with NA1)
9. <limits .h> Contains de ned constants specifying the
implementation-speci c properties of the integer
types, such as the range of numbers which can be
represented (_MIN, _MAX).
10. <locale.h> For setlocale() and related constants. This
is used to choose an appropriate locale.
11. <math.h> For computing common mathematical
functions
Standardowe pliki nagªówkowe IV
ANSI C library header les
12. <setjmp.h> Declares the macros setjmp and longjmp,
which are used for non-local exits
13. <signal.h> For controlling various exceptional
conditions
14. <stdarg.h> For accessing a varying number of
arguments passed to functions.
15. <stdbool.h> For a boolean data type. (New with C99)
16. <stdint.h> For de ning various integer types. (New
with C99)
17. <stddef.h> For de ning several useful types and
macros.
Standardowe pliki nagªówkowe V
ANSI C library header les
18. <stdio.h> Provides the core input and output
capabilities of the C language. This le includes the
venerable printf function.
19. <stdlib .h> For performing a variety of operations,
including conversion, pseudo-random numbers,
memory allocation, process control, environment,
signalling, searching, and sorting.
20. <string.h> For manipulating several kinds of strings.
21. <tgmath.h> For type-generic mathematical functions.
(New with C99)
Standardowe pliki nagªówkowe VI
ANSI C library header les
22. <time.h> For converting between various time and
date formats.
23. <wchar.h> For manipulating wide streams and several
kinds of strings using wide characters - key to
supporting a range of languages. (New with NA1)
24. <wctype.h> For classifying wide characters. (New
with NA1)
Makrorozwini¦cia I
1. Makrorozwini¦cia to de nicje które pozwalaj¡ duzy
fragment tekstu zast¡pi¢ krótkim:
#define nazwa z a s t e p u j a c y _ t e k s t
2. Kazde uzycie ci¡gu znaków nazwa zostanie zamienione
przez zastepujacy_tekst.
3. De nicja moze korzysta¢ z poprzednich de nicji.
4. Makrorozwini¦cia nie obowi¡zuj¡ wewn¡trz staªych
tekstowych (ograniczonych znakami cudzysªowów).
Makrorozwini¦cia II
5. Makrorozwini¦cia stosuje si¦ do caªych jednostek
leksykalnych. Zatem jezeli zde niowane jest co±
takiego:
#define YES " Tak "
to kazde wyst¡pienie YES zostanie zamienione na
"Tak", ale nie b¦dzie to dotyczyªo
p r i n t f ( " YES " ) ;
albo wyst¡pienia napisu YESMAN
A co b¦dzie w przypadku
p r i n t f ( YES ) ;
Makrorozwini¦cia z parametrami I
1. Istnieje mozliwo±¢ de niowania makr z argumentami
zast¦puj¡cy tekst moze by¢ rózny dla róznych
wywoªa«:
#define max ( A , B ) ( ( A ) > ( B ) ? ( A ) : ( B ) )
Bardzo przypomina wywoªanie funkcji, ale
realizowane b¦dzie w sposób nast¦puj¡cy:
I
Pojawienie si¦ w tek±cie programu napisu
x = max ( p+q , r + s ) ;
zostanie rozwini¦te jako
x = ( ( p+q ) > ( r + s ) ? ( p+q ) : ( r + s ) )
Makrorozwini¦cia z parametrami II
I
Rozwi¡zanie takie ma wad¦: wyrazenia obliczane s¡
dwukrotnie, zatem w
z = max ( i ++ , j + + ) ;
warto±ci i, j zostan¡ zwi¦kszone dwukrotnie!
2. W przypadku gdy makrorozwini¦cia uzywane s¡ do
prowadzenia oblicze«, pami¦ta¢ nalezy o
odpowiednim stosowaniu nawiasów.
#define square ( x ) x ∗ x
tªumaczone jest rozs¡dnie w najprostszym przypadku
y = square(v); na
Makrorozwini¦cia z parametrami III
y = v ∗ v;
ale w przypadku y = square(v + 1); na
y = v + 1 ∗ v + 1;
3. Poprawna de nicja powinna wygl¡da¢ jako± tak:
#define square ( x ) ( x ) ∗ ( x )
4. Uwaga: pomi¦dzy nazw¡ a nawiasem otwieraj¡cym
nie moze by¢ odst¦pu!
5. Makra rozwijanie s¡ przed kompilacj¡!
Makrorozwini¦cia z parametrami I
1. Jezeli nazw¦ parametru w zast¦puj¡cym tek±cie
poprzedzimy znakiem # to caªa kombinacja (parametr
i znak) zostan¡ rozwini¦te w ci¡g znaków
ograniczonych cudzysªowami.
2. Przyjmijmy, ze mamy tak¡ de nicj¦:
#define drukuj ( t e k s t ) p r i n t f ( # t e k s t )
to wywoªanie
drukuj ( a l a ma kota ) ;
jest rozwijane w
p r i n t f ( " a l a ma kota " ) ;
Makrorozwini¦cia z parametrami II
3. Znaków ## mozna uzywa¢ do sklejania parametrów
formalnych. Makro
#define s k l e j ( przod , t y l ) przod ## t y l
wywoªane
s k l e j ( a , 1)
zostanie rozwini¦te jako a1
Makrorozwini¦cia
Prosty przykªad
# i f d e f DEBUG
# include < s t d i o . h>
# define wypisz ( x ) do { p r i n t f ( " Zmienna " # x \
" = %d \ n " , x ) ; } \
while ( 0 ) ;
#else
# define wypisz ( x )
# endif
Uzycie
#define DEBUG
...
wypisz ( a ) ;
Odwoªywanie makra
Jezeli jaka± de nicja przestaje by¢ potrzebna mozna j¡
zlikwidowa¢ za pomoc¡ polecenia
#undef
Na przykªad tak:
#define DEBUG 1 /∗ Wydruki d i a g n o s t y c z n e ∗/
/∗ . . .
∗/
# i f d e f DEBUG
/∗ . . .
∗/
# endif
/∗ . . .
∗/
#undef DEBUG
/∗ . . .
∗/
Makrorozwini¦cia
Przykªad
# i f d e f DEBUG
# include < s t d i o . h>
# define D ( x ) do { p r i n t f ( " %s :%d (% s ) " , \
__FILE__ , __LINE__ , \
__FUNCTION__ ) ; \
printf x ;\
fputc ( ' \ n ' , stdout ) ; \
f f l u s h ( stdout ) ; } \
while ( 0 ) ;
#else
# define D ( x )
# endif
Uzycie makra D
D(("z= %d ", z))
Czemu tak?
Kompilacja warunkowa I
Preprocesor zostaª wyposazony w kilka polece«
pozwalaj¡cych na sterowanie przetwarzaniem kodu
¹ródªowego. S¡ to:
# i f warunek
/∗ . . .
# endif
# i f warunek
/∗ . . .
#else
/∗ . . .
# endif
∗/
∗/
∗/
Kompilacja warunkowa II
# i f warunek1
/∗ . . .
# e l i f warunek2
/∗ . . .
# e l i f warunek3
/∗ . . .
#else
/∗ . . .
# endif
∗/
∗/
∗/
∗/
Dodatkowo sprawdza¢ mozna czy zostaªy zde niowane
makra poleceniami
Kompilacja warunkowa III
# i f d e f makro
/∗ . . .
# endif
∗/
Oraz czy makro nie zostaªo zde niowane
# i f n d e f makro
/∗ . . .
# endif
∗/
Kompilacja warunkowa
Po co?
1. Warunkowe wª¡czanie kodu na potrzeby uruchomienia
(DEBUG).
2. Tworzenie kodu przeno±nego w zalezno±ci od wersji
systemu (kompilatora) standardowy zestaw
makrode nicji zawarty moze by¢ w plikach
nagªówkowych.
3. Zakomentowanie duzego fragmentu kodu.
Zmienne preprocesora
Wiele z tego zalezy od implementacji, ale zazwyczaj zde niowane s¡ nast¦puj¡ce
zmienne:
__LINE__
__FILE__
__DATE__
__TIME__
__cplusplus
__STDC__
1. __LINE__ i __FILE__ oznaczaj¡, odpowiednio, numer linii ¹ródªowej
kompilowanego pliku i jego nazw¦.
Zmienne preprocesora
Wiele z tego zalezy od implementacji, ale zazwyczaj zde niowane s¡ nast¦puj¡ce
zmienne:
__LINE__
__FILE__
__DATE__
__TIME__
__cplusplus
__STDC__
1. __LINE__ i __FILE__ oznaczaj¡, odpowiednio, numer linii ¹ródªowej
kompilowanego pliku i jego nazw¦.
2. Zmienna __DATE__ zawiera dat¦ precyzyjniej dat¦ kiedy dokonywana jest
kompilacja.
Zmienne preprocesora
Wiele z tego zalezy od implementacji, ale zazwyczaj zde niowane s¡ nast¦puj¡ce
zmienne:
__LINE__
__FILE__
__DATE__
__TIME__
__cplusplus
__STDC__
1. __LINE__ i __FILE__ oznaczaj¡, odpowiednio, numer linii ¹ródªowej
kompilowanego pliku i jego nazw¦.
2. Zmienna __DATE__ zawiera dat¦ precyzyjniej dat¦ kiedy dokonywana jest
kompilacja.
3. Zmienna __TIME__ zawiera czas precyzyjniej czas kiedy dokonywana jest
kompilacja.
Zmienne preprocesora
Wiele z tego zalezy od implementacji, ale zazwyczaj zde niowane s¡ nast¦puj¡ce
zmienne:
__LINE__
__FILE__
__DATE__
__TIME__
__cplusplus
__STDC__
1. __LINE__ i __FILE__ oznaczaj¡, odpowiednio, numer linii ¹ródªowej
kompilowanego pliku i jego nazw¦.
2. Zmienna __DATE__ zawiera dat¦ precyzyjniej dat¦ kiedy dokonywana jest
kompilacja.
3. Zmienna __TIME__ zawiera czas precyzyjniej czas kiedy dokonywana jest
kompilacja.
4. Zmienna __cplusplus zde niowana jest tylko wtedy, gdy kompilowany jest
program w j¦zyku C++.
Zmienne preprocesora
Wiele z tego zalezy od implementacji, ale zazwyczaj zde niowane s¡ nast¦puj¡ce
zmienne:
__LINE__
__FILE__
__DATE__
__TIME__
__cplusplus
__STDC__
1. __LINE__ i __FILE__ oznaczaj¡, odpowiednio, numer linii ¹ródªowej
kompilowanego pliku i jego nazw¦.
2. Zmienna __DATE__ zawiera dat¦ precyzyjniej dat¦ kiedy dokonywana jest
kompilacja.
3. Zmienna __TIME__ zawiera czas precyzyjniej czas kiedy dokonywana jest
kompilacja.
4. Zmienna __cplusplus zde niowana jest tylko wtedy, gdy kompilowany jest
program w j¦zyku C++.
5. Zmienna __STDC__ zde niowana jest wtedy, gdy kompilowany jest program
w j¦zyku C.