4. díl - Typový systém podruhé - Datové typy v C++

C++ Základní konstrukce C++ Typový systém podruhé - Datové typy v C++

V minulém dílu seriálu jsme si ukázali základní datové typy, byly to int, string a float. 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.

C++ rozeznává mnoho druhů datových typů. Těm základním se říká fundamentální a jedná se zejména o čísla.

Celočíselné datové typy

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

Datový typ Rozsah Velikost
signed char -128 až 127 8 bitů
unsigned char 0 až 255 8 bitů
short –32 768 to 32 767 16 bitů
unsigned short 0 až 65 535 16 bitů
int –2 147 483 648 až 2 147 483 647 32 bitů
unsigned int 0 až 4 294 967 295 32 bitů
long int velikost i rozsah jsou závislé na překladači
unsigned long int velikost i rozsah jsou závislé na překladači

Pozn.: rozsahy a velikosti typů jsou závislé na překladači a architektuře systému, já tu uvádím hodnoty pro Visual Studio a 64 bitovou architekturu.

Asi vás napadá otázka, 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 unsigned char, protože se jistě nedožije více, než 255 let. Představte si databázi milionu uživatelů nějakého systému, když zvolíme místo unsigned char, int, bude zabírat 4x 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 long.

Všimněte si, že některé typy začínají na unsigned. Jsou téměř stejné, jako jejich dvojníci bez unsigned, jen neumožňují záporné hodnoty a tím pádem na kladnou část mohou uložit 2x vyšší hodnotu. Opakem je signed, který ale překladač doplňuje automaticky (výjimkou je signed char, protože samotné char má jiný význam).

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 teprve vyplatí zabývat se paměťovými nároky. Tabulku sem dávám spíše pro úplnost. Mezi typy samozřejmě funguje již zmíněná implicitní konverze, tedy můžeme přímo přiřadit int do proměnné typu long a podobně, aniž bychom něco konvertovali.

Desetinná čísla

U desetinných čísel je situace poněkud jednodušší, máme na výběr pouze tři datové typy. Samozřejmě se liší opět v rozsahu hodnoty, 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 +-3.4 * 10−38 až +-3.4 * 1038 7 číslic
double +-1.7 * 10−308 až +-1.7 * 10308 15 číslic
long double +-1.7 * 10−308 až +-1.7 * 10308 15 číslic

Pozn: typ long double je někde stejný jako double, nebo může být větší, ve VS je stejný.

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, mohou se objevit problémy.

Jako desetinný separátor používáme ve zdrojovém kódu vždy tečku, nehledě na to, jaké máme ve Windows regionální nastavení.

Další vestavěné datové typy

Podívejme se na další datové typy, které nám C++ nabízí:

Datový typ Rozsah Velikost/Přesnost Význam
char U+00 až U+ff (0 až 255 nebo -128 až 127) 8 bitů znak
wchar_t U+0000 až U+ffff (0 až 65 535) 16 bitů "široký" znak
bool true nebo false (1 nebo 0) 8 bitů logická hodnota

Char

Char (character) nám reprezentuje jeden znak. Na rozdíl od stringu, který reprezentoval celý řetězec charů, píšeme znaky v C++ píšeme do jednoduchých apostrofů:

char c = 'A';

Char patří v podstatě do celočíselných proměnných (obsahuje číselný kód znaku), ale přišlo mi logičtější uvést ho zde.

wchar_t je podobný, jen umožňuje uložit více různých znaků.

Bool

Bool nabývá dvou hodnot: true (pravda) a false (nepravda). Budeme ho používat zejména tehdy, až se dostaneme k podmínkám. Do proměnné typu bool lze uložit jak přímo hodnotu true/false, tak i výsledek logického výrazu nebo celé číslo (0 jako false a cokoli jiného jako true). Zkusme si jednoduchý příklad:

bool b = false;
bool vyraz = (15 > 5);
cout << b << endl;
cout << vyraz << endl;
cin.get();

Výstup programu:

0
1

Výrazy píšeme do závorek. Vidíme, že výraz nabývá hodnoty true (pravda), protože 15 je opravdu větší než 5. Od výrazů je to jen krok k podmínkám, na ně se podíváme příště.

Ukazatele na datové typy

Jejich hlavní využití je u polí, funkcí a v objektově orientovaném programování, takže o nich ještě hodně uslyšíte. Teď si o nich řekneme jen pár základních věcí.

Ukazatel už podle názvu na něco ukazuje. Používá se jako odkaz na proměnnou. Výhodou tohoto přístupu je hlavně to, že pokud ukazatel zkopírujeme, odkazuje stále na stejnou proměnnou. Několik ukazatelů tedy může ukazovat na jednu hodnotu v paměti.

Ukazatele se tvoří podobně jako proměnné, jen před název proměnné připíšeme hvězdičku (*). V tomto případě samozřejmě nejde o násobení ;) .

int *ukazatel_na_int;

Do ukazatelů přiřazujeme adresy proměnných. Ty získáme operátorem &:

int a = 15;
int *u = &a;

Chceme-li pracovat s proměnnou, na kterou ukazatel odkazuje, napíšeme před něj hvězdičku.

int b = *u + 64;

Aby se nám to nepletlo s násobením, můžeme to dát do závorek:

int b = (*u) + 64;

Reference

Referenci lze popsat jako ukazatel, u kterého nelze měnit, na co ukazuje. Druhá možnost, jak referenci popsat, je, že se jedná o nový název pro existující proměnnou.

Referenci vytvoříme podobně jako ukazatel, jen místo hvězdičky použijeme znak & a k přiřazované proměnné už ho nepíšeme. Protože nelze měnit, na co reference odkazuje, musíme jí proměnnou přiřadit už při vytvoření.

int a = 15;
int &u = a;

Při práci s proměnnou, na kterou reference odkazuje, už žádnou hvězdičku psát nemusíme:

u = 7 + u * 8;

Je toho ještě spoustu k vysvětlování a jsou další datové typy, které jsme neprobrali. Aby jsme však stále neprobírali jen teorii, ukážeme si již příště podmínky :)


 

  Aktivity (5)

Článek pro vás napsal Zdeněk Pavlátka
Avatar
Autor se věnuje spoustě zajímavých věcí :)

Jak se ti líbí článek?
Celkem (7 hlasů) :
4.857144.857144.857144.857144.85714


 


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

 

 

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

Avatar
tomisoka
Redaktor
Avatar
tomisoka:

U těch "Plný(správný) název" nejsou ty typy závislé jen na MS a jejich compilerech?
Není lepší použít standardní typy int8_t, int16_t atd. ?

 
Odpovědět 20.2.2015 19:21
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):

je na to knižnica? Pretože normálne nefungujú.

Editováno 20.2.2015 19:24
Odpovědět 20.2.2015 19:23
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na tomisoka
Libor Šimo (libcosenior):

Ok súhlasím s tebou, si dobrý.

Odpovědět 20.2.2015 19:56
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Fikoun
Člen
Avatar
Fikoun:

char pismeno;

Klasický char bez signed nebo unsigned, bude mít jako výchozí rozsah podle unsigned(0 až 255) nebo signed(-128 až 127).

 
Odpovědět 4.9.2015 14:47
Avatar
Zdeněk Pavlátka
Tým ITnetwork
Avatar
Odpovídá na Fikoun
Zdeněk Pavlátka:

char by měl mít -128 až 127 ( https://msdn.microsoft.com/…3f49ktz.aspx )

Editováno 4.9.2015 16:18
Odpovědět 4.9.2015 16:17
Kolik jazyků umíš, tolikrát jsi programátor.
Avatar
Roman
Člen
Avatar
Roman:

Ahoj, prosím vás prečo mi sem hádže error, v tom druhom riadku mám podčiarknuté &

int a = 15;
int *u = &a;

Error a value of type "bool" cannot by used to initialize an entity of type "int"
Netreba tam importnúť nejakú knižnicu?
dík

Editováno 26. února 18:41
 
Odpovědět 26. února 18:39
Avatar
Roman
Člen
Avatar
Odpovídá na Roman
Roman:

Už som prišiel na chybu, keď som premenoval int a -> int aa a následne podľa toho upravil aj druhý riadok &aa tak to fungovalo neviem síce prečo :P

 
Odpovědět 26. února 19:07
Avatar
B42P6
Člen
Avatar
B42P6:

Nebude to tým že máš v kóde nadeklarovanú ešte jednu premennú "a"(pravdepodobne bool)?

Odpovědět  +1 26. února 21:34
'long long long' is too long for GCC
Avatar
nf fn
Člen
Avatar
nf fn:

U toho char a wchar_t bys mohl doplnit i char16_t a char32_t

 
Odpovědět 16. července 9:37
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 12. Zobrazit vše