Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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 - Základné konštrukcie jazyka C # .NET

(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]);

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í.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

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

 

Predchádzajúci článok
Ošetrenie užívateľských vstupov
Všetky články v sekcii
Základné konštrukcie jazyka C # .NET
Preskočiť článok
(neodporúčame)
Riešené úlohy k 7.-8. lekciu C # .NET
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
4 hlasov
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity