1 / 21

1 1. Preprocesiranje i stndardni ulaz/izlaz

1 1. Preprocesiranje i stndardni ulaz/izlaz. 11.1. Preprocesiranje. C-program se sastoji iz jedinaica za prevođenje (kompilacionih jedinica). Jedinica za prevođenje se sastoji iz izvorene datoteke i uključenih datoteka. Izvorna datoteka sadrži preprocesorske direktive i C-naredbe.

delano
Download Presentation

1 1. Preprocesiranje i stndardni ulaz/izlaz

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 11. Preprocesiranje i stndardni ulaz/izlaz 11.1. Preprocesiranje • C-program se sastoji iz jedinaica za prevođenje (kompilacionih jedinica). Jedinica za prevođenje se sastoji iz izvorene datoteke i uključenih datoteka. • Izvorna datoteka sadrži preprocesorske direktive i C-naredbe. • U procesu prevođenja, kompilaciona jedinica se najpre podvrgava preprocesoru. • Preprocesor priprema izvorni kod i prosleđuje ga prevodiocu. • U toku rada, preprocesor prolazi kroz 4 faze, a rezultat njegovog rada je izmenjen izvorni program tako da su: • izbačeni komentari • preprocesorske direktive su zamenjene rezultatom • njihovog izvršavanja

  2. Preprocesor obavlja sledeće: 1. Iz izvorne datoteke učitavaju se program znak po znak po potrebi neki znaci se prevode u znakove iz skupa dozvoljenih izvornih. 2.Ako se iza znaka za novi red nalazi obrnuta kosa crta, preprocesor briše oba znaka. 3. Izvorna datoteka razlaže se na preprocesorske tokene i na sekvence blanko-simbola (razmaka). Svaki komentar zamenjuje se jednim razmakom. 4. Izvršavaju se preprocesorske direktiva i realizuju pozivi makroa. Sve opisane radnje realizuju se i nad datotekama koje su umetnute pomoću direktive #include.

  3. U preprocesorske direktive spadaju direktive za: umetanje sadržaja drugih izvornih datoteka prepoznavanje delova koda koji se prevode samo pod određenim uslovima i definisanje makroa – identifikatora koje preprocesor zamenjuje drugim tekstom. Preprocesorska direktiva počinju znakom # i u redu se, osim nje, ne može naći ništa više. Završava se prvim znakom za novi red (posle njenog početka), Najkraća je prazna direktiva (koja je bez dejstva) i sastoji se samo iz zbaka #. Dozvoljeni su komentar i razmaci. Ako direktiva ne može da se smesti u jedan red, na kraj prvog reda stavlja se \ (obrnuta kosa crta) i prenosi se u sledeći red.

  4. Primer: #define ImeMakroa Pera,\ Ovo je Perin makro Obrnuta kosa crta mora biti poslednji znak pre znaka za novi red. Razmaci i tabulatori mogu se naći između znaka # i imena direktive. ( U prethodnom primeru ime direktive je define.) Rezultat rada preprocesora može se videti ako se on pokrene kao poseban program, tj. ako se može pokrenuti prevodiloac tako da se izvrše samo preprocesorske direktive. Nadlje ćemo razmotriti direktive uključenja datoteka makroe direktive uslovnog prevođenja

  5. 11.1.1. Direktiva umetanja (#include) Dirrektivom umetanja preprocesor umesto nje umeće sadržaj određene datoteke. Postoje 2 načina da se navede datoteka koja se umeće: #include <imedatoteke> #include “imedatoteke” U prvom slučaju uključuje se zaglavlje neke datoteke iz standardne biblioteke ili iz date implementacije. Na primer: #include <math.h> Pomoću drugog oblika mogu se umetnuti izvorne datoteke specifične za naš program. Na primer: #include “mojaDat.h” U direktivi #include mogu se koristiti makroi (o kojima će biti rečikasnije)

  6. Mesto na kojem se traže datoteke iz direktive #include, zavisi od konkretne implementacije jezika C. (Datoteke između uglastih zagrada obično traži u sistemskim folderima, a datoteke između navodnika, obično u tekućem folderu.) Ovde ime datoteke može sadržati i putanju do datoteke. Direktive #include mogu biti ugnježdene, tj. datoteka umetnuta pomoću direktive #include, može i sama sdržati direktive #include. Preprocesor dozvoljava najviše 15 nivoa gnježđenja. Prilikom gnjezdastog umetanja može se desiti da se neka datoteka 2 puta umetne (datoteka stdio.h je skoro svuda prisutna). Neka u datoteci “mojaOmiljena.h” postoji red: #include <stdio.h>. Ako u izvornu datoteku uključimo direktive: #include <stdio.h> #include “mojaOmiljena.h” tada bi stdio.h bila umetnuta 2 puta. Ovo se može sprečiti korišćenjem direktiva uslovnog prevođenja o kojim će još biti reči.

  7. 11.1.2. Makro-direktive (makroi) Makro se definiiše pomoću direktive #define. Ovom direktivom se dodeljuje ime proizvoljnom tekstu. Preprocesor ime makroa, gde god se pojavi u izvornom kodu posle definisanja, zameniti tim tekstom. Najčešće se koristi za definisanje konstanti. Na primer: #define MAX 100 Po konvenciji, ime makroa piše se velikim slovima da bi se razlikovalo od imena običnih promenljivih. U makrou se ne može definisati preprocesorska direktiva koja će potom biti realizovana (čak iako je korektno definisana). Makro može biti definisan bez parametra ili sa parametraima.

  8. 11.1.2.1 Makroi bez parametara Imaju opšti oblik: #define ime_makroa tekst_zamena Ovede tekst_zamena može biti i prazan. Primer: #define NASLOV “– Glavni sadrzaj –” #define VELICIN_BAF (4*512) Ako u programu postoje naredbe: puts (NASLOV). static char mojBafer[VELICINA_BAF]; onda bi , nakon rada preprocesora, bile izvršene zamene: put (“– Glavni sadrzaj –”); static char mojBafer[(4*512)];

  9. 11.1.2.2. Makroi sa parametrima Makroi sa parametrima liče na funkcije. Definišu se na 2 načina: #define ime_makroa( [lista_parametra] ) tekst_zamena #define ime_makroa( [lista_parametra,] …) tekst_zamena Lista_parametra je lista identfikatora razdvojenih zapetama. Tri tačke označavaju jedna ili više dodatnih argumenata. Ne sme se pojavljivati razmak između imena makroa i leve male zagrade. Prilikom zamene imena makroa tekstom, preprocesor umeće i odgovarajuće argumente koji zamenjuju parametre. Ako imamo #define DIST(x,y) ((x)>=(y) ? (x)-(y) : (y) – (x)) d= DIST (a, b+1.6); biće izvršena sledeća zamena: d= ((a)>=(b+1.6) ? (a)-(b+1.6) : (b+1.6) –(a));

  10. Prema standardu C99 u definiciji makroa mogu se koristiti i tri tačke (...). Takav makro se poziva sa promenljivim brojem argumenata. • Unarni operator # (često de naziva i operator konverzije u znakovni niz), služi za konvertovanje argumenta makroa u znakovni niz. Na primer, ako imamo: • #define stampaj( par ) printf(#par “ = %f “, par) • stampaj(4*sin(1.0)); • poziv makro iz poslednjeg reda svodi se na: • printf(“4*sin(1.0)” “= %f “, 4*sin(1.0)); • Kako prevodilac spaja susedne linije znkovnih nizova, bilo bi: • printf(“4*sin(1.0) = %f “, 4*sin(1.0)); • Makroi se mogu ubacivati unutar drugih makroa, može se koristiti poseban opertor ## za ubacivanje tokena (time se nećemo baviti!) • makro1.cpp

  11. 11.1.3. Direktiva uslovnog prevođenja Pomoću ove direktive može se, pod određenim uslovima, zadržati ili zameniti deo izvornog koda. Na taj način program se može prilagoditi raznim sistemima bez posebnog menjanja izvorne datoteke. Deo programa koji se uslovno prevodi počinje jednom od direktiva #if, #ifdef ili #ifndef, a završava se direktivom #endif. U njemu se može javiti proizvoljno mnogo direktiva #elif, a najviše jedna direktiva #else. U ovim direktivama mogu se javiti uslovi koji su celobrojni preprocesorski izrazi. Oni su slični običnim celobrojnim C-izrazima (pojavljuju se razlike u korišćenju direktiva) i mogu sadržati operator defined (o kojem će biti reči).

  12. Direktiva #if ima sledeći opšti oblik: #if izraz1 [grupa1] [#elif izraz2 [grupa2 ]] … [#elif izraz(n) [grupa(n) ]] [#else [grupa(n+1)]] #endif Preprocesor računa vrednosti izraza sve dok ne naiđe na vrednost različite od nule (true) i tekst u odgovarajućoj grupi zadržava za dalu obradu. Ako nijedan nije true, a postoji #else, zadržava se tekst u grupi iza #else. Grupe sadrže C-naredbe, a mogu sadržati i direktive.

  13. 11.1.3.1. Operator defined U uslovnoj direktivi #if ili #elif može se naći unarni operator defined, koji ima jedan od sledećih oblika: defined identifikator defined (identifikator) Preprocesorski izraz ima vrednost 1 ako je navedeni identifikator ime makroa, tj. ako je definisan pomoću direktive #define, a njegova definicija nije poništena pomoću direktive #undef. u suprotno, izraz sa operatorom defined je 0. makro21.cpp makro22.cpp

  14. 11.1.3.2. Direktive #ifdef , #ifndef i #error Ove direktive služe, takođe, za proveru da li je neki makro definisan. Imaju sledeću sintaksu: #ifdef identifikator #ifndef identifikator. One se jednostavno opisuju preko defined operatora: #if defined identifikator #if !defined identifikator. Direktiva #error nalaže procesoru da ispiše poruku o grešci, bez obzira d ali greška formalno postoji. Ima sintaksu: #error [tekst] Ako postoji opcioni tekst, on će se pojaviti u poruci o grešci. makro31.cpp makro32.cpp

  15. 11.1.4. Unapred definisani makroi Svaki prevodilac koji podržava ISO C mora da definiše 7 sledećih makroa (njihova imena počinju i završavaju se dvema crtama za podvlačenje): _ _ DATE _ _ tekst makroa je literal znakovnog niza koji sadrži datum prevođenja u formatu “Mes dd gggg”, npr. “Mar 23 2007” _ _ FILE_ _ literal znakovnog tipa koji sadrži ime tekuće izvorne datoteke. _ _ LINE _ _ celobrojna konstanta čija vrednost je broj reda u tekućoj izvornoj datoteci u kojem se poziva makro _ _ LINE_ _. _ _ TIME_ _ literal zakovnog niza koji sadrži vreme prevođenja u formatu “hh:mm:ss” _ _ STDC_ _ Celobrojna konstanta je 1 ako je podržan standar ISO C. _ _STDC_HOSTED_ _ celobrojna koja ima vrednost 1 ako izvršavanje tekućeg programa zavisi od operativnog sistema, inače je 0. _ _STDC_VERSION_ _ konstantta 199901 tipa long, ako je podržan C99

  16. 11.2. Standardni ulaz/izlaz • Stabdardne funkcije ulaza/izlaza smeštene su u standardne biblioteke od kojih se najviše koristi <stdio,h>. • Za učitavanje jednog znaka koristi se finkcija: • int getchar(void) • Za štampanje jednog znaka koristi se funkcija: • int putchar(int) • 3.Za štampanje koristi se funkcija: • int printf(char *format [, arg1, arg2, ...]) • koja prevodi interne vrednosti (zapisane u računaru) u znakovne. • Može se opisati i ovako: • int printf(<format-string> [,arg1, arg2, …])

  17. Funkcija printf konvertuje, formatira i štampa svoje argumente na standardni izlaz pod kontrolom format-stringa i vraća broj odštampanih znakova. Format-string sadrži 2 tipa znakova: znaci koji se kopiraju na izlaz i specifikaciju konverzije, koja vrši konverziju i štampa argumente Svaka specifikacija konverzije počinje znakom % i završava se znakom konverzije. Između % i znaka konverzije može postojati: znak – određuje levo poravnanje argumenata broj – određuje minimalnu širinu polja (ako treba, proširuje se!) tačka (.) – razdvaja širinu polja od tačnosti tačnost – određuje broj cifara iza dec. tačke ili maksimalan broj c ifara niske. h, l ili L – određujue short i long brojeve

  18. Znaci konverzije mogu biti: d,i int decimalni, celobrojni n int *x pokazivački o int neoznačen oktalni celobrojni x, X int neoznačen heksadekadni (x~a,b,..., X~A,B, ...) u int neoznačeni celobrojni c char znakovni celobrojni s string niska-tip f float, double razlomljeni([zn]m.dd…d) e, E float double razlomljeni ([zn]m.dd…dExx) g, G float double razlomljeni kraći zapis od %f i %e p void *x (void * ) x % ništa štampa %

  19. Funkcija • int sprintf(char *string, char *format [, arg1, arg2, ...]) • ima isti efekat kao i finkcija printf, ali štampanje vrši u string umesto na standardni izlaz. • 5. Funkcija • int scanf(char *format [,arg1, arg2, ...]) • ili • int scanf(<format-string> [, arg1, arg2, …]) • vrši konveryiju u suprotnom smeru u odnosu na printf. Argumenti su pokazivači i pokazuju gde se memoriše konvertovani podaci. Vraća se broj uspešno dodeljenih ulaznih podataka.

  20. Konverzioni string, u ovom slučaju, sadrži: beline – koje se zanemaruju obične znake (izuzev %) koji se moraju podudarati sa odgovarajućim znakom na ulazu specifikaciju konverzije koja se satoji od %, opcionog znaka *za ukidanje dodeljivanja, opcionog broja – širine polja, opcionog h, l ili L i znaka konverzije. 6. Funkcija int sscanf(char *string, char *format [, arg1, arg2, ...]) ili int sscanf(<string>, <format-string> [, arg1, arg2, ...]) se primenjuje isto kao i scanf, jedino što vrši učitavanje iz navedenog stringa umesto sa standardnog ulaza.

  21. Konvezioni znaci: c pokazivač na char d int f float, double e, E float. double g, G float, double i int n int o int oktalni s string u neoznačen ceo dekadni, x neoznačen ceo hesadekadni […] char x[] % bez dejstva

More Related