Office week Slevový týden - Květen
Pouze tento týden sleva až 80 % na e-learning týkající se MS Office
30 % bodů zdarma na online výuku díky naší Slevové akci!

8. diel - Poľa v C #

V minulej lekcii kurzu, Ošetrenie užívateľských vstupov , sme si ukázali ošetrenie užívateľských vstupov. 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é uzivatel1 , uzivatel2 ... až uzivatel50 . Nehľadiac na to, že ich môže byť potrebné 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, tento problém nám rieši poľa. 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 .

štruktúra poľa

(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ä starších, kompilovaných) nebolo možné za behu programu vytvoriť pole s dynamickou veľkosťou (napr. Mu dať veľkosť podľa nejaké premenné). Pole sa muselo deklarovať s konštantnou veľkosťou priamo v zdrojovom kóde. Toto sa obchádzalo tzv. Pointer a vlastnými dátovými štruktúrami, čo často viedlo k chybám pri manuálnej správe pamäte a nestabilite programu (napr. V C ++ ). Naopak niektoré interpretované jazyky 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 ). My vieme, že C # je virtuálny stroj, teda čosi medzi kompilerem a interpretom. Preto môžeme pole založiť s veľkosťou, ktorú dynamicky zadáme až za behu programu, ale veľkosť existujúceho poľa modifikovať nemôžeme. Možno to samozrejme obísť alebo použiť iné dátové štruktúry, ale k tomu sa dostaneme.

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 C #. 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. Mnoho vnútorných funkčnosťou v .NET preto nejako pracuje s poľom alebo poľa vracia. Je to kľúčová štruktúra.

Pre hromadnú manipuláciu s prvkami poľa sa používajú cykly.

Pole deklarujeme pomocou hranatých zátvoriek:

int[] pole;

Výraz pole je samozrejme názov našej premennej. Teraz sme však len deklarovali, že v premennej bude pole int ov. Teraz ho musíme založiť, aby sme ho mohli používať. Použijeme na to kľúčové slovo new , ktoré na našej úrovni vedomostí nie sme zatiaľ schopní podrobne vysvetliť. Uspokojme sa s tým, že je to kvôli tomu, že je pole referenčná dátový typ (môžeme chápať ako zložitejšie typ):

int[] pole = new int[10];

Teraz máme v premennej pole poľa veľkosti desiatich int ov.

K prvkom poľa potom pristupujeme cez hranatú zátvorku, poďme na prvý index (teda index 0 ) uložiť číslo 1 .

int[] pole = new int[10];
pole[0] = 1;

Plniť pole takhle 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:

int[] pole = new int[10];
pole[0] = 1;
for (int i = 0; i < 10; i++)
    pole[i] = i + 1;

Aby sme pole vypísali, môžeme za predchádzajúci kód pripísať:

for (int i = 0; i < pole.Length; i++)
    Console.Write("{0} ", pole[i]);
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Všimnite si, že pole má vlastnosť Length , kde je uložená jeho dĺžka, teda počet prvkov.

Konzolová aplikácia
1 2 3 4 5 6 7 8 9 10

Môžeme použiť zjednodušenú verziu cyklu pre prácu s kolekciami, známu ako foreach . Ten prejde všetky prvky v poli a jeho dĺžku si zistí sám. Jeho syntax je nasledujúca:

foreach (datovytyp premenna in kolekcia)
{
    // príkazy
}

Cyklus prejde prvky v kolekcii (to je všeobecný názov pre štruktúry, ktoré obsahujú viac prvkov, u nás to bude údaj) postupne od prvého do posledného. Prvok máme v každej iterácii cyklu uložený v danej premennej.

Prepíšme teda náš doterajší program pre foreach . Cyklus foreach nemá riadiace premennú, nie je teda vhodný pre vytvorenie nášho poľa a použijeme ho len pre výpis.

int[] pole = new int[10];
pole[0] = 1;
for (int i = 0; i < 10; i++)
    pole[i] = i + 1;
foreach (int i in pole)
    Console.Write("{0} ", i);
Console.ReadKey();

Výstup programu:

Konzolová aplikácia
1 2 3 4 5 6 7 8 9 10

Pole samozrejme môžeme naplniť ručne a to aj bez toho, aby sme dosadzovali postupne do každého indexu. Použijeme na to zložených zátvoriek a prvky oddeľujeme čiarkou:

string[] simpsonovi = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};

Pole často slúži na ukladanie medzivýsledkov, ktoré sa potom ďalej v programe používajú. Keď potrebujeme nejaký výsledok 10x, tak to nebudeme 10x počítať, ale spočítame to raz a uložíme do poľa, odtiaľ potom výsledok len načítame.

Metódy na triede Array

.NET nám poskytuje triedu Array , ktorá obsahuje pomocné metódy pre prácu s poľami. Poďme sa na ne pozrieť:

Sort ()

Ako už názov napovedá, metóda nám poľa zoradí. Jej jediný parameter je pole, ktoré chceme zoradiť. Je dokonca tak múdra, že pracuje podľa toho, čo máme v poli uložené. Stringy triedi podľa abecedy, čísla podľa veľkosti. Skúsme si zotrieďiť a vypísať našu rodinku Simpson:

string[] simpsonovi = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
Array.Sort(simpsonovi);
foreach (string s in simpsonovi)
    Console.Write("{0} ", s);
Console.ReadKey();

Konzolová aplikácia
Bart Homer Lisa Maggie Marge

Skúste si urobiť polia čísel a vyskúšajte si, že to naozaj funguje aj pre nich.

Reverse ()

Reverse() nám pole otočí (prvý prvok bude ako posledná atď.), Toho môžeme využiť napr. Pre triedenie pospiatky:

string[] simpsonovi = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
Array.Sort(simpsonovi);
Array.Reverse(simpsonovi);
foreach (string s in simpsonovi)
    Console.Write("{0} ", s);
Console.ReadKey();

IndexOf () a lastIndexOf ()

Tieto metódy vráti index prvého alebo posledného nájdeného prvku. V prípade nenájdenia prvku vráti -1 . Každá z metód berie dva parametre, prvým je pole, druhým hľadaný prvok. Umožníme užívateľovi zadať meno Simpsons a povieme mu, na akej pozícii je uložený. Teraz to pre nás nemá hlbší význam, pretože prvok poľa je len string . Bude sa nám to však veľmi hodiť vo chvíli, kedy v poli budeme mať uložené plnohodnotné objekty. Berme to teda ako takú prípravu.

string[] simpsonovi = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
Console.WriteLine("Ahoj zadaj svojho obľúbeného Simpsni (z rodiny Simpson): ");
string simpson = Console.ReadLine();
int pozice = Array.IndexOf(simpsonovi, simpson);
if (pozice >= 0)
    Console.WriteLine("Jo, to je môj {0}. najobľúbenejší Simpson!", pozice + 1);
else
    Console.WriteLine("Hele, toto nie je Simpson!");
Console.ReadKey();

Konzolová aplikácia
Ahoj zadaj svojho obľúbeného Simpsni (z rodiny Simpson):
Homer
Jo, to je môj 1. najobľúbenejší Simpson!

Copy ()

Copy() už podľa názvu skopíruje časť poľa do iného poľa. Prvým parametrom je zdrojové pole, druhým cieľové a tretím počet prvkov, ktorý sa má skopírovať.

Metódy na poli

Trieda Array nie je jedinou možnosťou, ako s poľom manipulovať. Priamo na samotné inštanciu pole (konkrétne premenné) môžeme volať aj veľa metód. Aj keď si spomenieme len niektoré, je ich naozaj veľa. Nebudeme teda robiť príklady, len si ich popíšeme:

Length

Length sme si už spomenuli, vráti dĺžku poľa. Nie je metódou, ale vlastností, nepíšu sa za ňu teda zátvorky () .

Min (), Max (), Average (), Sum ()

Matematické metódy, vracajúci najmenší prvok ( Min() ), najväčší prvok ( Max() ), priemer zo všetkých prvkov ( Average() ) a súčet všetkých prvkov ( Sum() ). Metódy nemajú žiadne parametre.

Concat (), Intersect (), Union ()

Všetky tieto metódy vráti na výstupe nové pole a ako parameter majú druhé pole. Concat() vykoná nám už známu konkatenaci, teda k nášmu poli pripojí druhé pole a takto vzniknuté nové pole vráti. Intersect() vykoná prienik oboch polí, teda zostaví pole s prvkami, ktoré sú obom poliam spoločné. Union() naopak vykoná zjednotenie, funguje teda podobne ako Concat() , len prvky, ktoré boli v oboch poliach, sú v novom poli len raz.

First () a Last ()

Už podľa názvu metódy vráti prvý a posledný prvok, neberú žiadne parametre.

Take () a Skip ()

Obe tieto metódy berú ako parameter počet prvkov. Take() vráti pole s daným počtom prvkov skopírovaných od začiatku pôvodného poľa. Skip() naopak vráti pole bez týchto prvých prvkov.

Contains ()

Metóda vracia true / false podľa toho, či sa prvok, uvedený v parametri metódy, v danom poli nachádzajú.

Reverse ()

Metódu Reverse() poznáme už z triedy Array , pokiaľ ju ale voláme na konkrétnom poli, tak sa prvky v ňom neotočí, ale je vytvorené nové otočené poľa a to je vrátený. Metóda nemá žiadne parametre.

Distinct ()

Distinct() je metóda bez parametrov a zabezpečí, aby bol v poli každý prvok len raz, teda vymaže duplicitné prvky a unikátne pole vráti ako návratovú hodnotu metódy, opäť teda nemodifikuje dané pole.

Mnoho metód nemení priamo naše polia, ale vráti iba polia nové (sú to metódy Concat() , Intersect() , Union() , Reverse() a Distinct() ), v ktorom sú vykonané požadované zmeny. Ak chceme modifikovať pôvodné pole, musíme doň dosadiť. Tieto metódy bohužiaľ z dôvodov, ktoré pochopíme až neskôr, nevracia priamo pole, ale typ IEnumerable . Aby bolo dosadení výsledku späť do poľa možné, musíme ho ešte previesť na pole metódou ToArray() .

int[] cisla = { 1, 2, 3, 3, 3, 5 };
cisla = cisla.Distinct().ToArray();

Premenná dĺžka poľa

Hovorili sme si, že dĺžku poľa môžeme definovať aj za behu programu, poďme si to skúsiť a rovno si vyskúšajme nejakú metódu na poli:

Console.WriteLine("Ahoj, spočítám ti priemer známok. Koľko známok zadáš?");
int pocet = int.Parse(Console.ReadLine());
int[] cisla = new int[pocet];
for (int i = 0; i < pocet; i++)
{
    Console.Write("Zadajte {0}. číslo: ", i + 1);
    cisla[i] = int.Parse(Console.ReadLine());
}
Console.WriteLine("Priemer tvojich známok je: {0}", cisla.Average());
Console.ReadKey();

Konzolová aplikácia
Ahoj, spočítám ti priemer známok. Koľko známok zadáš?
5
Zadajte 1. číslo: 1
Zadajte 2. číslo: 2
Zadajte 3. číslo: 2
Zadajte 4. číslo: 3
Zadajte 5. číslo: 5
Priemer tvojich známok je: 2,6

Tento príklad by išiel samozrejme napísať aj bez použitia poľa, ale čo keby sme chceli spočítať napr. Medián? Alebo napr. Vypísať zadané čísla pospiatky? To už by bez poľa nešlo. Takto máme k dispozícii v poli pôvodnej hodnoty a môžeme s nimi neobmedzene a jednoducho pracovať.

To by pre dnešok stačilo, môžete si s poľom hrať. V budúcej lekcii, Riešené úlohy k 7.-8. lekciu C # .NET , na vás čaká prekvapenie ;-)

V nasledujúcom cvičení, Riešené úlohy k 7.-8. lekciu C # .NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Stiahnuť

Stiahnuté 1140x (141.34 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

 

Článok pre vás napísal David Čápka
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sa informačné technológie naučil na Unicorn College - prestížnej súkromnej vysokej škole IT a ekonómie.
Predchádzajúci článok
Ošetrenie užívateľských vstupov
Všetky články v sekcii
Základné konštrukcie jazyka C #
Miniatúra
Nasledujúci článok
Riešené úlohy k 7.-8. lekciu C # .NET
Aktivity (2)

 

 

Komentáre

Avatar
Zdeněk Srnský:3.9.2019 15:50

Ahoj , Velice se mi líbí tyto stránky, ale ať se snažím jak chci nejsem schopen se nic naučit z česky psaného textu. Potom se mi motá 2x tolik výrazů které k sobě neumím přiřadit. Vím co je Array a jak s ním pracovat, ale jak někdo řekne pole tak jsem úplně vedle.

 
Odpovedať
3.9.2019 15:50
Avatar
Odpovedať
3.9.2019 18:31
Kdo je připraven, toho zaskočí něco jiného
Avatar
Jiří Dvořák:19.9.2019 0:32

Zdravím,
zkouším si dělat pole a napadlo mě... když mám pole o 5ti hodnotách které zadá uživatel:

int[] pole = new int [5];
            Console.WriteLine("1.č");
            pole[0] = int.Parse(Console.ReadLine());
            Console.WriteLine("2.č");
            pole[1] = int.Parse(Console.ReadLine());
            Console.WriteLine("3.č");
            pole[2] = int.Parse(Console.ReadLine());
            Console.WriteLine("4.č");
            pole[3] = int.Parse(Console.ReadLine());
            Console.WriteLine("5.č");
            pole[4] = int.Parse(Console.ReadLine());

            Console.ReadKey();

jak vypíši např. třeba jen 2. a 4. hodnotu... kupříkladu...

poradí někdo? :)

Díky za odpovědi! :)

 
Odpovedať
19.9.2019 0:32
Avatar
Odpovedá na Jiří Dvořák
Jiří Dvořák:19.9.2019 0:37

tak nakonec sem na to přišel sám :D

int[] pole = new int [5];
            Console.WriteLine("1.č");
            pole[0] = int.Parse(Console.ReadLine());
            Console.WriteLine("2.č");
            pole[1] = int.Parse(Console.ReadLine());
            Console.WriteLine("3.č");
            pole[2] = int.Parse(Console.ReadLine());
            Console.WriteLine("4.č");
            pole[3] = int.Parse(Console.ReadLine());
            Console.WriteLine("5.č");
            pole[4] = int.Parse(Console.ReadLine());

            Console.Write(pole[2] + " ");
            Console.Write(pole[0] + " ");

            Console.ReadKey();
 
Odpovedať
19.9.2019 0:37
Avatar
Rebeka Bulkova:24.11.2019 17:03

Ahoj ahoj, čo sa týka toho average príkladu.... ide mi to iba ak dám using System.linq; ale vtedy mi neberie console. V čom je chyba? Ďakujem :)

 
Odpovedať
24.11.2019 17:03
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!
Avatar
Marek Vajčner:8. marca 13:22

Opět velký dík za další lekci. Je to stále zajímavější. Jdu se vrhnout na ta cvičení. Jsem zvědav jak mi to půjde.

 
Odpovedať
8. marca 13:22
Avatar
David Holohlavský:8. marca 21:44

Díky za článek. ;-)

 
Odpovedať
8. marca 21:44
Avatar
Josef Theuer
Člen
Avatar
Josef Theuer:13. marca 0:24

Jen taková malá technická, asi bych místo výzvy
Console.Write("Za­dejte {0}. číslo: ", i + 1);
podšoupnul
Console.Write("Za­dejte {0}. známku: ", i + 1);
když už je to o průměru ze známek
Jinak chválím , celý tutoriál, výborný zdroj pro nějaké získání základních znalostí.

Editované 13. marca 0:26
Odpovedať
13. marca 0:24
No pain no gain
Avatar
Vlkodlak90
Člen
Avatar
Odpovedá na Rebeka Bulkova
Vlkodlak90:3. apríla 0:56

Ahoj rovnaký problém som mal aj ja a vyššie som našiel len riešenie a rovnako ako teba aj mňa napadlo nahradiť pôvodné týmto.

using System.Linq;

Správne to však len dopíšeš pod to viď. nižšie, ( dokonca naraz vieš využívať viaceré "systémy" )

using System;
using System.Linq;
 
Odpovedať
3. apríla 0:56
Avatar
Vlasta Řenčová:21. mája 15:06

Díky metodě ToArray() jsem si konečně zapamatovala, že pole je Array a ne Field (vím, že to je něco jiného...) :D

Editované 21. mája 15:06
 
Odpovedať
21. mája 15:06
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!