Przyklady:
PREPROCESOR
1)
Preprocesor jest wywoływany w pierwszym kroku tłumacze- #define YES 1
nia programu; przed rozpocz¸ wÅ‚aÅ›ciwej kompilacji.
eciem
2)
#define then
Preprocesor przetwarza tekst zródłowy progarmu !!!
#define begin {
#define end ;}
Wstawianie plików
Cz¸ na pocz¸ programu pojawiaja sie jeden lub dwa
esto atku ¸ ¸
Nast¸ można pisać:
epnie
wiersze postaci:
if (i>0) then
begin
#include
a=1;
albo b=2;
#include "nazwa_pliku" end
Makro z argumentami
Oznaczaj¸ one, że w miejscu wyscapienia polecenia inc-
a
lude zostanie wstawiona zawartość pliku określonego przez
nazwa_pliku.
#define identyfikator(lista-identyfikatorow) \
oznacza, ze plik bedzie poszukiwany zgodnie z
ciag-leksemow
zasadami obowiazujacymi w implementacji
¸ ¸
"nazwa_pliku"oznacza, że poszukiwanie pliku zaczyna si¸ tam,
e
gdzie znaleziono progarm zródłowy, a jeśli w tym miejscu go nie
ma, to plik jest poszukiwany zgodnie z zasadami obowiazuj¸ PrzykÅ‚ad:
¸ acymi
w implementacji.
Ograniczenia w przypadku użycia pierwszej formy:
#define max(a,b) ((a)>(b)?(a):(b))
" W nazwa_pliku nie może wystapić znak > oraz znak
¸
nowego wiersza Nawiasy w definicji sa istotne, ponieważ np.
" Skutek tej instrukcji jest nieokreÅ›lony, jeżeli wyst¸
api
x=max(p+q,r+s);
kt6óryś ze znaków " \ lub para znaków /* .
zostanie zastapione przez
x=((p+q)>(r+s)?(p+q):(r+s);
Ograniczenia w przypadku użycia drugiej formy:
" skutek użycia znaków \ oraz pary znaków
Kilka reguł:
/* jest nadal nieokreślony
" definicja może korzystać z poprzednich definicji (zagnież-
dżenie),
" znak > jest dozwolony
" makrorozwini¸ nie obowiazuje w staÅ‚ych tekstowych
ecie ¸
Możliwe jest również użycie wiersza postaci:
ograniczonych znakami cudzysłowu, np.
printf("YES");
#include ciag_leksemow
nie spowoduje zast¸ YES.
apienia
Ciag leksemów jest rozwijany wówczas zgodnie ze zwykłymi re-
¸
Przykład 2:
gułami, natomiast w wyniku musi doprowadzić do jednej z po-
staci: <...> albo "...".
/* makro zamieniajace miejscami argumenty */
Stosowanie #include jest zalecanym sposobem sporz¸ #define SWAP(x,y) { \
adzania
deklaracji dla dużego programu. Gwarantuje to identyczność double tmp; \
definicji i deklaracji zmiennych i funkcji. tmp=x; \
Uwaga: W¸ plików może być zagnieżdżone. x=y; \
aczanie
y=tmp; \
Makrorozwini¸ zast¸ nazwy przez ci¸ zna-
ecia apienie ag
}
ków
Zas¸ dyrektywy od miejsca wyst¸ do koÅ„ca pliku.
ego apienia
Przykład 3:
Wiersz sterujacy o postaci
¸
#define DOPISZ(name,f,thing) \
{\
FILE *out; \
#define identyfikator ciag-leksemow
out=fopen("a:\\kat\\"#name,"a");\
fprintf(out,f,thing); \
fclose(out); \
zleca preprocesorowi zast¸ dalszych wyst¸ identyfi-
epowanie apień
}
katora wskazanym ciagiem leksemów. Opuszca si¸ odstepy ota-
¸ e ¸
czajace ciag leksemów.
¸ ¸
UWAGA: Należy unikać jako argumentów wyrażeÅ„ maj¸
acych
Uwaga Ponowne wystapienie #define z tym samym
¸
efekty uboczne, a także wywołań funkcji, ponieważ po roz-
identyfikatorem traktuje si¸ jako bÅ‚edne, jeżeli ciagi leksemów
e ¸
wini¸ makrodefinicji tekst może zostać wstawiony kilkakrot-
eciu
nie s¸ w obu przypadkach identyczne (przy tym wszystkie biaÅ‚e
a
nie.
plamy rozdzielajace leksemy traktuje si¸ jako równoważne).
¸ e
Przykłady:
#define max(x,y) ((x)>(y)?(x):(y)) var123
maximum=max(++a,10);
Wynik wywolania
/* wynikiem b\c edzie 10 albo a+2 */
/* a bedzie zwiekszone o 1 lub 2 */
cat(cat(1,2),3)
maximum=max(fgetc(file),maximum);
jest nieokreślony; obecność operatora ## zapobiega roz-
/* tak mozna sasiada najwiekszego
wini¸ argumentów wewn¸ wywoÅ‚ania.
eciu etrznego
znaku w pliku */
W rezultacie powstanie cat( 1 ,2 )3 , w którym lek-
sem )3 (wynik sklejenia ostatniego leksemu pierwszego ar-
maximum=max(rand(),maximum);
gumentu z pierwszym leksemem drugiego jest niepoprawny.
/* !!!!!! */
Po wprowadzeniu makra drugiego poziomu
Uwaga: Ostrożnie z używaniem średnika w makrodefinicjach.
#define xcat(x,x) cat(x,y)
Wiersz sterujacy o postaci
¸
wszystko to działa bardziej przyzwoicie: xcat(xcat(1,2),3) rze-
#undef identyfikator czywiście tworzy leksem 123, ponieważ w samym xcat nie
wyst¸ operator ## .
epuje
Podobnie ABSDIFF(ABSDIFF(a,b),c) tworzy wynik w
zleca preprocesorowi, aby zapomniaÅ‚ definicj¸
eidentyfikatora. Za- pełni rozwiniety zgodnie z oczekiwaniem.
¸
stosowanie #undef do nie zdefiniowanego identyfikatora nie
Kompilacja warunkowa
jest bÅ‚¸
edem.
Fragmenty programu mog¸ być kompilowane warunkowo
a
Znaki # i ##
zgodnie z poniższ¸ schematyczn¸ skÅ‚adnia:
a a ¸
Jeśli parametr poprzedzany znakiem # , to identyfikator
parametru wraz ze znakiem # zostan¸ ¸ odpowied-
azastapione
nim argumentem otoczonym znakami cudzysłowu " . Kompilacja warunkowa:
Każdy ze znaków " i \ wyst¸ acy na pocz¸ w wiersz-if tekst czesci-elif czesc-else #endif
epuj¸ atku,
Å›rodku lub na koÅ„cu staÅ‚ych znakowych i napisów tworz¸
acych
argument zostanie poprzedzony znakiem \ . wiersz_if:
#if wyrazenie-stale
JeÅ›li w ciagu leksemów definiuj¸ makro wyst¸ opera-
¸ acych api
#ifdef identyfikator
tor ## , to po zastapieniu parametrów napisami operator
¸
#ifndef identyfikator
## wraz z otaczajacymi go biaÅ‚ymi plamami zostanie usuni¸
¸ ety.
Jeśli tak utworzony leksem jest niepoprawny lub wykonanie
czesci el-if:
zależy od kolejności, to skutek jest niezdefiniowany.
wiersz-elif tekst
Niezależnie od postaci makrodefinicji zast¸ acy ciag lek-
epuj¸ ¸
czesci-elif
semów jest wielokrotnie przegladany w poszukiwaniu innych
¸
tak zdefiniowanych identyfikatorów. Jeżeli jednak identyfikator
wiersz-elif:
zast¸ już w danym rozwinieciu, znów pojawi si¸ przy po-
apiony ¸ e
#elif wyrazenie stale
nownym przegladaniu, to pozostanie w rozwini¸ tekÅ›cie bez
¸ etym
zmiany.
czesc-else
wiersz_else tekst
Mechanizm makrodefinicji przydaje si¸ do definiowania
e
wżnych stałych
czesc-else:
Przykład:
wiersz-else tekst
#define ABSDIFF(a,b) ((a)>(b)?(a)-(b):(b)-(a))
wiersz-else:
#else
Definiuje makro zwracaj¸ wartość absolutn¸ różnicy jego ar-
ace a
gumentów.
W przeciwieństwie do funkcji zwracana wartość może być dowol- Kilka reguł:
nego typu.
" Wyrażenia staÅ‚e wyst¸ ace w #if i #elif s¸ ob-
epuj¸ a
liczane kolejno, aż do wyst¸ wyrażenia z niezerow¸
apienia a
#define tempfile(dir) #dir "/%s"
wartościa.
¸
" Tekst nastepuj¸ po wyrażeniach z zerow¸ wartoÅ›cia
¸ acy a ¸
Wywołanie tempfile(/usr/tmp) daje w wy-
opuszcza si¸ w czasie kompilacji.
e
niku
" Tekst wyst¸ acy po wyrażeniach z pozytywn¸ ¸
epuj¸ awartoÅ›cia
jest właczany do programu.
¸
"/usr/tmp" "/%s"
" Po znalezieniu wyrażenia z pozytywn¸ ¸ i jego ob-
awartościa
sÅ‚użeniu to kolejne wiersze #elif lub #else s¸ po-
a
co nast¸ zostaje sklejone w jeden napis. Przy definicji
epnie
mijane wraz z ich tekstami.
" Jeżeli wszystkie wyrażenia s¸ równe zero i wyscepuje
a
#define cat(x,y) x ## y
#else , to obsÅ‚uguje sie tekst nast¸ acy po
¸ epuj¸
#else .
Wywolanie
epuj¸ eziach
cat(var,123) " Tekst wyst¸ acy w gaÅ‚¸ nieaktywnych jest ignoro-
wany, ale sprawdza si¸ najpierw, czy nie wyst¸ a wnim
e epuj¸
produkuje leksem zagnieżdżone konstrukcje warunkowe.
Wyrzżenia staÅ‚e w #if i #elif s¸ przedmiotem zwy- zleca kompilatorowi, aby dla celów diagnostycznych przyjaÅ‚, że
a ¸
kÅ‚ych makrorozwini¸ nast¸ wiersz zródÅ‚owy b¸ miaÅ‚ numer okre:ony przez
eć. epny edzie
Wyrażenia postaci: staÅ‚a, a nazw¸ bieżacego pliku zródÅ‚owego b¸ nazwa-pliku.
¸ a ¸ edzie
Makra wyst¸ ace w takich wierszach s¸ rozwijane przed
epuj¸ a
interpretacja instrukcji.
¸
defined identyfikator
Generowanie bÅ‚¸
edów
lub
defined ( identyfikator )
Wiersz sterujacy o postaci
¸
przed rozwijanie makr otrzymuja wartość:
¸
#error ciag-leksemow
1L - jeśli identyfikator jest zdefiniowany w preprocesorze
zleca procesorowi wypisanie komunikatu diagnostycznego zawie-
0L - jeśli nie jest zdefiniowany
raj¸ podany ciag leksemów.
acego ¸
Wszystkie identyfikatory pozostaÅ‚e po makrorozwini¸
eciach
Instrukcja pragma
otrzymuja wartość 0L , a cała arytmetyka na stałych jest
¸
Wiersz sterujacy o postaci
¸
przeprowadzana na liczbach całkowitych długich lub długich bez
znaku.
Wynikowe wyrażenie stałe ma ograniczenia:
#pragma ciag-leksemow
" musi być całkowite
zleca procesorowi podj¸ akcji zależnej od implementacji. Nie-
ecie
" nie może zawierać operatora sizeof, rzutowania i stałych
znana akcja jest ignorowana.
wyliczeń.
Pusta instrukcja preprocesora
Wiersze sterujace postaci:
¸
Wiersz zawieraj¸ jedynie znak # nie ma żadnego
acy
skutku.
#ifdef identyfikator
Nazwy zdefiniowane w preprocesorze
#indef identyfikator
Definicji tych nazw, jak rówmież operatora defined
(wyst¸ acego w wyrażeniach preprocesora), nie można odwo-
epuj¸
s¸ równoważne:
a
łać ani zmienić.
" LINE Dziesi¸ staÅ‚a caÅ‚kowita zawierajaca numer
etna ¸
#if defined identyfikator
bież¸ wiersza programu zródÅ‚owego
acego
#if ! defined identyfikator
" FILE StaÅ‚a napisowa zawieraj¸ nazw¸ tÅ‚umaczo-
aca e
nego pliku
Przykłady:
" DATE StaÅ‚a napisowa zawieraj¸ dat¸ tÅ‚umaczenia
aca e
1) /* Kompilowanie programu w kilku wersjach */
programu w formacie "Mmm dd rrrr"
#define DEMO
" TIME StaÅ‚a napisowa zawierajça czas tÅ‚umaczenia
#ifdef DEMO
programu w formacie "gg:mm:ss"
/* kod tylko dla wersji demonstracyjnej */
" STDC Stała 1. Z zamierzenia identyfikator ten po-
instrukcje
winien być zdefiniowany z wartościa 1 jedynie w imple-
¸
mentacjach dostosowanych do standardu.
#endif
#ifndef DEMO
/* Kod tylko dla wersji normalnej */
#endif
2) /* Uniemozliwienie wielokrotnego przetwarzania
tego samego kodu zrodlowego */
/* poczatek pliku naglowkowego okienka.h */
#ifndef OKIENKA
#define OKIENKA
/* tresc pliku */
#endif
/* Koniec pliku okienka */
Numeracja wierszy
Dla potrzeb innych preprocesorów, które generuj¸ programy
a
wjezyku C, wiersz majacy jedn¸ z postaci
¸ ¸ a
#line stala "nazwa-pliku"
#line stala
Wyszukiwarka
Podobne podstrony:
c cxx w09
W09 IL aproksymacja cz 2(1)
w09 b
anl1 w09 lato2009
W09 Interfejsy komunikacji bezprzewodowej irDA, Bluetooth
PodstawyProgramowania W09
AM23 w09 Całki podwójne
m1 w09
MPiS30 W09 Podstawy statystyki matematycznej
bal w09
W09
Multimedia W09
W09 produkcja III
W09 sprzegla
WM w09 2 w10 Energia okno
W09 Miedź i stopy miedzi
więcej podobnych podstron