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 (16.díl) - Modifikátory paměťové třídy
16. ledna 2001, 00.00 | Typové modifikátory ovlivňující paměťovou třídu a optimalizaci a
modifikátor const.
Modifikátory paměťové třídy
Kromě identifikátoru a datového typu jsou proměnné určeny ještě paměťovou třídou, které náleží. Paměťová třída určuje kde bude proměnná v paměti uložena, jakou bude mít viditelnost a jakou životnost.
Modifikátor auto
Modifikátor paměťové třídy auto je implicitně používán pro všechny lokální proměnné (definované na začátku bloku), jejichž paměťová třída nebyla určena jiným modifikátorem. Těmto proměnným se také často říká automatické, protože paměť se pro ně alokuje automaticky až při vstupu do bloku, ve kterém jsou definovány. Po opuštění bloku je tato paměť zase uvolněna. V případě návratu do stejného bloku je místo pro proměnnou alokováno znovu, neexistuje ale žádná záruka, že to bude stejné místo jako při poslední alokaci. Stejně tak neexistuje vůbec žádná záruka, že hodnota proměnné zůstane zachována. Automatické proměnné nejsou nikdy implicitně inicializovány nulovou hodnotou. Inicializovat je musíme explicitně, například při definici proměnné. Výhodou je, že k této inicializaci není potřeba použít konstantní výraz, ale je možné inicializovat i hodnotami jiných proměnných, nebo návratovou hodnotou funkce. Automatická proměnná je viditelná jen v rámci bloku, ve kterém je definována. Existuje–li vedle této automatické proměnné i nějaká globální proměnná se stejným identifikátorem, je zastíněna automatickou proměnnou.
|
V uvedeném příkladu jsou definovány dvě proměnné i. První z nich je globální a druhá, definovaná uvnitř funkce fce(), je automatická lokální proměnná, která ,v oblasti své viditelnosti (uvnitř funkce), zastiňuje globální proměnnou i. Jak bude vidět z kontrolního výstupu funkce printf(), ve funkci fce() jsme skutečně pracovali s lokální proměnnou i. Definice proměnné j s modifikátorem auto vyvolá chybu, protože globální proměnné nemohou být automatické. Nevyužitá proměnná k ve funkci fce() je implicitně automatická i bez použití modifikátoru auto.
Modifikátor static
Chceme-li definovat lokální proměnnou paměťové třídy static, musíme při definici použít klíčové slovo static. Viditelnost statické lokální proměnné je shodná s viditelností automatických proměnných, tedy je viditelná jen v bloku, kde je definována. Životnost statické proměnné je ale po celou dobu vykonávání programu. Paměť pro takovou proměnnou je alokována při startu programu a uvolněna je až po jeho skončení. Z toho vyplývá, že, máme-li statickou proměnnou a opustíme blok, ve kterém byla definována, tato proměnná nezaniká, pouze již není viditelná. I tak ale lze s touto proměnnou pracovat např. pomocí ukazatele. Dojde-li k návratu do bloku s touto proměnnou, můžeme s ní znovu pracovat. Statické lokální proměnné se při definici dají inicializovat jen konstantním výrazem. Tato inicializace se ale provede jen při prvním vstupu do bloku, kde je proměnná definována. Není-li statická lokální proměnná inicializována explicitně, provede se implicitní inicializace nulovou hodnotou (opět jen při prvním vstupu do bloku).
Typickým ukázkovým příkladem na statické lokální proměnné je zjištění kolikrát byla nějaká funkce volána:
|
Proměnná i je při prvním zavolání funkce fce() inicializována nulovou hodnotou. Při dalším spuštění funkce se již inicializace neprovede a v proměnné i zůstává hodnota nastavená v předchozím volání funkce.
Následující program ukáže, jak změnit hodnotu statické lokální proměnné v oblasti mimo její viditelnost pomocí ukazatele:
|
Klíčové slovo static se používá i při definicích globálních proměnných, ale v tom případě je význam tohoto klíčového slova jiný. Slovo static by označovalo globální neexportovatelnou proměnnou (o kterých bude řeč v jiné části tohoto seriálu).
Modifikátor register
Modifikátor register patří mezi modifikátory ovlivňující optimalizaci kódu programu. Pro zvýšení efektivnosti je totiž možné uložit některé proměnné přímo do registrů procesoru, a tak umožnit rychlejší přístup k těmto proměnným. Je ale nutné říct, že klíčové slovo register slouží spíše jen jako doporučení kompilátoru, že proměnná se hodí k uložení do registru. Jestli se tak opravdu stane, není zaručeno, už třeba kvůli omezenému počtu registrů. Na registrové proměnné také nelze aplikovat operátor reference &, a to ať už proměnná skutečně je umístěna v registru, nebo není. Životnost a viditelnost registrových proměnných je stejná jako u proměnných automatických. Modifikátor register lze aplikovat pouze na lokální proměnné, a tedy nelze definovat globální proměnnou s modifikátorem register.
|
Modifikátor volatile
Druhým z modifikátorů, které ovlivňují optimalizaci, je modifikátor volatile. Pokud tímto klíčovým slovem označíme nějakou proměnnou, kompilátor ji nebude optimalizovat. Modifikátor volatile se používá především v případech, kdy hodnota proměnné může být měněna nějakým asynchronním procesem z vnějšku programu, např. pomocí přerušení. V takovém případě by mohl kompilátor dospět k chybným závěrům o funkci některých programových konstrukcí a nesprávně program optimalizovat.
|
Modifikátor const
Modifikátorem const vlastně neurčujeme paměťovou třídu, ale definujeme pomocí něho tzv. konstantní proměnné. Hodnoty takovýchto proměnných pak v programu nemůžeme přímo měnit (např. přiřazením). Jediným normálním způsobem, jak se dá hodnota konstantní proměnné nastavit, je inicializace při její definici. Pomocí ukazatelů však lze změnit hodnotu konstantní proměnné i z jiných míst programu.
Konstantní proměnné jsou jistou alternativou symbolických konstant preprocesoru. Na rozdíl od nich ale vždy zabírají místo v paměti. Jistou jejich nevýhodou je fakt, že konstantní proměnné v C (na rozdíl od C++) nemohou být součástí konstantních výrazů, a nelze je tedy použít např. pro inicializaci globálních proměnných, pro definování velikostí polí, apod. Modifikátor const lze použít i v kombinaci s jinými modifikátory.
|
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
Diskuse k článku
-
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