8. díl - Pole v C++
C a C++ C++ Základní konstrukce C++ Pole v C++


V minulé lekci, Cykly v C++ (while, do while), jsme si ukázali další typy cyklů a naučili
se používat příkazy break
a continue
. Dnes si v
C++ tutoriálu představíme datovou strukturu pole a vyzkoušíme si, co
všechno umí.
Pole
Představte si, že si chcete uložit nějaké údaje o více prvcích.
Např. chcete v paměti uchovávat 10 čísel, políčka šachovnice nebo jména
50ti uživatelů. Asi vám dojde, že v programování bude nějaká lepší
cesta, než začít "bušit" proměnné s názvy uzivatel1, uzivatel2... až
uzivatel50. Nehledě na to, že jich může být třeba 1000. A jak by se v tom
potom hledalo? Brrr, takle ne
Pokud potřebujeme uchovávat větší množství proměnných stejného typu, můžeme použít pole. Můžeme si ho představit jako řadu přihrádek, kde v každé máme uložený jeden prvek. Přihrádky jsou očíslované tzv. indexy, první má index 0.

(Na obrázku je vidět pole osmi čísel)
Programovací jazyky se velmi liší v tom, jak s polem pracují. V některých jazycích (zejména kompilovaných) není možné za běhu programu vytvořit pole s dynamickou velikostí (např. mu dát velikost dle nějaké proměnné). Pole se zde musí deklarovat s konstantní velikostí přímo ve zdrojovém kódu. Lze to obejít pointery a vlastními datovými strukturami. Naopak některé modernější interpretované jazyky nebo jazyky s virtuálním strojem umožňují nejen deklarovat pole s libovolnou velikostí, ale dokonce tuto velikost na již existujícím poli měnit (např. PHP). C++ je jazyk čistě kompilovaný, u pole tedy budeme vždy velikostně omezeni.
Možná vás napadá, proč se tu zabýváme s polem, když má evidentně mnoho omezení a existují lepší datové struktury. Odpověď je prostá: pole je totiž jednoduché. Nemyslím pro nás na pochopení (to také), ale zejména pro počítač. Rychle se s ním pracuje, protože prvky jsou v paměti jednoduše uloženy za sebou, zabírají všechny stejně místa a rychle se k nim přistupuje. Je to klíčová struktura. Pro hromadnou manipulaci s prvky pole se poté používají cykly.
Pole deklarujeme pomocí hranatých závorek, ve kterých uvedeme jeho velikost. Před název proměnné nezapomene uvést datový typ jeho prvků, zde celá čísla:
int pole[16];
pole je samozřejmě název naší proměnné.
Velikost pole je pevně zadaná číslem ve zdrojovém kódu. Schválně si zkuste místo čísla použít proměnnou. Visual Studio to označí za chybu.
Pokud nám pevná velikost pole stačí, ale chceme jeho velikost zadat proměnnou (např. abychom ji pak použili v podmínce v cyklu), musíme použít tzv. konstantu. To je proměnná, jejíž hodnotu nelze měnit. Vytváří se téměř stejně jako běžné proměnné, jen před datový typ napíšeme klíčové slovo const:
const int delkaPole = 24;
int pole[delkaPole];
Ohledně změny délky jsme si sice za běhu programu nepomohli, nicméně, když si jako programátoři rozmyslíme, že chceme zadat napevno jiný počet prvků, změní se konstanta na všech místech v programu. Bez konstant, kdybychom pole poté vypisovali cykly, mohli bychom např. zapomenou změnit počet prvků i tam a z pole vyjet nebo jej nevypsat celé.
Často potřebujeme délku pole zadat pomocí obyčejné proměnné. Takové pole musíme založit tzv. dynamicky, což se naučíme v navazujícím C++ kurzu. Probírat tuto problematiku hned v úvodním kurzu by určitě nebyl dobrý nápad.
K prvkům pole přistupujeme přes hranatou závorku. Pojďme na první index (tedy index 0) uložit číslo 1.
const int delkaPole = 24;
int pole[delkaPole];
pole[0] = 1;
Plnit pole takto ručně by bylo příliš pracné, použijeme cyklus a
naplníme si pole čísly od 1 do 10. K naplnění použijeme for
cyklus:
const int delkaPole = 10;
int pole[delkaPole];
for (int i = 0; i < delkaPole; i++)
pole[i] = i + 1;
Všimněte si, že délku pole máme opět uloženou v konstantě.
Pozn.: Nikdy se nesnažte přistupovat k prvkům za koncem pole (např k 20. prvku v poli o 10 prvcích). V lepším případě dostanete nedefinovaný výsledek (hodnoty, co byly zrovna náhodou uloženy v paměti), v tom horším případě program spadne.
Abychom pole vypsali, můžeme za předchozí kód připsat:
{CPP_CONSOLE}
const int delkaPole = 10;
int pole[delkaPole];
for (int i = 0; i < delkaPole; i++)
pole[i] = i + 1;
for (int i = 0; i < delkaPole; i++)
cout << pole[i] << ' ';
{/CPP_CONSOLE}
Naplnit pole hodnotami můžeme ještě jedním způsobem. Pokud známe jeho prvky předem, můžeme využít následující syntaxi:
int pole[5] = {1, 2, 3, 4, 5};
Číslo v hranatých závorkách lze vynechat, délka pole se poté určí podle počtu prvků ve složených závorkách. Na druhou stranu můžeme v hranatých závorkách uvést hodnotu větší než počet prvků ve složených závorkách. Pole poté nebude mít všechny prvky nastavené.
Funkce pro práci s poli
Mnoho užitečných funkcí pro práci s poli můžeme najít v souboru "algorithm". Některé z nich si tu ukážeme (nesmíme zapomenout umístit #include <algorithm> na začátek souboru).
find()
Funkce find()
nám vrací tzv. ukazatel na první výskyt
hodnoty, kterou jsme jí předali. S ukazateli se teprve setkáme, ale abychom
mohli hledání v poli používat již nyní, naučíme se funkci volat již
teď. Pole je vnitřně ukazatel, který ukazuje na určité místo v paměti,
kde pole začíná (např. může ukazovat na adresu 100). Funkce
find()
nám vrátí ukazatel na místo v paměti, kde je prvek,
který hledáme (např. na adresu 120). Ukazatel deklarujeme pomocí
hvězdičky. Pokud od této adresy odečteme adresu začátku pole, získáme s
těmito čísly hodnotu 20, což je pozice prvku (prvek byl 20 pozic od
začátku pole). Pokud vás to zmátlo, používejte funkci zatím pouze
intuitivně, s ukazateli se ještě bohatě setkáme dále v kurzu a vše si
velmi podrobně vysvětlíme. Byla by ovšem škoda psát si hledací funkci
pokaždé znovu, když ji můžeme použít již nyní.
Pojďme si vše ukázat na příkladu a nechme si najít pozici hodnoty 7 v poli několika čísel:
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
const int delkaPole = 5;
int pole[delkaPole] = { 1, 7, 3, 4, 10 };
int hledanyPrvek = 7;
int *i = find(pole, pole + delkaPole, hledanyPrvek);
int pozice = i - pole;
if (pozice < delkaPole)
cout << "Prvek " << hledanyPrvek << " nalezen na pozici: " << pozice << "." << endl;
else
cout << "Prvek nenalezen." << endl;
cin.get();
return 0;
}
count()
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
const int delkaPole = 6;
int pole[delkaPole] = { 1, 6, 9, 2, 6, 3 };
int c = count(pole, pole + delkaPole, 6);
cout << c; // c = 2
cin.get();
return 0;
}
Funkce count()
nám spočítá, kolikrát se v poli vyskytuje
předaná hodnota - v ukázce 6.
copy()
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
const int delkaPole = 5;
int pole[delkaPole] = { 1, 2, 3, 4, 5 };
int pole2[delkaPole] = { 0, 0, 0, 0, 0 };
copy(pole, pole + delkaPole, pole2);
// pole = { 1, 2, 3, 4, 5 }, pole2 = { 1, 2, 3, 4, 5 }
for (int i = 0; i < delkaPole; i++)
{
cout << pole[i] << "->" << pole2[i] << " ";
}
cin.get();
return 0;
}
Funkce copy()
zkopíruje obsah jednoho pole do druhého.
Pozn.: druhé pole musí být stejně dlouhé jako první pole, nebo delší.
max_element()
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
const int delkaPole = 5;
int pole[delkaPole] = { 2, 1, 4, 5, 3 };
int *i = max_element(pole, pole + delkaPole);
cout << *i; // i = pole + 3, *i = 5
cin.get();
return 0;
}
Funkce max_element()
vrací ukazatel na největší hodnotu v
poli. Hodnoty porovnává pomocí operátoru <. Pokud se nejvyšší hodnota
vyskytuje v poli několikrát, vrácený ukazatel bude ukazovat na její první
výskyt. Pozici získáme stejně jako u příkladu s find().
min_element()
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
const int delkaPole = 5;
int pole[delkaPole] = { 2, 1, 4, 5, 3 };
int *i = min_element(pole, pole + delkaPole);
cout << *i; // i = pole + 1, *i = 1
cin.get();
return 0;
}
Funkce min_element()
je obdoba předchozí funkce s jediným
rozdílem - vrací ukazatel na nejnižší hodnotu v poli.
Pozici získáme stejně jako u příkladu s find().
sort()
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
const int delkaPole = 5;
int pole[delkaPole] = { 2, 1, 4, 5, 3 };
sort(pole, pole + delkaPole);
// pole = { 1, 2, 3, 4, 5 }
for (int i = 0; i < delkaPole; i++)
{
cout << pole[i] << " ";
}
cin.get();
return 0;
}
Sort() vzestupně seřadí prvky v poli (pomocí operátoru < ).
fill()
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
const int delkaPole = 5;
int pole[delkaPole] = { 1, 2, 3, 4, 5 };
fill(pole, pole + delkaPole, 5);
// pole = { 5, 5, 5, 5, 5 }
for (int i = 0; i < delkaPole; i++)
{
cout << pole[i] << " ";
}
cin.get();
return 0;
}
Funkce fill()
naplní pole zadanou hodnotou.
reverse()
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
const int delkaPole = 5;
int pole[delkaPole] = { 1, 2, 3, 4, 5 };
reverse(pole, pole + delkaPole);
// pole = { 5, 4, 3, 2, 1 }
for (int i = 0; i < delkaPole; i++)
{
cout << pole[i] << " ";
}
cin.get();
return 0;
}
Funkce reverse()
"převrátí" obsah pole. To znamená, že jeho
hodnoty budou pozpátku.
random_shuffle()
#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;
int main(void)
{
srand(unsigned(time(0))); // inicializuje generátor náhodných čísel
const int delkaPole = 5;
int pole[delkaPole] = { 1, 2, 3, 4, 5 };
random_shuffle(pole, pole + delkaPole);
// např. pole = { 3, 1, 5, 2, 4 }
for (int i = 0; i < delkaPole; i++)
{
cout << pole[i] << " ";
}
cin.get();
// Prosím, pamatujte, že pokud používáte náš online kompiler, výsledky jsou
// cachované a zůstávají tedy stejné po několik dní. Pro vynucení nové kompilace
// a tedy vygenerování nových náhodných čísel je třeba kód upravit, stačí upravit
// i jen komentář.
return 0;
}
Funkce random_shuffle()
náhodně přehází prvky v poli.
To by pro dnešek stačilo, můžete si s polem hrát. V příští lekci, Řetězce v jazyce C++, se začneme věnovat práci s textem v C++.
Komentáře


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