Programování v C jazyku seminář

Download Report

Transcript Programování v C jazyku seminář

PROGRAMOVÁNÍ
V C JAZYKU - SEMINÁŘ
Ing. Michal Heczko [email protected]
7 Preprocesor jazyka C
Programování v C jazyku – SEMINÁŘ
Ing. Michal Heczko [email protected]
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
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
Makra bez parametrů

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 /
Makra bez parametrů
#define PI 3.14
#define DVE_PI (2*PI)
#define MOD %
#define JMENO ″Michal″
#define ERROR {printf(″Chyba″);}
Makra bez parametrů

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
Makra bez parametrů

Ukončení platnosti makra – příkaz #undef

Příklad:
#define POCET 20
#undef POCET
#define POCET 30
Makra bez parametrů
#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;
}
Makra bez parametrů
#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;
}
Makra s parametry

Alternativa ke kratším funkcím

Nevýhoda použití funkce
 Při

Nevýhoda použití makra
 Při

použití funkce menší efektivita programu
použití makra vznikne delší (ale rychlejší) program
Na rozdíl od funkcí preprocesor nahradí jméno
makra v programu konkrétním textem
Makra s parametry

Obecná syntaxe:
#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′ &&
′A′):ch
(ch) <= ′Z′) ? Ch + (′a′-
Makra s parametry


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)
Volání:
mocnina(f + g)
Rozvinutí:
f + g * f + g
x * x
Správně:



Definice: #define
mocnina(x)
((x) * (x))
Volání:
mocnina(f + g)
Rozvinutí:
((f + g) * (f + g))
Předdefïnovaná makra


Jazyk C obsahuje nejen řadu předdefinovaných
funkcí, ale i makra.
Makra pro konverzi znaků:
 Definovány
 tolower
 toupper
 toascii
v souboru ctype.h
- konverze na malá písmena
- konverze na velká písmena
- převod na ascii (pouze posledních 7b)
Předdefïnovaná makra

Makra pro určení typu znaků:
 Definovány
 isdigit
 islower
 isupper
…
v souboru ctype.h
- testuje, zda daný znak je číslice
- testuje, zda je malé písmeno
- testuje, zda je velké písmeno
-…
Vkládání souborů


Příkaz include
obsah zdrojového souboru soubor bude vložen
do místa, kde byla volána direktiva include
Vkládání souborů

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í
Vkládání souborů

Příkaz #include <stdio.h>
 Hledá
soubor stdio.h v systémové složce.
 Použití pro standardní hlavičkové soubory.
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
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\
Oddělený překlad souborů
Vkládání souborů
S1.C
Oddělený překlad
S2.C
S3.C
S1.C
S2.C
S3.C
S1.OBJ
S2.OBJ
S3.OBJ
sestavení
link S1, S2, S3
S.C
#include ”S1.C”
#include ”S2.C”
#include ”S3.C”
S.OBJ
sestavení
link S
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
Podmíněný překlad

Testuje hodnotu logického výrazu
Syntaxe:
#if konstantní_výraz
část_1
#else
část_2
#endif

Podmíněný překlad

Příklad 1:
#define LADENI 1
#if LADENI
printf(″Hodnota: %d″,i);
#endif
Podmíněný překlad

Příklad 2:
#define WINDOWS 1
#if WINDOWS
#define CESTA ″C:\\program\\data″
#else
#define CESTA ″/program/data″
#endif
Podmíněný překlad

Testuje, zda je dané makro definováno
Syntaxe:
#ifdef konstantní_výraz
část_1
#else
část_2
#endif

Podmíněný překlad

Příklad:
#define WINDOWS 0
#ifdef WINDOWS
#define CESTA ″C:\\program\\data″
#else
#define CESTA ″/program/data″
#endif
Podmíněný překlad

Testuje, zda dané makro není definováno
Syntaxe:
#ifndef konstantní_výraz
část_1
#else
část_2
#endif

Podmíněný překlad

Příklad:
#ifndef DEFINICE
#define DEFINICE 1
#define PI 3.14
#define CESTA ″C:\\program\\data″
#endif
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)
#define
KONST_3
#endif
&& defined(KONST_2)
3
Podmíněný překlad

#elif


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í
Podmíněný překlad
#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
A1PCJ-s
07. Preprocesor
Děkuji za pozornost
Ing. Michal Heczko
[email protected]
218/U3
Prezentace k dispozici na http://vyuka.qsh.eu
Uživatelské jméno: student
Heslo: utb