8. diel - Poľa v C ++
V predchádzajúcom cvičení, Riešené úlohy k 6.-7. lekciu C ++, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V minulej lekcii, Riešené úlohy k 6.-7. lekciu C ++ , sme si ukázali ďalšie typy cyklov a
naučili sa používať príkazy break
a continue
.
Dnes si v C ++ tutoriálu predstavíme dátovú štruktúru poľa a vyskúšame
si, čo všetko vie.
Poľa
Predstavte si, že si chcete uložiť nejaké údaje o viac prvkoch. Napr.
chcete v pamäti uchovávať 10
čísel, políčka šachovnice
alebo mena 50tich užívateľov. Asi vám dôjde, že v programovaní bude
nejaká lepšia cesta, než začať "búšiť" premenné s názvami
uzivatel 1
, uzivatel 2
... až
uzivatel 50
. Nehľadiac na to, že ich môže byť
napríklad 1000
. A ako by sa v tom potom hľadalo? Brrr, takze nie
Ak potrebujeme uchovávať väčšie množstvo premenných rovnakého
typu, môžeme použiť polia. Môžeme si ho predstaviť ako rad
priehradiek, kde v každej máme uložený jeden prvok. Priehradky sú
očíslované tzv. Indexy, prvý má index 0
.
(Na obrázku je vidieť pole ôsmich čísiel) Programovacie jazyky sa veľmi líšia v tom, ako s poľom pracujú. V niektorých jazykoch (najmä kompilovaných) nie je možné za behu programu vytvoriť pole s dynamickou veľkosťou (napr. Mu dať veľkosť podľa nejaké premenné). Pole sa tu musí deklarovať s konštantnou veľkosťou priamo v zdrojovom kóde. Možno to obísť Pointer a vlastnými dátovými štruktúrami. Naopak niektoré modernejšie interpretované jazyky jazyky s virtuálnym strojom umožňujú nielen deklarovať pole s ľubovoľnou veľkosťou, ale dokonca túto veľkosť na už existujúcom poli meniť (napr. PHP). C ++ je jazyk čisto kompilovaný, u poľa teda budeme vždy veľkostne obmedzeni.
Možno vás napadá, prečo sa tu zaoberáme s poľom, keď má evidentne veľa obmedzení a existujú lepšie dátové štruktúry. Odpoveď je prostá: poľa je totiž jednoduché. Nemyslím pre nás na pochopenie (to tiež), ale najmä pre počítač. Rýchlo sa s ním pracuje, pretože prvky sú v pamäti jednoducho uložené za sebou, zaberajú všetky rovnako miesta a rýchlo sa k nim pristupuje. Je to kľúčová štruktúra. Pre hromadnú manipuláciu s prvkami poľa sa potom používajú cykly.
Pole deklarujeme pomocou hranatých zátvoriek, v ktorých uvedieme jeho veľkosť. Pred názov premennej nezabudneme uviesť dátový typ jeho prvkov, tu celé čísla:
int pole[16];
pole
je samozrejme názov našej premennej.
Veľkosť poľa je pevne zadaná číslom v zdrojovom kóde. Schválne si skúste namiesto čísla použiť premennú. Visual Studio to označia za chybu.
Ak nám pevná veľkosť poľa stačí, ale chceme jeho veľkosť zadať
premennú (napr. Aby sme ju potom použili v podmienke v cykle), musíme
použiť tzv. Konštantu. To je premenná, ktorej hodnotu nemožno meniť.
Vytvára sa takmer rovnako ako bežné premenné, len pred dátový typ
napíšeme kľúčové slovo const
:
const int delkaPole = 24; int pole[delkaPole];
Ohľadom zmeny dĺžky sme si síce za behu programu nepomohli, však, keď si ako programátori rozmyslíme, že chceme zadať napevno iný počet prvkov, zmení sa konštanta na všetkých miestach v programe. Bez konštánt, keby sme pole potom vypisovali cykly, mohli by sme napr. Zabudnú zmeniť počet prvkov aj tam az poľa vyjsť alebo ho nevypsat celé.
Často potrebujeme dĺžku poľa zadať pomocou obyčajnej premennej. Takéto pole musíme založiť tzv. Dynamicky, čo sa naučíme v nadväzujúcom C ++ kurzu. Preberať túto problematiku hneď v úvodnom kurze by určite nebol dobrý nápad.
K prvkom poľa pristupujeme cez hranatú zátvorku. Poďme na prvý index
(teda index 0
) uložiť číslo 1
.
const int delkaPole = 24; int pole[delkaPole]; pole[0] = 1;
Plniť poľa takto ručne by bolo príliš pracné, použijeme cyklus a
naplníme si pole číslami od 1
do 10
. K naplneniu
použijeme for
cyklus:
const int delkaPole = 10; int pole[delkaPole]; for (int i = 0; i < delkaPole; i++) pole[i] = i + 1;
Všimnite si, že dĺžku poľa máme opäť uloženú v konštante.
Pozn .: Nikdy sa nesnažte pristupovať k prvkom za koncom poľa
(napr k 20. prvku v poli o 10
prvkoch). V lepšom prípade
dostanete nedefinovaný výsledok (hodnoty, čo boli práve náhodou uložené v
pamäti), v tom horšom prípade program spadne.
Aby sme pole vypísali, môžeme za predchádzajúci kód pripísať:
{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}
Naplniť pole hodnotami môžeme ešte jedným spôsobom. Ak poznáme jeho prvky vopred, môžeme využiť nasledujúcu syntax:
int pole[5] = {1, 2, 3, 4, 5};
Číslo v hranatých zátvorkách možno vynechať, dĺžka poľa sa potom určí podľa počtu prvkov v zložených zátvorkách. Na druhú stranu môžeme v hranatých zátvorkách uviesť hodnotu väčší ako počet prvkov v zložených zátvorkách. Pole potom nebude mať všetky prvky nastavené.
Funkcie pre prácu s poľami
Mnoho užitočných funkcií pre prácu s poľami môžeme nájsť v súbore
algorithm
. Niektoré z nich si tú ukážeme (nesmieme zabudnúť
umiestniť #include <algorithm>
na začiatok súboru).
Find ()
Funkcia find()
nám vracia tzv. Ukazovateľ na prvý výskyt
hodnoty, ktorú sme jej odovzdali. S ukazovateli sa ešte len stretneme, ale aby
sme mohli hľadanie v poli používať už teraz, naučíme sa funkciu volať
už teraz. Pole je vnútorne ukazovateľ, ktorý ukazuje na určité miesto v
pamäti, kde pole začína (napr. Môže ukazovať na adresu 100
).
Funkcia find()
nám vráti ukazovateľ na miesto v pamäti, kde je
prvok, ktorý hľadáme (napr. Na adresu 120
). Ukazovateľ
deklarujeme pomocou hviezdičky. Pokiaľ od tejto adresy odpočítame adresu
začiatku poľa, získame s týmito číslami hodnotu 20
, čo je
pozícia prvku (prvok bol 20
pozícií od začiatku poľa). Ak vás
to zmiatlo, používajte funkciu zatiaľ iba intuitívne, s ukazovateľmi sa
ešte bohato stretneme ďalej v kurze a všetko si veľmi podrobne vysvetlíme.
Bola by však škoda písať si hľadací funkciu zakaždým znova, keď ju
môžeme použiť už teraz.
Poďme si všetko ukázať na príklade a nechajme si nájsť pozíciu
hodnoty 7
v poli niekoľkých čí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 << "Prvok " << hledanyPrvek << " nájdený na pozíciu: " << pozice << "." << endl;
else
cout << "Prvok nenašiel." << 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;
}
Funkcia count()
nám spočíta, koľkokrát sa v poli vyskytuje
odovzdaná hodnota - v ukážke 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;
}
Funkcia copy()
skopíruje obsah jedného poľa do druhého.
Pozn .: druhej poľa musí byť rovnako dlhé ako prvá pole, alebo dlhšie.
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;
}
Funkcia max_element()
vracia ukazovateľ na najväčšiu hodnotu
v poli. Hodnoty porovnáva pomocou operátora <
. Ak sa
najvyššia hodnota vyskytuje v poli niekoľkokrát, vrátený ukazovateľ bude
ukazovať na jej prvý výskyt. Pozíciu získame rovnako ako v príklade 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;
}
Funkcia min_element()
je obdoba predchádzajúcej funkcie s
jediným rozdielom - vracia ukazovateľ na najnižšiu hodnotu
v poli. Pozíciu získame rovnako ako v príklade 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;
}
Funkcia sort()
vzostupne zoradia prvky v poli (pomocou
operátora <
).
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;
}
Funkcia 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;
}
Funkcia reverse()
"prevráti" obsah poľa. To znamená, že jeho
hodnoty budú pospiatky.
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, pamätajte, že ak používate náš online kompiler, výsledky sú
// cachovanie a zostávajú teda rovnaké po niekoľko dní. Pre vynútenie novej kompilácie
// a teda vygenerovanie nových náhodných čísel je potrebné kód upraviť, stačí upraviť
// i len komentár.
return 0;
}
Funkcia random_shuffle()
náhodne přehází prvky v poli.
To by pre dnešok stačilo, môžete si s poľom hrať. V budúcej lekcii, Riešené úlohy k 8. lekcii C ++ , sa začneme venovať práci s textom v C ++.
V nasledujúcom cvičení, Riešené úlohy k 8. lekcii C ++, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.