Učíme se C (16.díl) - Modifikátory paměťové třídy - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

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.

int        i=10; 
auto int   j; 

void fce()
{ auto int i;
  int k;

  i=20;
}

int main()
{ 
  fce();
  printf("%d", i);
  return 0;
}

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:

int fce()
{ static int i=0;
  return ++i;
}

int main()
{ int j;
  for (j=0; j<10; j++) printf("%d  ", fce());
  return 0;
}

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:

int *p;

void fce()
{ static int i=50;
  p=&i;
  printf("%d\n",i);
}

int main()
{
  fce();
  *p=30;
  fce();
  return 0;
}

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.

register int  i;
register char c;

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.

volatile int i;

i=0;
while (i==0) ;
//smyčku ukončí až vnější událost, která
//změní hodnotu i

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.

const int i=20;
int *p=&i;

i=30;   //chyba, nelze provést
printf("%d\n", i);
*p=40;  //nepřímá změna hodnoty konstantní proměnné
printf("%d\n", i);

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » C/C++  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: