Proměnné, konstanty a ukazatele

Přehled informací

Proměnné

Jakýkoliv typ programu pracuje s daty. Aby k datům bylo možné jednoduchým způsobem v programu přistupovat (nemuseli jsme k nim přistupovat pomocí adres do paměti), používáme proměnné. Proměnné jsou paměťové místa, do kterých se ukládají data určitého typu. K datům poté přistupujeme pomocí identifikátoru (jména) proměnné.

Každá proměnná v programu musí být určitého datového typu. Datový typ proměnné určuje vnitřní reprezentaci proměnné v počítači, obor hodnot a operace, které lze s proměnnou provádět.

Všechny položky používané programátorem v programu je nutné nejprve deklarovat (seznamuje počítač s názvem proměnné, funkce, třídy, šablony nebo datového typu, ale nevyhradí jim prostor v paměti) a zpravidla i definovat (nejenom popisuje objekt, ale zároveň přikazuje překladači, aby objekt i vytvořil).

Syntaxe deklarace proměnné

  extern int promenna;

Syntaxe definice proměnné

  int promenna;

Proměnnou je možné při deklaraci i inicializovat

  int promenna = 5;

Konstanty

Jako konstanty lze v C++ používat libovolná celá i reálná čísla a znaky. Konstanty se deklarují buď pomocí direktivy preprocesoru:

  #define jméno_konstanty hodnota   // pozor neuvádí se středník!!!

nebo pomocí modifikátoru const:

  const specifikátor_datového_typu jméno_konstanty = hodnota;

Druhý způsob vytvoření konstanty je bezpečnější, protože C++ provede typovou kontrolu hodnoty. První případ typovou kontrolu neprovede.

Ukazatele

Na ukazatel je možné pohlížet jako na proměnnou, která obsahuje adresu datového objektu nebo funkce v paměti. Bez použití ukazatelů se při práci s ObjectARX neobejdete, proto věnujte prosím následujícím odstavcům dostatečnou pozornost.

Syntaxe deklarace

  datový_typ *jméno_ukazatele;

Argumenty deklarace

datový_typ
Datový typ objektu, na který ukazatel ukazuje (doménový typ). Doménový typ ukazatele musí odpovídat skutečnému typu objektu, na který ukazatel ukazuje, jinak by program nesprávně interpretoval hodnoty, které tam jsou uloženy.
*
Symbol sdělující programu, že uvedená proměnná je deklarovaná jako ukazatel.
jméno_reference
Identifikátor deklarovaného ukazatele.

Způsob inicializace ukazatele

Ukazatel inicializujeme, uložíme-li do něj adresu proměnné nebo funkce odpovídajícího typu. Pokud ukazatel neukazuje na žádný objekt má hodnotu 0. Uložení adresy do ukazatele lze různými způsoby - viz příklad:

  int x, *px = &x;  
      //přidělením adresy existujícího objektu pomocí operátoru &
  int *py = px;         // předáním hodnoty z jiného ukazatele
  int pole[10];              
  int *ppole = pole;    
      // pole se automaticky konvertuje na ukazatel na první prvek,
      // který můžeme předat proměnné typu ukazatel

  py = NULL;            // přiřazením hodnoty adresy 0 nebo 
  py = 0;               // NULL - má význam ukazatel ukazující nikam

  void f(float, float);
  void (*pf)(float, float) = f
      // vytvoření ukazatele na funkci, identifikátor funkce
      // představuje její adresu

  long double *p = new long double  
      // uložení ukazatele na paměť velikosti long double

Poznámka - deklarace ukazatele

Při každé deklaraci ukazatele je dobré buď ukazatel ihned inicializovat na požadovanou hodnotu nebo jim alespoň přiřadit hodnotu 0 nebo NULL. Předejdete tím výskytu řady velice záludných chyb.

Při pojmenování ukazatele je dobré začínat jméno ukazatele např. písmenem p (jako pointer - ukazatel). Usnadní to orientaci v napsaném programu.

Dereferencování ukazatele

Aby mělo použití ukazatelů praktický význam musí být možné přistupovat k objektům, které se nachází na adresách uložených v ukazatelích. Přístup k těmto objektům se nazívá dereferencování. Jazyk C++ obsahuje několik operátorů umožňujících dereferencování:

Poznámka - operátor dereferencování

Operátor * (dereferencování) překladači sděluje, že se nezajímáme o adresu uloženou v ukazateli, ale o objekt, který je na této adrese uložen.

Dynamické přidělování a uvolňování paměti

Dynamické přidělování paměti umožňuje vytvářet objekty za běhu programu podle okamžité potřeby. K rezervování a uvolňování paměti slouží v programovacím jazyku C++ operátory new a delete. Při použití operátoru new je alokován volný úsek paměti, je označen jako použitý a je vrácena adresa na začátek alokované paměti.

Operátor new je možné využít při vytváření dynamického pole. Rozsahy inexů se udávají v hranatých závorkách. Rozsah prvního indexu nemusí být konstanta.

Příklad vytvoření dynamického pole 10x10 prvků

  int n = 10;                  // definování proměnné typu integer
  p_int = new int[n];          // vytvoření pole o 10 prvcích
  int (*pp_int) [10];          // ukazatel na pole 10-ti prvků int
  pp_int = new int[n][10];     // vytvoření pole n x 10 prvků typu int

K uvolnění paměťového prostoru programovací jazyk C++ nabízí operátor delete. Operátor delete uvoní paměť, ale nesmaže hodnotu adresy uloženou v ukazateli. Pokud ukazatel znovu ihned neinicializujete, musíte do něj hodnotu NULL nebo 0 uložit sami.

Operátor delete sám nerozpozná jestli vymazává samostatnou hodnotu nebo pole hodnot. V případě požadavku na vymazání pole hodnot je nutné použít příkaz delete[] viz následující příklad.

  int max = 10;         // definování proměnné typu integer
  int *p_int;           // vytvoření ukazatele
  p_int = new int(22);  // vytvoření jednoduché proměnné
  delete p_int;         // uvolnění paměti
  p_int = new int[n];   // vytvoření pole o 10 prvcích
  delete[] p_int;       // uvolnění paměti
  p_int = 0;            // ukazatel nyní nebudeme využívat, přiřadíme
                        // mu hodnotu 0, aby neukazoval nikam

Poznámka - uvolňování paměti

Při dynamickém přidělování je důležité, abychom neztratily ukazatel na alokovanou paměť. Pokud by k tomu došlo nemohli bychom později tuto paměť uvolnit.

Datový typ reference

Datový typ reference je hybridní datový typ kombinující chování proměnné a ukazatele. Reference lze použít stejným způsobem jako jiné druhy proměnných v jazyce C++. S referencí lze však také změnit hodnotu proměnné, která je z dosahu možnosti funkce bez nutnosti dereferencovat ukazatele. Na referenci je možné pohlížet jako na druhé jméno proměnné.

Reference jsou často používány k předávání parametrů funkcím (předání hodnot odkazem) a návratu hodnot z funkcí (více viz lekce Funkce).

Použití reference

Aby bylo možné použít referenci na proměnnou T, musíme ji inicializovat referenci na proměnnou typu T. Jednou inicializovaná reference je již natrvalo svázána s proměnnou (nelze ji reinicializovat).

Syntaxe deklarace reference

  datový_typ& jméno_reference;

Argumenty příkazu reference

datový_typ
Datový typ objektu, na který ukazuje reference.
&
Symbol sdělující programu, že uvedená proměnná je deklarovaná jako reference.
jméno_reference
Identifikátor deklarované referenční proměnné.

Poznámka - operátor &

Operátor & se v programovacím jazyku C++ používá dvěma způsoby:

Příklad použití reference

  int promInt = 1;
                  // definice proměnné typu integer
  int& promIntRef = promInt;
                  // vytvoření reference na proměnnou typu integer
  promInt = 5;
                  // promIntRef = promInt = 5
  promIntRef = 7;
                  // promIntRef = promInt = 7

Poznámky k použití reference