Skip to main content

Začínáme programovat v jazyku C++ (Ukázka, strana 99)

Page 1

98

Začínáme programovat v jazyku C++

Podívejme se však znovu na zdrojový kód funkce zadost(). Zde se sice ne zcela zjevně, ale přece jen opakujeme. Číst prvky pole bychom měli pokud možno v cyklu. Abychom ho ovšem mohli použít, potřebujeme také uložit do pole vypisované znakové řetězce.

Poznámka Všimněte si, že ve funkci zadost jsme do prvků pole datum uložili hodnoty a ty jsme pak v jiné funkci používali. Jinak řečeno, změnou formálního parametru typu pole jsme změnili skutečný parametr. Připomeňme si, že to pro parametry typů, které jsme používali v předchozích kapitolách, neplatilo.

7.5

Typ string

Jazyk C++ nabízí hned dva nástroje pro práci se znakovými řetězci: pole znaků a typ string. Pro pole řetězců bychom však potřebovali pole složené z polí znaků (tomu říkáme dvourozměrné pole). To C++ samozřejmě umožňuje, ale zatím se tomu vyhneme, neboť práce s typem string je jednodušší. Typ string je deklarován v hlavičkovém souboru string (bez přípony) a představuje posloupnost znaků spolu s rozsáhlou sadou nástrojů pro operace s ní. Mimo jiné: z K jednotlivým znakům můžeme přistupovat podobně jako k prvkům pole pomocí indexování. Prvky, které tvoří proměnnou typu string, jsou proměnné typu char a počáteční prvek – počáteční znak – má index 0, podobně jako je tomu u polí. z Délku řetězce uloženého v proměnné x typu string, tedy počet znaků v něm, zjistíme zápisem x.length() nebo x.size(). z Pro instance typu string jsou definovány relační operátory == a !=. Dva řetězce jsou si rovny, když obsahují na stejných místech stejné znaky. z Pro instance (tj. proměnné) typu string jsou definovány i operátory <, >, <= a >=. Ovšem pozor, nejde o abecední porovnávání, ale o tzv. lexikografické porovnávání podle kódových čísel znaků; o tom si povíme později. z Operátor += umožňuje připojit k řetězci na konec nový znak nebo celý řetězec. z Operátory << a >> slouží k výstupu, resp. ke vstupu řetězců. Chceme-li v programu zapsat řetězcovou konstantu typu string, uzavřeme potřebnou posloupnost znaků do uvozovek a za uzavírací uvozovky připojíme malé s. To znamená, že např. zápisem auto pozdrav = "Nazdar, lidi"s;

jsme deklarovali proměnnou typu string.

Poznámka Standardní knihovna jazyka C++ ve skutečnosti obsahuje šablonu, která se nazývá basic_string. Tato šablona má parametr, který určuje typ, z něhož chceme řetězce vytvářet. Pro typ řetězců složených ze znaků typu char, tedy pro basic_string<char>, je v knihovně zaveden alias string; pro typ řetězců složených ze znaků typu wchar_t, tedy pro basic_string<wchar_t>, je v knihovně zaveden alias wstring. (O deklaraci aliasu, tedy alternativního jména pro datový typ, jsme hovořili v oddílu 5.9.)


99

Pole

7.6

Vstup pomocí cyklu

Nyní už můžeme naprogramovat elegantnější podobu funkce zadost(). Nejprve si ale deklarujeme pomocné pole string nazev[] = {"Den"s, "Mesic"s, "Rok"s};

do něhož uložíme jména složek data. Pak už můžeme napsat void zadost(int datum[]) { cout << "Zadej prosím datum." << endl; for(int i = 0; i < 3; i++) { cout << nazev[i] << ": "; cin >> datum[i]; } }

Tato podoba funkce zadost() jistě nevyžaduje komentáře. Zdrojový kód současné podoby našeho programu najdete mezi soubory ke stažení v adresáři 07\02. Jestliže jste si pozorně prohlédli zdrojový kód, který jsme zatím napsali, jistě vám neušlo, že jsme se zase jednou prohřešili proti pravidlům, která jsme si řekli v předešlých kapitolách: program obsahuje magická čísla 3, 12 a 13. Odstraníme je v následujícím oddílu, kde se zároveň seznámíme s výčtovými typy.

7.7

Výčtový typ

Náš program, jak jsme ho zatím napsali, není v některých místech příliš srozumitelný a nemohou za to jen magická čísla, o nichž jsme se zmínili na konci předchozího oddílu. Podívejme se na zápis int vysledek = pocet_dnu_do_zacatku[datum[1]] + datum[0];

v těle funkce cislo_dne. Co znamená např. datum[1]? Jistě by bylo srozumitelnější, kdybychom mohli místo toho napsat mesic, nebo alespoň datum[mesic]. První varianta, psát jen mesic, by znamenala použít pro reprezentaci data tři nezávislé proměnné, ale pak bychom složky data nemohli zpracovávat v cyklu. Abychom mohli použít druhou variantu, používat zápis, jako je datum[mesic], potřebujeme tři pojmenované konstanty. Mohli bychom je deklarovat tak, jak jsme si to ukázali v oddílu 4.12. Zde si však ukážeme jinou možnost, založenou na tzv. výčtových typech (enum type). Nejprve si o nich krátce povíme, pak je použijeme k úpravě našeho programu. Výčtový typ představuje zvláštní případ celočíselného typu a je založen na sadě pojmenovaných konstant. Jeho deklaraci lze zjednodušeně popsat následujícím schématem: enum jméno { seznam-konstant } ; Deklarace výčtového typu začíná klíčovým slovem enum, za kterým následuje jméno deklarovaného typu a pak ve složených závorkách seznam konstant. V nejjednodušší podobě to jsou identifikátory oddělené čárkou. Například výčtový typ pro reprezentaci jednotek času, které v našem programu potřebujeme, můžeme deklarovat zápisem enum jednotka {den, mesic, rok};


100

Začínáme programovat v jazyku C++

Potom bude platit, že den představuje konstantu s hodnotou 0, mesic konstantu s hodnotou 1 a rok konstantu s hodnotou 2. Přesněji, první z konstant představuje hodnotu 0 a každá další pak hodnotu o 1 vyšší než konstanta, která jí v deklaraci výčtového typu bezprostředně předchází. Jestliže nám takovéto hodnoty z nějakého důvodu nevyhovují nebo jestliže chceme, aby byly na první pohled zřejmé, můžeme hodnoty konstant v deklaraci výčtového typu předepsat – například takto: enum jednotka {den = 1, mesic = 5, rok = 42};

Proměnnou výčtového typu deklarujeme podobně jako proměnnou jakéhokoli nám už známého typu. Například deklarací jednotka x = den;

jsme zavedli proměnnou typu jednotka, která má počáteční hodnotu den. Už jsme si řekli, že výčtové typy jsou zvláštním případem celočíselných typů. Platí pro ně následující pravidla: z Hodnotu výčtového typu můžeme použít kdekoli, kde program očekává celé číslo. z Na druhé straně na místě, kde program očekává hodnotu jistého výčtového typu, smíme použít jen hodnotu tohoto typu. To znamená, že např. proměnné x typu jednotka můžeme přiřadit pouze hodnotu typu jednotka. Poznamenejme, že deklarace výčtových typů zpravidla umísťujeme do hlavičkových souborů. Nyní se už můžeme pustit do úpravy našeho programu. Deklarujeme v něm výčtový typ jednotka, jehož konstanty budou představovat hodnoty 0, 1 a 2 – to jsme viděli výše. Pak deklarujeme konstanty const int POCET_MESICU = 12; const int POCET_SLOZEK = rok + 1;

Konstanta POCET_MESICU nepotřebuje komentáře; konstanta POCET_SLOZEK vyjadřuje počet složek data, tedy počet prvků pole datum. Deklarace polí pocet_dnu_v_mesici a pocet_dnu_do_zacatku upravíme následovně, const int pocet_dnu_v_mesici[POCET_MESICU + 1] = { /* … */ }; int pocet_dnu_do_zacatku[POCET_MESICU + 1]{};

Inicializaci prvního z polí jsme zde pro stručnost nahradili komentářem. Funkci cislo_ dne() přepíšeme do tvaru int cislo_dne(int datum[]) { int vysledek = pocet_dnu_do_zacatku[datum[mesic]] + datum[den]; if(prestupny(datum[rok])) { vysledek++; } return vysledek; }

Ukázka elektronické knihy


Turn static files into dynamic content formats.

Create a flipbook
Začínáme programovat v jazyku C++ (Ukázka, strana 99) by Kosmas-CZ - Issuu