na obsah klávesové zkratky na hlavní stránku na menu

Proměnné a konstanty

Jazyk C je typový jazyk a definuje tak základní číselné typy různých vlastností. V tomto článku bude stručně vysvětlena definice proměnné a konstanty a dále načtení a výpis proměnné.

Typy

Jazyk C je typový jazyk stejně jako drtivá většina ostatních staticky kompilovaných jazyků. Proto jazyk C definuje několik základních číselných typů. Tyto typy se liší rozsahy i typem uchovávaných dat.

signed/unsigned char
Jde o nejmenší z typů. Běžně se používá pro uchovávání znaků. Podle standardu má minimálně 8 bitů.
signed/unsigned short int
Číselný typ o velikosti minimálně 16 bitů.
signed/unsigned int
Číselný typ o velikosti minimálně 16 bitů. Musí být alespoň tak velký jako typ short int.
signed/unsigned long int
Číselný typ o velikosti minimálně 32 bitů. Musí být alespoň tak velký jako typ int.
signed/unsigned long long int
Číselný typ o velikosti minimálně 64 bitů. Tento typ se nachází až ve standardu C99. Musí být alespoň tak velký jako typ long.
float
Číselný typ o velikosti 32 bitů. Uchovává čísla s plovoucí desetinnou tečkou s přesností 5-7 desetinných míst.
double
Číselný typ o velikosti 64 bitů. Uchovává čísla s plovoucí desetinnou tečkou s přesností 15-16 desetinných míst.

Typy short int, long int a long long int mají své kratší ekvivalenty short, long a long long. Je vidět, že standard neurčuje pevně velikost typů a toto rozhodnutí je ponecháno na cílové platformě. V počítačích s procesory x86 je int jako základní typ běžně 32 bitový. Nikomu se ovšem nebrání vytvořit si svoji platformu, kde budou mít všechny typy např. 32 bitů.

Proměnné a konstanty

Na rozdíl od pascalu se proměnná v jazyce C definuje zápisem typu před jméno proměnné. Chceme-li tedy vytvořit proměnnou x typu int, provedeme to zápisem

int x;

Proměnnou můžeme v jednom kroku také inicializovat na libovolnou hodnotu. To provedeme zápisem

int x = 3;

což je ekvivalentní zápisu

int x;
x = 3; // přiřazení do proměnné

Zde jsme proměnné x nastavili hodnotu 3. Proměnné v jazyce C se implicitně nenulují! V proměnné bude po jejím vytvoření hodnota, která je v danou chvíli na daném místě v paměti (jinými slovy v podstatě náhodná). Proto je vždy nutné před prvním použitím proměnné nastavit počáteční hodnotu, většinou nulu.

V jazyce C existují dva typy proměnných, a to lokální a globální. Předvedeme na příkladu jejich rozdíl.

const int x = 1;

int main (int argc, char **argv)
{
  int x = 3;
  x = 4;
  ...
}

Na řádce jedna vytváříme tzv. konstantu. Konstanta se definuje tak, že před typ konstanty napíšeme klíčové slovo const. Konstantu musíme při vytvoření inicializovat, nelze to udělat později. V tuto chvíli máme konstantu typu int s hodnotou 1. Jelikož je definice této konstanty mimo jakékoliv tělo funkce (mimo jakékoliv složené závorky, na úrovni souboru), bude hodnota této konstanty přístupná všude v celé délce souboru (pokud nedojde k zastínění). Na řádce pět definujeme tzv. lokální proměnnou, neboť je umístěna v těle funkce main. Tato definice zastíní globální definici. Jinými slovy v těle funkce main se bude pracovat s lokální proměnnou x. To tedy mimo jiné znamená, že přiřazení na řádce šest bude v pořádku. Kdybychom řádek pět vymazali, program se nepřeloží, neboť se budeme pokoušet přiřadit hodnotu do konstanty.

Přetypování

V jazyce C existují dva typy přetypování, a to explicitní a implicitní. Implicitní přetypování probíhá na pozadí a provádí ho překladač.

double a = 3;

Zde jsme do proměnné typu double přiřadili celočíselnou hodnotu. Překladač správně pochopí, co chceme udělat a hodnotu 3 převede na 3.0. Někdy není možné hodnotu převést automaticky, aniž by to nezpůsobilo problémy. V tom případě překladač vypíše nejméně varování. Pokud jsme si jisti, co děláme, můžeme provést tzv. explicitní přetypování.

double a = 3.0;
double b = 2.0; 
int c = (int) a % (int) b;

Zde byl použit operátor modulo, který je možné aplikovat pouze na celá čísla. Protože jsme z nějakého důvodu měli čísla a a b uložená jako double, musíme explicitně říct, že je chápeme jako proměnné typu int. To provedeme zápisem cílového typu do závorek před proměnnou, kterou chceme přetypovat. Pokud bychom chtěli přetypovat výsledek složitějšího výrazu, museli bychom uzavřít celý výraz do závorek a před ně umístit cílový typ v závorkách.

Výpis pomocí printf()

Proměnnou libovolného typu lze vypsat pomocí již dříve zmíněné funkce printf(). Výpis proměnné bude nejlepší vysvětlit na příkladu

int x = 3;
printf("promenna x ma hodnotu %d\n", x);

První parametr funkce printf() je řetězec s maskou. Speciální sekvence uvozená % říká, že na toto místo se bude vkládat proměnná typu int (viz níže). Za masku je pak nutné uvést samotnou proměnnou, která se bude vypisovat. Samozřejmě je možné v jednom volání vypsat libovolné množství hodnot, jen je nutné mít ke každému místu v masce přiřazenou právě jednu proměnnou správného typu. Výše uvedený program vypíše na výstupu

promenna x ma hodnotu 3

Pro každý typ existuje jiná sekvence. Několik nejpoužívanějších uvedeme.

%c
Zastupuje jeden znak.
%s
Zastupuje řetězec znaků.
%d
Zastupuje znaménkový číselný typ (signed int).
%u
Zastupuje neznaménkový číselný typ (unsigned int).
%f
Zastupuje typ s plovoucí desetinnou tečkou (float, double).
%e
Zastupuje typ s plovoucí desetinnou tečkou ve vědeckém zápisu s exponentem (float, double).

Jak je vidět, funkce printf() toho umí opravdu hodně. To ale ještě není vše. Výpis proměnné lze dále upravovat pomocí parametrů řídící sekvence. Obecně je plný tvar sekvence

<[vlajka]><[šířka]><[.přesnost]><[délka]>typ
vlajka
Hodnota - určuje zarovnání vlevo ve sloupci dané šířky. Zarovnání vpravo je výchozí. Hodnota + vynutí výpis znaménka. Mezera znamená, že místo znaménka, které by se netisklo, bude vložena mezera. Hodnota # vynutí vypsání 0, 0x, 0X nebo desetinné tečky u oktalových, hexadecimálním nebo necelých čísel. Konečně 0 znamená, že se bude hodnota zleva doplňovat nulami namísto mezer.
šířka
Udává minimální počet znaků, které se budou tisknout. Je-li číslo kratší, bude doplněno znakem nastaveným výše. V případě, že zadáme *, uvádíme velikost šířky v přidané proměnné namísto čísla v sekvenci masky.
přesnost
U decimálních čísel uvádí minimální počet vytisknutých hodnot (jako šířka). Je-li přesnost nastavená na nulu, nebude pro nulu vytisknut žádný znak. U necelých čísel jde o počet číslic za desetinnou tečkou. U řetězců tímto omezíme maximální vypsanou délku. Stejně jako u šířky můžeme toto číslo zadat jako přídavný parametr zapsáním *.
délka
Hodnota h značí short a je použitelná jen u decimálních hodnot. Hodnota l značí long u decimálních hodnot nebo double u neceločíselných hodnot. Hodnota L značí long double a je použitelná jen u neceločíselných hodnot.

Načtení hodnoty

K načtení hodnoty ze vstupu slouží funkce scanf(). Tato funkce opět používá masku jako první parametr. Nejlepší bud uvést příklad.

int x;
scanf("%d", &x);

Maska má v této funkci úlohu importního filtru. Hodnota je načtena jen a pouze, pokud vstup vyhoví masce a na určeném místě je hodnota správného typu, v tomto případě typu int. Lze si představit, že bychom chtěli např. načítat hodnotu vektoru zapsaného jako [3,2]. Pak lze zavolat funkci scanf takto:

int a, b;
scanf("[%d,%d]", &a, &b);

Všechny bílé znaky před každým zástupným symbolem jsou ignorovány, tedy i vstup [  3,  2 ]  by vyhověl masce. Znak & je u volání této funkce nutný. Důvod bude vysvětlen v kapitole o ukazatelích.