4. díl - Typový systém v céčku podruhé: Datové typy

C++ Základní konstrukce C Typový systém v céčku podruhé: Datové typy

V minulém dílu seriálu o programování v céčku jsme si ukázali základní datové typy, byly to int, float a char. Nyní se na datové typy podíváme více zblízka a vysvětlíme si, kdy jaký použít. Dnešní lekce bude hodně teoretická, ale o to více bude praktická ta příští. Na konci si vytvoříme pár jednoduchých ukázek.

Pozn.: Velikosti a přítomnost některých datových typů se může někdy různit podle zvoleného standardu céčka a cílové architektury počítače.

Celočíselné datové typy

Podívejme se nyní na tabulku vestavěných celočíselných datových typů v Céčku. Všimněte si typu int, který již známe z minule.

Datový typ Rozsah Velikost
char -128 až 127 8 bitů
short -128 až 127 nebo -32 768 až 32 767 16 nebo 32 bitů
int -32 768 až 32 767 nebo -2 147 483 648 až 2 147 483 647 16 nebo 32 bitů (záleží na systému)
long int -2 147 483 648 až 2 147 483 647 32 bitů
long long int -9 223 372 036 854 775 808 až 9 223 372 036 854 775 807 64 bitů

Poznámka: U velikostí datových typů záleží na operačním systému, tedy zda je 16 bitový nebo 32/64 bitový. Pro vás budou platit obvykle ty vyšší hodnoty.

Možná si teď říkáte, že je divné, že char je číslo, když jsme ho používali jako znak v předchozích dílech. My však můžeme char použít jako číslo a zároveň jako znak (při výpisu buď použijeme %d jako číslo a nebo %c jako znak).

Další otázka, která vás asi napadá, je: Proč máme tolik možných typů pro uložení čísla? Odpověď je prostá - záleží na jeho velikosti. Čím větší číslo, tím více spotřebuje paměti. Pro věk uživatele tedy zvolíme char, protože se jistě nedožije více, než 127 let. Představte si databázi milionu uživatelů nějakého systému. Když zvolíme místo charu int, bude zabírat 4x (nebo 2x) více místa. Naopak, když budeme mít funkci k výpočtu faktoriálu, stěží nám bude stačit rozsah intu a použijeme long.

Nad výběrem datového typu nemusíte moc přemýšlet a většinou se používá jednoduše int. Typ řešte pouze v případě, když jsou proměnné v nějakém poli (obecně kolekci) a je jich tedy více, potom se vyplatí zabývat se paměťovými nároky. Tabulky sem dávám spíše pro úplnost.

Desetinná čísla

U desetinných čísel je situace poněkud jednodušší, máme na výběr pouze dva datové typy. Samozřejmě se opět liší v rozsahu hodnot, dále však ještě v přesnosti (vlastně počtu des. míst). Double má již dle názvu dvojnásobnou přesnost oproti float.

Datový typ Rozsah Přesnost
float 1.2E-38 to 3.4E+38 6 číslic (32 bitů)
double 2.3E-308 to 1.7E+308 15 číslic (64 bitů)
long double 3.4E-4932 to 1.1E+4932 19 číslic (80 bitů)

Pozor, vzhledem k tomu, že desetinná čísla jsou v počítači uložena ve dvojkové soustavě, dochází k určité ztrátě přesnosti. Odchylka je sice téměř zanedbatelná, nicméně když budete programovat např. finanční systém, nepoužívejte tyto datové typy pro uchování peněz, mohlo by dojít k malým odchylkám. Velikost long double se může lišit dle implementace.

Když do floatu chceme dosadit přímo ve zdrojovém kódu, můžeme použít sufix f, u double sufix d:

float f = 10.1f;
double d = 10.02d;

Jako desetinný separátor používáme ve zdrojovém kódu vždy tečku, nehledě na to, jaké máme v operačním systému regionální nastavení (například v českém prostředí se tradičně používá desetinná čárka).

Char

Podívejme se ještě blíže na typ char, který může reprezentovat buď celé číslo nebo znak.

Pro reprezentaci znaku použijeme char takto:

char z = 'A';
printf("%c", z);

a když chceme reprezentovat char jako číslo:

char i = 127;
printf("%d", i);

Usingned typy

Většinu datových typů můžeme ještě předsadit klíčovým slovem unsigned, např. vytvoříme proměnnou typu unsigned int, unsigned float, unsigned double a podobně. Sign označuje znaménko čísla a unsigned znamená, že číslo znaménko nemůže obsahovat. Výsledkem je, že je taková proměnná vždy nezáporná a vejde se do ni proto i 2x větší číslo, jelikož není využita záporná část. Uveďme si příklad u charu:

typ rozsah
char -128 až 127
unsigned char 0 až 255

Zkusme jsi teď něco naprogramovat :) Vytvoříme si "tabulku" s různými datovými typy a jejich velikostmi. Založíme jsi nový projekt s názvem Tabulka a jeho kód upravíme takto:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(int argc, char** argv) {

return (EXIT_SUCCESS);
}

Pro názornost jsem vymazal šedou dokumentaci, ale klidně si ji tam nechte. Změna spočívá v includování limits.h, což nám umožňuje přístup k funkcím pro zjištění nejvyšší hodnoty datových typů.

Pro zjištění velikosti datového typu použijeme funkci sizeof(), která nám vrátí velikost datového typu v bajtech.

Pro zjištění rozsahu použijeme konstanty (konstantu si vysvětlíme později) ze souboru limits.h, který jsme si includovali.

Zmíněné funkce tedy vyzkoušejme:

int velikostIntu = sizeof(int); // Ukládáme si velikost intu.
printf("Int zabírá %d bajt/y/ů místa \n", velikostIntu); // Vypisujeme velikost intu

A toto by měl být výsledek:

Velikost datového typu int v céčku

Nyní víme, že funkce sizeof() nám vrátí velikost zadaného datového typu. Pojďme vyzkoušet ještě konstanty ze souboru limits.h, které by nám měly vrátit největší možné číslo zadaného datového typu:

int maximalniRozsah = INT_MAX; // Ukládáme maximalní rozsah intu
printf("Maximální rozsah intu je %d \n", maximalniRozsah); // Vypisujeme maximální rozsah intu

A toto by měl být výsledek (pokud nemáte jiný typ procesoru, viz. výše):

Maximální hodnota typu int v céčku

Když teď víme, že nám konstanty i funkce fungují, můžeme se vrhnout do programování konzolové tabulky :) Kód bude vypadat asi tak to:

int maxInt = INT_MAX;
short maxShort = SHRT_MAX;
char maxChar = CHAR_MAX;
char sizeInt = sizeof(int);
char sizeShort = sizeof(short);
char sizeChar = sizeof(char);
printf("INT: zabírá %d počet bajt/y/ů a největší možné číslo je %d\n", sizeInt, maxInt);
printf("SHORT: zabírá %d počet bajt/y/ů a největší možné číslo je %d\n", sizeShort, maxShort);
printf("CHAR: zabírá %d počet bajt/y/ů a největší možné číslo je %d\n", sizeChar, maxChar);

Takto by měl vypadat výsledek:

Tabulka základních datových typů v céčku

To bychom měli, příště nás čekají podmínky :)


 

Stáhnout

Staženo 173x (31.75 kB)
Aplikace je včetně zdrojových kódů v jazyce c

 

  Aktivity (3)

Článek pro vás napsal Monarezio
Avatar
Autor se věnuje Javě, PHP, C, HTML ale furt se tyto jazyky učí. Zajímá ho spíše game design a píše svůj vlastní 2d engine v JavěFX.

Jak se ti líbí článek?
Celkem (5 hlasů) :
4.24.24.24.2 4.2


 


Miniatura
Předchozí článek
Cvičení k 1.-3. lekci Céčka
Miniatura
Všechny články v sekci
Programování v jazyce C - Základy
Miniatura
Následující článek
Podmínky (větvení) v jazyce C

 

 

Komentáře
Zobrazit starší komentáře (1)

Avatar
Posix
Člen
Avatar
Posix:

long mívá 8 bytů. Navíc tam máš rozsah -9,223,372,036­,854,775,808 až 9,223,372,036­,854,775,807, což je 264 => 8 bytů.

A opravdu jsem ještě neslyšel o unsigned floatu a doublu...

Editováno 15.9.2014 0:03
Odpovědět 15.9.2014 0:02
Proč to dělat jednoduše, když to jde složitě.
Avatar
David Čápka
Tým ITnetwork
Avatar
David Čápka:

Před publikací jsem se na ty typy schválně díval a je v tom hrozný bordel, všude píšou něco jiného a liší se to i podle standardů, takže nevím, jestli to tu má úplně smysl rozmazávat. Jestli máte návrh na konkrétní úpravu, tak prosím napište co byste kde odebrali/přidali.

Odpovědět 15.9.2014 0:21
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
coells
Redaktor
Avatar
Odpovídá na David Čápka
coells:

Konkrétní úpravy:

  1. opravit ten popis u rozsahu intu
  2. přidat long int
  3. opravit popis u float, double, protože je rozdíl mezi číslem a číslicí
  4. přidat long double

Typ int primárně reflektuje velikost základního registru, tzn. že na 16-bitovém stroji bude 16 bitů, na 32 a 64-bitovém stroji bude 32 bitů. Na 18-bitovém stroji bude 18 bitů. Důvodem je efektivita výpočtů.

Typ short je polovina z intu, tzn. na 16-bitovém stroji má short 8 bitů.

Typ long je rozšířením int na základě rozsahu registrů, tzn. pokud má procesor rozšíření akumulátoru na 64 bitů, bude mít long 64 bitů.

Typ long long má 64 bitů, long double má 128 bitů a výpočty lze simulovat softwarově.

 
Odpovědět 15.9.2014 11:23
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na coells
David Čápka:

Díky za připomínky, zapracovali jsme je s autorem, článek je teď díky tobě kvalitnější. U long double jsem na několika místech našel, že má spíše 80 bitů, tak jsme použil tuto hodnotu.

Odpovědět 9.10.2014 15:59
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Tom Pospíšil:

Pro věk uživatele tedy zvolíme char, protože se jistě nedožije více, než 127 let. No nejstarší člověk se dožil 123 let, za chvíli nám char nebude stačit:D

 
Odpovědět  +2 31.3.2015 16:05
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Tom Pospíšil
tomisoka:

Ale bude jen bude potřeba použít:

unsigned char
 
Odpovědět  +2 31.3.2015 17:19
Avatar
karel3klic
Člen
Avatar
Odpovídá na Posix
karel3klic:

bajt má osm bitu takže maximální hodnota takového čísla nemůže být 2 na 64tou. Asembler hovoří jasně.

 
Odpovědět 28.9.2015 0:22
Avatar
JohnLuther
Člen
Avatar
JohnLuther:

Osobne by som rád šiel rovno z visual C, ale kedže plánujem ísť na VŠ, čo som väčšinou pozeral tak od začiatku sa tam už ide väčšinou c prípadne aj rovno c++, škoda... Doteraz som sa skôr orientoval na weby... Prekvapuje ma ale že mi to celkom ide...

 
Odpovědět 28.12.2015 16:44
Avatar
DarkCoder
Člen
Avatar
DarkCoder:

Druhý článek o C a opět mnoho chyb. Datový typ short rozhodně nemá rozsah -128 až 127! Norma stanovuje minima, zde je 16bitu. V 16bitovém prostředí není rozdíl mezi typy int a short int. Ve 32bitovém prostředí zase mají int a long int stejnou velikost. Když už se tu řeší modifikátory datových typů, tak je třeba zmínit přesně a správně, který modifikátor se pro který datový typ používá!

unsigned float, unsigned double a podobně...

To opravdu ne..

Nad výběrem datového typu nemusíte moc přemýšlet a většinou se používá jednoduše int..

Odvážné tvrzení. Aby typ přesněji splňovat požadavky je důležité. Obzvláště když se tyto modifikované typy užívají ve funkcích (jako třeba printf(), scanf()). Při výpisu celých čísel modifikovaných pomocí short, long, unsigned opravdu nestačí použít jen specifikátor %d. Funkce potřebují znát přesný typ přebíraných dat. Pokud bychom nad tím moc nepřemýšleli, tak to dopadne jako v příkladu výše, kde je špatně použit specifikátor %d místo správného %hd.

short maxShort = SHRT_MAX;
printf("SHORT: zabírá %d počet bajt/y/ů a největší možné číslo je %d\n", sizeShort, maxShort);

Modifikátory datových typů:
long - použití u int, double
short - použití u int
signed - použití u char, int (lze použít spolu s modifikátory long nebo short)
unsigned - použití char, int (lze použít spolu s modifikátory long nebo short)

Když do floatu chceme dosadit přímo ve zdrojovém kódu, můžeme použít sufix f, u double sufix d:

double d = 10.02d;

Žádný sufix d neexistuje! Nespecifikujeme-li sufix, je konstanta brána jako ty double. Pro float používáme F, pro long double L.

Znaková proměnná může být reprezentována i pomocí konstanty se zpětným lomítkem. (\n \r \t \a apod.)

Opět apeluji na důslednou kontrolu výkladu, jinak to čtenářům, kteří se seznamují a chtějí naučit jazyk C, nic nedá!

 
Odpovědět 6. října 0:26
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 11. Zobrazit vše