include
Transkrypt
include
Katedra Elektrotechniki Teoretycznej i Informatyki wykład 12 - sem.III M. Czyżak Język C - preprocesor Dyrektywy preprocesora Preprocesor C i C++ (cpp) jest programem, który przetwarza tekst programu przed przekazaniem go kompilatorowi. Można sterować zachowaniem preprocesora stosując odpowiednie polecenia zwane dyrektywami preprocesora. Język C - preprocesor Dyrektywy preprocesora #include … - dyrektywa włączająca tekst innego pliku źródłowego w miejscu jej wystąpienia w pliku podlegającym aktualnie przetwarzaniu #if … - dyrektywa kompilacji warunkowej #elif … - działa podobnie jak else if w języku C #endif … - oznacza koniec bloku kompilacji warunkowej #define - definiuje stałe i makroinstrukcje (pseudofunkcje) #undef - usuwa definicje stałej lub makra #ifdef … - znaczy to samo co #if defined(…) #ifndef - znaczy to samo co #if !defined(…) #error … - generuje błąd wraz z opisem Język C - preprocesor Dyrektywy kompilacji warunkowej #if, #else, #elif i #endif #if wyrażenie1 sekwencja instrukcji 1 #elif wyrażenie2 sekwencja instrukcji 2 #elif wyrażenie3 sekwencja instrukcji 3 ................. #elif wyrażenieN sekwencja instrukcji N #endif W standardzie ANSI C dyrektywy #if i #elif można zagnieżdżać do co najmniej 8 poziomów, a w C99 do co najmniej 63. Język C - preprocesor Przykład. Użycie dyrektyw #if, #else, #elif i #endif #define POLSKA 0 #define FRANCJA #define USA 1 3 #define AKTYWNY_KRAJ USA #if AKTYWNY_KRAJ==USA char waluta[ ]="dolar"; #elif AKTYWNY_KRAJ==FRANCJA char waluta[ ]="euro"; #else AKTYWNY_KRAJ==POLSKA char waluta[ ]="zloty"; #endif Język C - preprocesor Dyrektywy kompilacji warunkowej #define i #undef Dyrektywy #define i #undef Dyrektywa #define definiuje makro, a dyrektywa usuwa poprzednio zdefiniowaną nazwę makra. Dyrektywy #define ma postać #define makro, a dyrektywa #undef ma postać #undef makro. #define N 5 #define M 5 double tab[N][M] #undef N #undef M // Od tego miejsca N i M nie są zdefiniowane Język C - preprocesor Dyrektywy preprocesora Dyrektywy #ifdef i #ifndef (cz.1) Dyrektywy te oznaczają odpowiednio " jeśli zdefiniowano" i " jeśli nie zdefiniowano". Ogólna postać dyrektywy #ifdef to #ifdef nazwa_makra sekwencja instrukcji #endif Jeśli nazwa_makra została wcześniej zdefiniowana, wówczas kompilowany jest kod określony jako sekwencja instrukcji. Język C - preprocesor Dyrektywy preprocesora Dyrektywy #ifdef i #ifndef (cz.2) Ogólna postać dyrektywy #ifndef (oznacza - jeśli nie zdefiniowano) ma formę nastepujacą: #ifndef nazwa_makra sekwencja instrukcji #endif Jeśli nazwa_makra została nie została wcześniej zdefiniowana przy użyciu dyrektywy #define, wówczas kompilowany jest kod określony jako sekwencja instrukcji. Język C - preprocesor Dyrektywy preprocesora Dyrektywy #ifdef i #ifndef (cz.3) #include <stdio.h> #define STUDENT 1 int main() { #ifdef STUDENT printf(" Witaj\n"); #else printf("Witajcie"); #endif #ifndef STUDENT printf("\n STUDENT nie zostal zdefiniowany"); return 0;} Język C - preprocesor Dyrektywy preprocesora Operator defined Operator ten umożliwia sprawdzenie czy istnieje definicja danej nazwy makra. Ogólna postać stosowania tego operatora to: defined nazwa_makra Jeśli nazwa_makra została zdefiniowana, wyrażenie to ma wartość logiczną prawda, jeżeli nie to ma wartość fałsz. Operator ten można użyć następująco: #if defined FINAL printf("Wersja finalna\n"); Do operatora defined można też stosować operator negacji ! , wtedy wyrażenie z operatorem defined ma postać !defined. Język C - preprocesor Dyrektywy preprocesora Dyrektywa #line (cz.1) Dyrektywa #line zmienia zawartość stałych __LINE__ oraz __FILE__ będących predefiniowanymi identyfikatorami kompilatora. Stała __LINE__ zawiera numer aktualnie kompilowanego wiersza kodu. Stała __FILE__ zawiera nazwę aktualnie kompilowanego pliku źródłowego. Dyrektywa jest stosowana w następującej postaci #line numer "nazwa pliku", gdzie numer to dowolna dodatnia liczba całkowita, a nazwa pliku to dowolna poprawna nazwa pliku. numer staje się nową wartością __LINE__ a nazwa pliku staje się nową wartością __FILE__. Język C – preprocesor Dyrektywy preprocesora Przykład. Zastosowanie #line, __LINE__ i __FILE__.(cz.1) #include <stdio.h> #include <conio.h> int main(int argc, char* argv[]) { printf("Linia programu:%d\n", __LINE__); printf("Nazwa pliku :%s\n", __FILE__); #line 30 "Plik1" printf("Linia programu:%d\n", __LINE__); printf("Nazwa pliku :%s\n", __FILE__); getch(); return 0; } Język C – preprocesor Dyrektywy preprocesora Przykład. Zastosowanie #line, __LINE__ i __FILE__.(cz.2) Wynik działania programu Linia programu:5 Nazwa pliku :C:\Documents and Settings\Administrator\My Documents\Unit1_01122010.cpp Linia programu:30 Nazwa pliku :Plik1 Język C – preprocesor Dyrektywy preprocesora Dyrektywa #pragma Dyrektywa o postaci #pragma nazwa_dyrektywy pozwala przekazywać kompilatorowi różnego rodzaju polecenia. W języku C99 dodano operator _Pragma umożliwiający umieszczenie pragmy w inny sposób _Pragma("dyrektywa") Przy użyciu pragmy można wprowadzić polecenia dla konkretnego kompilatora, jeżeli dany kompilator nie pragmy umieszczonej w tekście programu to ją pomija. Język C – preprocesor Dyrektywy preprocesora Przykład. Wybrane dyrektywy #pragma dla kompilatora Borland Builder C++.( cz.1). #pragma argsused Pragma ta jest dozwolona tylko między definicjami funkcji i wpływa na następną definicję funkcji. Wyłącza ona komunikat: "Parameter name is never used in function func-name" #pragma hdrstop Dyrektywa ta kończy listę plików nagłówkowych, które mogą być prekompilowane. Pozwala to zredukować miejsce na dysku używane przez prekompilowane nagłówki. Język C – preprocesor Dyrektywy preprocesora Przykład. Wybrane dyrektywy #pragma dla kompilatora Borland Builder C++ . ( cz.2). #pragma startup function-name <priority> #pragma exit function-name <priority> Pragma startup określa funkcję, która jest wywoływana jako pierwsza przed main(), a pragma exit, funkcję która jest wywoływana przed zakończeniem programu przez funkcję _exit(). <priority> może być liczbą z przedziału <64,256>. Funkcje o wyższym priorytecie są wywoływane jako pierwsze przy starcie i jako ostatnie przy wyjściu. Funkcja ta musi być wcześniej zdefiniowana i mieć nagłówek o postaci void fun (void); Język C – preprocesor Dyrektywy preprocesora Przykład. Proste zastosowanie #pragma startup #include <stdio.h> #include <conio.h> void fun(void) { printf("Wywolanie funkcji fun\n"); } #pragma startup fun 100 int main(int argc, char* argv[]) { printf(" Funkcja main()"); getch(); return 0; } Wynik działania programu Wywolanie funkcji fun Funkcja main() Język C – preprocesor Operatory preprocesora Operator # Operator ten nazywany jest operatorem tworzenia łańcuchów. Przekształca on poprzedzany argument na tablicę znakową. Przykład. Przekształcenie programu przy użyciu operatora #. Program realizowany #include <stdio.h> #include <stdio.h> #define UtworzLan(s) #s #define UtworzLan(s) #s int main(){ int main(){ printf(UtworzLan(Lubie C)); printf("Lubie C"); return 0; } return 0; } Język C – preprocesor Operatory preprocesora Operator ## Operator ten to operator sklejania łańcuchów. Przykład. Przekształcenie programu przy użyciu operatora ##. #include <stdio.h> #include <stdio.h> #define PolaczLan(a,b) a##b #define PolaczLan(s) a##b int main(){ int main(){ int xy=10; int xy=10; printf("%d",PolaczLan(x,y)); printf("%d",xy); return 0; } return 0; } Język C – preprocesor Komentarze W języku ANSI C występuje jeden rodzaj komentarza. Jest to komentarz wielowierszowy rozpoczynający się parą znaków /* i kończący parą */. Kompilator pomija cały tekst znajdujący się między tymi parami znaków. Komentarze takie nie mogą być zagnieżdżane( nie można umieszczać jednego komentarza wewnątrz drugiego). Komentarze takie mogą być umieszczane w programie prawie w każdym miejscu, z wyjątkiem wnętrza słowa kluczowego i identyfikatora. Przykład. /* to jest komentarz poprawny */ swi /* komentarz niepoprawny */tch (ch) { case 1:printf("war1"); break; case 2:printf("war2"); } Język C – preprocesor Komentarze W standardzie C99 istnieje dodatkowo komentarz jednowierszowy w stylu C++ rozpoczynający się parą znaków // i rozciągający się do końca wiersza. Komentarz taki może być umieszczany wewnątrz komentarza wielowierszowego. Przykład. a) // komentarz jednowierszowy b) /* // komentarz zagnieżdżony jednowierszowy .................................. */ Język C Predefiniowane makra W języku ANSI C istnieje pięć predefiniowanych nazw makr: __LINE__, __FILE__, __DATE__, __TIME__, __STDC__. Makra __LINE__ i Makro __DATE__ __FILE__ zostały przedstawione poniżej. zawiera łańcuch w postaci miesiąc/dzień/rok reprezentujący datę translacji pliku źródłowego na plik obiektowy. Makro __TIME__ zawiera godzinę kompilacji programu w postaci godzina:minuta:sekunda . Makro __STDC__ zawiera informację o zgodności kompilatora ze standardem C, jeśli jest równe 1, to kompilator jest zgodny ze standardem.