Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
Učíme se C (7.díl)
9. října 2000, 00.00 | Pokračování minule načatého tématu - Preprocesor jazyka C. Tentokrát
o parametrických makrech.
Preprocesor jazyka C - pokračování
Minule jsme začali s výkladem preprocesoru. Řekli jsme si, mimo jiné, i o direktivě #define, pomocí které je možné substituovat text ve zdrojovém souboru. Tato problematika je však ještě složitější, protože kromě jednoduchých maker, o kterých byla řeč minule, existují i makra parametrická, která dovádějí textovou substituci ještě o něco dál.
Makra s parametry
V zásadě jde o to, že samotný text, kterým preprocesor nahrazuje výskyt makra, může být různý v závislosti na parametrech makra. Parametrická makra se definují takto:
#define identifikátor_makra(seznam formálních parametrů) text_makra
Jak vidíte, oproti obyčejným makrům, je přidán seznam formálních parametrů. Ten musí být uveden v kulatých závorkách, přičemž levá závorka musí bezprostředně následovat za identifikátorem makra. V opačném případě nebude makro považováno za parametrické a seznam parametrů bude náležet přímo textu makra. Aby mělo použití parametrického makra smysl, měly by být někde v textu makra formální parametry použity.
Když už máme makro nadefinované, můžeme ho začít používat. Volání parametrického makra vypadá takto:
identifikátor_makra(seznam skutečných parametrů)
A jak to vlastně funguje si ukážeme na příkladu. Nejprve si nadefinujeme vlastní makro implementující druhou mocninu:
#define SQR(x) x*x
A pak někde v programu toto makro zavoláme:
SQR(3)
Preprocesor pak toto volání makra nahradí textem, který získá poměrně jednoduchým postupem. Nejdříve je celé volání nahrazeno textem makra a vzápětí jsou všechny výskyty formálních parametrů makra v tomto textu nahrazeny skutečnými parametry, získanými při volání makra. V našem případě to znamená, že nejprve je celé volání makra nahrazeno zápisem x*x, což je text makra, a následně jsou všechny výskyty znaku x nahrazeny znakem 3, který je skutečným parametrem. Konečným výsledkem nahrazení makra je zápis 3*3.
Co ale v případě, že je makro voláno třeba s parametrem a+1?
SQR(a+1)
Po zpracování preprocesorem bychom získali zápis a+1*a+1, což se značně liší od předpokládaného výsledku. Řešením je uzavřít každý výskyt formálního parametru v textu makra do závorek:
#define SQR(x) (x)*(x)
Makro se pak rozvine do očekávaného tvaru (a+1)*(a+1). Ani pak ale není takto nadefinované makro zcela univerzální. Představme si toto volání makra:
!SQR(a+1)
To se rozvine do zápisu !(a+1)*(a+1), což opět nedává očekávaný výsledek. Zcela správná definice makra by musela vypadat takhle:
#define SQR(x) ((x)*(x))
Rozvinutí !SQR(a+1) pak bude konečně ve správném tvaru !((a+1)*(a+1)).
Dobrou zásadou při vytváření parametrických maker tedy je uzavírat všechny výskyty formálních parametrů v textu makra do závorek a stejně tak i celý text makra.
Použití
No a nakonec si řekneme něco o použití parametrických maker. Jak bylo z předcházejících řádků patrné, parametrická makra mohou nahradit některé funkce. Ve skutečnosti i některé knihovní funkce jsou vlastně jen makry. Výhodou oproti klasickým funkcím je to, že odpadají všechny instrukce, které je potřeba zavolat při předávání řízení funkci. V případě, že voláme např. v cyklu nějakou jednoduchou funkci, můžeme ji často nahradit makrem, a tak zrychlit běh programu. Další výhodou použití parametrických maker je jejich typová nezávislost. Např. výše nadefinované makro SQR můžeme se stejným úspěchem použít s argumenty reálnými i celočíselnými.
Obsah seriálu (více o seriálu):
- Učíme se C (1. díl)
- Učíme se C (2. díl)
- Učíme se C (3.díl)
- Učíme se C (4. díl)
- Učíme se C (5.díl)
- Učíme se C (6.díl)
- Učíme se C (7.díl)
- Učíme se C (8.díl)
- Učíme se C (9.díl) - Řetězce
- Učíme se C (10.díl) - Vstupně výstupní funkce
- Učíme se C (11.díl) - Formátovaný výstup
- Učíme se C (12.díl) - Formátový specifikátor
- Učíme se C (13.díl)
- Učíme se C (14.díl) - Vícerozměrná pole
- Učíme se C (15.díl) - Ukazatele
- Učíme se C (16.díl) - Modifikátory paměťové třídy
- Učíme se C (17.díl) - Pole a ukazatel
- Učíme se C (18. díl) - Dynamická alokace paměti
- Učíme se C (19. díl) - Práce se soubory I.
- Učíme se C (20. díl) - Práce se soubory II.
- Učíme se C (21. díl) - Parametry funkce main()
- Učíme se C (22. díl) - Ukazatele na funkce
- Učíme se C (23. díl) - Složité deklarace a definice
- Učíme se C (24. díl) - Funkce s proměnným počtem parametrů
- Učíme se C (25. díl) - Bitové operátory a bitové pole
- Učíme se C (26. díl) - Datové typy enum a union
- Učíme se C (27. díl - závěr) - Programové moduly
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007