V předchozím díle jsme se naučili používat podmínky, probrali jsme si některé operátory a také jsme si ukázali, jak se používá příkaz switch. V dnešním díle nás čekají pole. Povíme si tedy co to vlastně pole je, jak jej definovat atd. Musím podotknout, že ve spoustě případů se práce s polem pojí s použitím cyklů, které zatím neumíme a budou obsahem příštího dílu. Proto se pole vyskytnou i v následujícím díle, čímž se vlastně naučíme jak cykly, tak si též zopakujeme do jisté míry dnešní díl.
Co je to pole
Řekneme-li to jednoduše, je to proměnná, do které můžeme uložit více hodnot stejného typu. Například tedy 20 hodnot typu int, 40 hodnot typu bool apod. Odborněji můžeme o poli mluvit jako o určité kolekci míst v úložišti dat, kde každé místo v úložišti označujeme jako prvek nebo element pole. Pole deklarujeme zadáním jeho typu (bool, char, double apod.), za nímž následuje název pole a index neboli subskript. Index uzavíráme do hranatých závorek a říkáme jím, kolik prvků bude pole obsahovat. Viz ukázka:
int mojePole[20];
V ukázce je deklarováno pole o dvaceti prvcích, z nichž každý bude typu int. Kompilátor si tedy v paměti vyhradí dostatek paměti pro uchování všech dvaceti prvků. Vzhledem k tomu, že v našem případě je prvků dvacet a jsou typu int, bude v paměti vyhrazeno 20 x 4B (velikost int jsou 4 bajty), čili celkem 80 bajtů.
Prvky pole
Prvky pole se číslují od nuly, proto k prvnímu prvku přistoupíme takto:
// Do prvního prvku v poli přiřazujeme hodnotu 5
mojePole[0] = 5;
Stejným způsobem můžeme i ostatním prvkům přiřadit hodnoty. Naše pole má velikost dvacet prvků, nezapomínejte však, že první prvek je vlastně nultý, proto poslední prvek nemá index 20, ale 19. Jde o poměrně častou začátečnickou chybu, proto si na ní dávejte pozor.
Co se stane, když zapíšeme hodnotu za konec pole?
V případě, že zapisujeme hodnotu do nějakého prvku v poli, kompilátor si spočítá, kam se má hodnota uložit a to podle velikosti jednotlivých prvků a indexu. Chceme-li tedy například zapsat hodnotu na mojePole[20], což je jednadvacátý prvek, kompilátor znásobí odsazení (20) velikostí jednoho prvku (v našem případě 4) a pak se posune o zjištěný počet bajtů (80) od začátku pole a hodnotu zapíše na danou pozici.
Zjednodušeně řečeno, kompilátoru je jedno, jestli Vámi zadaný prvek existuje či nikoliv. Spočítá pouze jak daleko za první prvek se má posunout a pak přepíše cokoliv, co se vyskytuje na daném místě. Může se jednat téměř o jakákoliv data, proto zápis za konec pole může mít nepředvídatelné následky. Proto ještě jednou zdůrazňuji, dávejte si na to opravdu velký pozor.
Inicializování polí
Stejně jako obyčejné proměnné, tak i pole lze inicializovat již při deklaraci. Za název pole napíšete rovnítko a do složených závorek uvedete seznam hodnot, oddělených čárkami. Například takto:
int malePole[5] = {3, 5, 2, 1, 0};
V ukázce jsme vytvořili pole o pěti prvcích, kde první prvek má hodnotu 3, druhý 5, třetí 2 atd. Je to tedy stejné, jako tento zápis:
int malePole[5];
malePole[0] = 3;
malePole[1] = 5;
malePole[2] = 2;
malePole[3] = 1;
malePole[4] = 0;
Program - průměr známek ve škole
Nyní si napíšeme jednoduchý program na výpočet průměru několika čísel. Předem podotýkám, že program nebude napsán tak, jak by ho napsal asi každý programátor, protože nám půjde pouze o porozumění práci s polem. V dalším díle, kde se naučíme cykly, si tento program napíšeme znovu, ale mnohem jednodušeji. Rozdíl bude určitě patrný.
Chceme tedy napsat program, do kterého uživatel zadá pět čísel, řekněme, že to budou například známky, které dostal ve škole a program mu vypočítá jeho průměr. Všechny známky si uložíme do pole s názvem znamky a pak vypočítáme průměr. Asi nemusím připomínat, že průměr vypočteme jako součet jednotlivých známek vydělený celkovým počtem známek.
#include <iostream>
using namespace std;
int main()
{
int znamky[5];
cout << "Zadej prvni znamku: ";
cin >> znamky[0];
cout << "Zadej druhou znamku: ";
cin >> znamky[1];
cout << "Zadej treti znamku: ";
cin >> znamky[2];
cout << "Zadej ctvrtou znamku: ";
cin >> znamky[3];
cout << "Zadej patou znamku: ";
cin >> znamky[4];
int soucet = znamky[0] + znamky[1] + znamky[2] + znamky[3] + znamky[4];
double prumer = soucet / 5;
cout << "Tvuj prumer je " << prumer << ".\n";
return 0;
}
Na začátku funkce main deklarujeme pole o pěti prvcích, přičemž každý prvek je typu int. Poté postupně ukládáme hodnoty, které uživatel zadá, do našeho pole. Ještě jednou připomínám, naše pole má indexy 0, 1, 2, 3 a 4. Dále jsme si vytvořili proměnnou soucet, do které uložíme součet všech známek. Nakonec vypočteme průměr, který uložíme do proměnné prumer. Tato proměnná je typu double, neboť průměr nemusí být vždy celé číslo.
Za domácí úkol si zkuste napsat tentýž program, jen s tím rozdílem, že známek nebude pět, ale tisíc. Předpokládám, že do toho se asi nikomu chtít nebude, proto vězte, že jsem si dělal legraci. Museli byste totiž napsat poměrně dlouhý kód, kde by se vyskytovalo samé cout a cin. Program by samozřejmě fungoval, kompilátor by si s tím poradil bez nejmenších problémů, ale psát by se to nechtělo nikomu. To, že by uživatel musel zadávat tisíc hodnot je věc druhá.
V dalším díle si tento program napíšeme znovu – jinak, lépe a pohodlněji. Funkčnost bude naprosto stejná, námaha však minimální a to i bez ohledu na to, z kolika známek budeme průměr počítat.
Co se týče polí, rozhodně jsme si v tomto díle neřekli vše. Nezmínili jsme se o vícerozměrných polích, polích ukazatelů, dynamické alokaci paměti apod. Je to totiž o něco málo složitější, proto tomu bude věnován jeden z pozdějších dílů. To, co jsme se ale dověděli dnes nám bude prozatím stačit.
V příštím díle se podíváme na cykly (někdy též smyčky), které poté využijeme při práci s poli. Poté už budeme schopni napsat i některé algoritmy pro třídění nebo vyhledávání prvků v poli. O tom by měla být řeč v devátém díle.