Programování v C jazyku - SEMINÁŘ Ing. Michal Heczko heczko@fai.utb.cz
Preprocesor jazyka C 7 Programování v C jazyku – SEMINÁŘ Ing. Michal Heczko heczko@fai.utb.cz
Agenda Základní činnosti preprocesoru Makra bez parametrů (symbolické konstanty) Makra s parametry Vkládání souborů Oddělený překlad souborů Podmíněný překlad
Preprocesor jazyka C Zpracování programu
Základní činnost preprocesoru Zpracování zdrojového textu před použitím překladače Nekontroluje syntaktickou správnost programu Provádí pouze záměnu textu (např. identifikátorů konstant) za odpovídající číselné hodnoty (zpracování maker) Vypustí ze zdrojového textu všechny komentáře Připravuje podmíněný překlad Preprocesor
Makra bez parametrů Úvod Symbolické konstanty Příkaz #define Pravidla pro psaní konstant: Většinou se zapisují velkými písmeny Mezi jménem a hodnotou alespoň jedna mezera Za hodnotu je vhodné umístit komentář Nové konstanty mohou využívat již dříve definovaných konstant Pokud je konstanta delší než řádka, uvádíme na konci znak / Úvod
Makra bez parametrů Příklady #define PI 3.14 #define DVE_PI (2*PI) #define MOD % #define JMENO ″Michal″ #define ERROR {printf(″Chyba″);} Příklady
Makra bez parametrů Poznámky Poznámky: Za hodnotami není středník Mezi jménem konstanty a hodnotou se nepíše znak „=“ Konstanta platí od místa definice do konce souboru Poznámky
Makra bez parametrů Ukončení platnosti makra Ukončení platnosti makra – příkaz #undef Příklad: #define POCET 20 #undef POCET #define POCET 30 Ukončení platnosti makra
Makra bez parametrů Ukázka 1 #include <stdio.h> #define PI 3.14 int main() { double r = 6.5; double v = 2.1; printf(″Objem valce je %f!″,PI*r*r*v); return 0; } Ukázka 1
Makra bez parametrů Ukázka 2 #include <stdio.h> #define POSUN (′a′-′A′) #define KONEC_R ′\n′ int main() { int c; while ((c = getchar()) != KONEC_R) if (c >= ′a′ && c <= ′z′) putchar(c-POSUN); else putchar(c); } return 0; Ukázka 2
Makra s parametry Úvod Alternativa ke kratším funkcím Nevýhoda použití funkce Při použití funkce menší efektivita programu Nevýhoda použití makra Při použití makra vznikne delší (ale rychlejší) program Na rozdíl od funkcí preprocesor nahradí jméno makra v programu konkrétním textem Úvod
Makra s parametry Syntaxe Obecná syntaxe: Příklad použití: #define jmeno_makra(arg1,…,argN) hodnota_makra Příklad použití: #define je_velke(c) ((c) >= ′A′ && (c) <= ′Z′) ch = je_velke(ch) ? ch + (′a′- ′A′):ch Soubor se preprocesorem rozvine takto: ch = ((ch) >= ′A′ && (ch) <= ′Z′) ? Ch + (′a′- ′A′):ch Syntaxe
Makra s parametry Závorky Argument v definici makra je nutné uzavírat do závorek. V opačném případě velká šance vzniku chyb. Špatně: Definice: #define mocnina(x) x * x Volání: mocnina(f + g) Rozvinutí: f + g * f + g Správně: Definice: #define mocnina(x) ((x) * (x)) Rozvinutí: ((f + g) * (f + g)) Závorky
Předdefïnovaná makra Předdefinovaná makra Jazyk C obsahuje nejen řadu předdefinovaných funkcí, ale i makra. Makra pro konverzi znaků: Definovány v souboru ctype.h tolower - konverze na malá písmena toupper - konverze na velká písmena toascii - převod na ascii (pouze posledních 7b) Předdefinovaná makra
Předdefïnovaná makra Předdefinovaná makra Makra pro určení typu znaků: Definovány v souboru ctype.h isdigit - testuje, zda daný znak je číslice islower - testuje, zda je malé písmeno isupper - testuje, zda je velké písmeno … - … Předdefinovaná makra
Vkládání souborů Úvod Příkaz include obsah zdrojového souboru soubor bude vložen do místa, kde byla volána direktiva include Úvod
Vkládání souborů Tvary příkazu include Příkaz #include ″konstanty.h″ Hledá soubor konstanty.h ve složce, kde je uložen volající soubor. Pokud není nalezen, pokračuje se v hledání v dalších složkách dle aktuálního nastavení Tvary příkazu include
Vkládání souborů Tvary příkazu include Příkaz #include <stdio.h> Hledá soubor stdio.h v systémové složce. Použití pro standardní hlavičkové soubory. Tvary příkazu include
Vkládání souborů Standardní hlavičkové soubory: Obsahují definice funkcí, konstant a maker ze standardní knihovny Definovány ANSI normou Použití hlavičkových souborů v souladu s ANSI normou by mělo zajistit 100% přenositelnost mezi nejrůznějšími PC a OS Standardní hlavičkové soubory 1
Vkládání souborů Standardní hlavičkové soubory: Neobsahují celé konstrukce funkcí, ale pouze jejich hlavičky (tzv. funkční prototypy) – popisy jaké má funkce parametry a jaký datový typ vrací Většinou uloženy ve složce \include Např. v MS Visual C++ 2008 EXPRESS: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\ Standardní hlavičkové soubory 2
Oddělený překlad souborů Vkládání souborů Oddělený překlad Jak se liší od vkládání souborů?
Oddělený překlad souborů Každý soubor se překládá zvlášť – vzniká více .obj souborů Využití u větších projektů Při opakovaném překladu je přeložen pouze ten soubor, který byl změněn Oddělený překlad souborů
Podmíněný překlad Testuje hodnotu logického výrazu Syntaxe: #if konstantní_výraz část_1 #else část_2 #endif Řízení hodnotou konst. výrazu
Podmíněný překlad Příklad 1: #define LADENI 1 #if LADENI printf(″Hodnota: %d″,i); #endif Řízení hodnotou konst. výrazu
Podmíněný překlad Příklad 2: #define WINDOWS 1 #if WINDOWS #define CESTA ″C:\\program\\data″ #else #define CESTA ″/program/data″ #endif Řízení hodnotou konst. výrazu
Podmíněný překlad Testuje, zda je dané makro definováno Syntaxe: #ifdef konstantní_výraz část_1 #else část_2 #endif Řízení definicí makra
Podmíněný překlad Příklad: #define WINDOWS 0 #ifdef WINDOWS #define CESTA ″C:\\program\\data″ #else #define CESTA ″/program/data″ #endif Řízení definicí makra
Podmíněný překlad Testuje, zda dané makro není definováno Syntaxe: #ifndef konstantní_výraz část_1 #else část_2 #endif Řízení definicí makra 2
Podmíněný překlad Příklad: #ifndef DEFINICE #define DEFINICE 1 #define PI 3.14 #define CESTA ″C:\\program\\data″ #endif Řízení definicí makra 2
Podmíněný překlad Operátor defined Pokud chceme kontrolovat více definic zároveň – umožňuje spojování logickými operátory #if defined(KONST_1) && defined(KONST_2) #define KONST_3 3 #endif Operátor defined
Podmíněný překlad #elif #error Stejný význam jako u else-if v mnohonásobném větvení #error Výpis textu preprocesorem na standardní výstup chybových hlášení #elif a #error
Podmíněný překlad Příklad #if LADENI==1 printf("Provedla se 1.cast\n"); #elif LADENI==2 printf("Provedla se 2.cast\n"); #elif LADENI==3 printf("Provedla se 3.cast\n"); #else #error Neplatna hodnota konstanty LADENI! printf("Nebyla provedena zadna cast\n"); #endif Příklad
A1PCJ-s 07. Preprocesor Děkuji za pozornost Ing. Michal Heczko heczko@fai.utb.cz 218/U3 Prezentace k dispozici na http://vyuka.qsh.eu Uživatelské jméno: student Heslo: utb