w11, Studia PK, JiPP, Wykłady - Chmaj
[ Pobierz całość w formacie PDF ]
Preprocesor • włącza się automatycznie, bez udziału uŜytkownika • poprzedza kompilację • dokonuje konwersji tekstu • realizuje dyrektywy (linie zaczynające się od znaku #) • dyrektywy mogą wystąpić w dowolnym miejscu tekstu programu • oprócz realizacji dyrektyw – wykonanie pewnych standardowych przekształceń: o wszystkie wystąpienia znaków ‘\’ po którym natychmiast następuje ‘\n’ są usuwane – następny wiersz zostaje połączony z tym, w którym był znak ‘\’ o usuwane są wszystkie komentarze – są zamieniane na pojedynczą spację o sekwencje specjalne w stałych znakowych i tekstowych są zamieniane na ich równowaŜniki (np. sekwencja ‘\n’ jest zamieniana znakiem o kodzie ASCII 13) o następuje połączenie sąsiednich stałych tekstowych w jedną stałą tekstową, np.: ”Ala ” ”ma kota” ë ”Ala ma kota” Makrodefinicje (dyrektywa #define) • składnia #define identyfikator ci ą g_symboli lub #define ident1(ident2, ident3, …, identk) ci ą g_symboli Forma krótka: • nakazuje preprocesorowi zastąpienie dalszych wystąpień identyfikatora przez ci ą g_symboli • nie penetruje wnętrza stringów (stałych tekstowych) Przykład: #define CZTERY 4 extern void funkcja(int k); main() { float tablica[CZTERY]; int i; i=CZTERY + 2*CZTERY; funkcja(CZTERY-1); printf(”Mowilem Ci to CZTERY razy !!!\n”); } • Dyrektywy #define mogą wykorzystywać wcześniej wykonane definicje Przykład: #define DLUGOSC 20 #define SZEROKOSC 15 #define POLE (DLUGOSC*SZEROKOSC) • dyrektywa #define słuŜy nie tylko definicji stałych, np.: #define forever for( ; ; ) forever { … break; … } • długie dyrektywy – gdy ci ą g_znaków jest długi, to moŜemy wpisać kończąc linię znakiem ‘\’, po którym następuje ‘\n’ i kontynuując w następnej linijce: Przykład: #define ADRES ”Politechnika Krakowska\n\ im. Tadeusza Kosciuszki\nul. Warszawska 24\n\ 31-155 Krakow\n” cout << ADRES; • definiowanie stałych o poprzez dyrektywę #define o poprzez kwalifikator const Przykład: #define PI 3.1415926 const double PI=3.1415926; RóŜnice: gdy uŜyjemy #define to identyfikator nie jest znany kompilatorowi; gdy const – jest. To daje większą szansę wykrycia błędów składniowych przez kompilator. Forma długa: • słuŜy do definiowania makr z argumentami (zastępowany tekst moŜe być róŜny dla róŜnych makrowywołań) • pomiedzy ident1 a prawym nawiasem nie moŜe być spacji Przykład: #define KWADRAT(a) ((a) * (a)) • Działanie: KWADRAT(parametr) ë ((parametr)*(parametr)) np. KWADRAT(x+0.5) ë ((x+0.5)*(x+0.5)) a=KWADRAT(c)+KWADRAT(a+1) ë a=((c)*(c))+((a+1)*(a+1)) • Zalety – brak zaleŜności od typu (gdybyśmy zdefiniowali makro jako funkcję, to musielibyśmy zdefiniować wiele wariantów dla roŜnych typów • Pułapki o moŜliwe efekty uboczne: KWARDAT(n++) ë dwukrotna inkrementacja o uwaga na nawiasy gdy określimy: #define KWADR(a) a*a to KWADR(n+1) ë n+1*n +1 = 2*n +1 naleŜy definiować jako ((a)*(a)) Odwołanie definicji – dyrektywa #undef • dyrektywa #define obowiązuje od momentu wystąpienia do końca pliku • jeŜeli zamieścimy dyrektywę #undef wyraz to od tej chwili definicja dokonana przez dyrektywę #define wyraz ..... przestaje obowiązywać Dyrektywy kompilacji warunkowej • stosowane w sytuacjach, gdy chcemy pewne fragmenty kodu włączyć selektywnie do kompilacji Przykład: x=i*c + szereg(x0); printf(”x = %f\n”,x); /* wydruk pomocniczy */ m=funkcja(x); Po uruchomieniu wydruk pomocniczy niepotrzebny; moŜemy: • fizycznie usunąć – pracochłonne; być moŜe znów będzie potrzebny • zakomentować – j.w., ryzyko zagnieŜdŜenia komentarza (gdy usuwamy kilka linii zawierających juŜ komentarze) • zastosować kompilację warunkową – najlepsze rozwiązanie [ Pobierz całość w formacie PDF ] |