6. Přístup k prvkům pole

Pro ilustraci principu procházení prvků pole využijme předchozí příklad deklarace jednorozměrného pole včetně inicializace jeho prvků s odvozením velikosti pole pomocí kompilátoru – viz Kód 1. Jednalo se o deklaraci jednorozměrného pole obsahující celá čísla, včetně vytvoření instance takového pole o 5 prvcích: 7, 5, 2, 4, 9. Instance se jmenovala poctyLidi. 

/*Vytvoření instance pole o 5 prvcích včetně inicializace, kde
*velikost pole je odvozena kompilátorem */
int[] poctyLidi = { 7, 5, 2, 4, 9 };

Kód 1: Příklad deklarace jednorozměrného pole poctyLidi s odvozením velikosti pole, vytvoření instance včetně inicializace

Na obrázku vidíme, co by provedl předchozí kód v paměti - viz Obrázek 1.

Deklarace jednorozměrného pole poctyLidi včetně inicializace

Obrázek 1: Deklarace jednorozměrného pole poctyLidi včetně inicializace

Pro procházení prvků jednorozměrného pole je zapotřebí pouze jeden index, pomocí kterého přistupujeme k jednotlivým prvkům tohoto pole, jak je vidět u jednotlivých prvků pole na obrázku – viz Obrázek 2. První prvek má hodnotu indexu 0, další 1 (o jedna vyšší než předchozí), atd.

Přístup k jednotlivým prvkům pole poctyLidi

Obrázek 2: Přístup k jednotlivým prvkům pole poctyLidi


Ilustrativní příklad PoleLidiVypisPrvku
Program PoleLidiVypisPrvku
  • Popis: Výpis obsahu předposledního prvku jednorozměrného pole obsahující celá čísla
  • Zadání: Vytvořte instanci jednorozměrného celočíselného pole o 5 prvcích: 7, 5, 2, 4, 9. Instance se bude jmenovat poctyLidi. Vypište v metodě Main hodnotu předposledního prvku instance poctyLidi
  • Řešení: Bude postupně probráno v následujícím textu


Pro výpis v konzolové aplikaci jsme použili standardní příkaz WriteLine, kde jsme v závorce zobrazili informaci o pozici prvku (je důležité si uvědomit, že první prvek pole má index 0 a proto index předposledního prvku je 3) – viz Kód 2.
static void Main(string[] args)
{
    /*Vytvoření instance pole o 5 prvcích včetně inicializace, kde
    *velikost pole je odvozena kompilátorem */
    int[] poctyLidi = { 7, 5, 2, 4, 9 };
 
    //Výpis hodnoty předposledního prvku jednorozměrného pole
    Console.WriteLine("Prvek na pozici {0} má hodnotu: {1}", 3, poctyLidi[3]);
 
 
    //Čekání na stisk klávesy -> ukončení programu
    Console.ReadKey();
}

Kód 2: Výpis obsahu předposledního prvku jednorozměrného pole poctyLidi obsahující celá čísla

Na výpisu v konzoli vidíme, že byla vypsána indexu prvku včetně jeho hodnoty – viz Výstup programu - Kód 2.

Prvek na pozici 3 má hodnotu: 4

Výstup programu - Kód 2: Výpis obsahu předposledního prvku jednorozměrného pole poctyLidi obsahující celá čísla


Zkusme si vytvořit program, kde uživatel bude zadávat index prvku sám. Uživatel je tvor lidský, tudíž může udělat chybu. Zkusme pomocí výjimky ošetřit program proti chybě na straně uživatele.


Ilustrativní příklad PoleLidiVypisVyjimka
Program PoleLidiVypisVyjimka
  • Popis: Výpis obsahu prvku jednorozměrného pole obsahujícího celá čísla s testem konverze a ošetřením výjimky
  • Zadání: Vytvořte instanci jednorozměrného celočíselného pole o 5 prvcích: 7, 5, 2, 4, 9. Instance se bude jmenovat poctyLidi. Vypište hodnotu prvku instance poctyLidi, kde index prvku bude načten od uživatele. Pokud uživatel zadá špatný číselný formát indexu, vypište mu varovné hlášení: "Zadal jste špatný formát čísla indexu". Pokud bude index mimo povolené hranice, vypište uživateli text vyvolané výjimky typu IndexOutOfRangeException
  • Řešení: PoleLidiVypisVyjimka_Main


V následujícím výřezu kódu našeho programu nejprve vybídneme uživatele, aby zadal index prvku – viz Kód 3. Je vhodné uživatele přímo informovat o hodnotách, které může zadávat. Proto jsme v závorkách příkazu Write (tento příkaz nezařádkuje na další řádek) využili vlastnost Length, která navrací hodnotu velikosti pole. U vlastnosti Length se nemusí používat závorka, protože to není metoda! Vzhledem k tomu, že první index má hodnotu 0, museli jsme odečíst hodnotu 1 od velikosti pole, abychom získali index posledního prvku. Pro konverzi zadaných číslic na hodnotu celého čísla, jsme využili příkaz TryParse. Tento příkaz kromě konverze také umí vyhodnotit, zda lze provést konverzi. Pokud ano, navrátí hodnotu true a hodnota výstupního parametr je uložena do lokální proměnné indexPrvku. V kladné větvi příkazu if, tzn., že proběhla konverze číslic, je v bloku try ošetřen potenciálně nebezpečný kód na zadání chybné hodnoty indexu ze strany uživatele. Pokud uživatel zadá špatnou hodnotu indexu prvku, je vyvolána výjimka typu IndexOutOfRangeException a v bloku příkazu catch je provedeno ošetření této výjimky. Pokud uživatel zadal správný index prvku, je vypsána hodnota prvku na pozici indexPrvku. Pokud neproběhla konverze číslic na hodnotu, která lze uložit do proměnné indexPrvku, bude vykonán výpis v záporné větvi příkazu if. V tomto výpis bude zobrazena chyba, která vyvolala výjimku.


//Výpis textu pro zadání indexu
Console.Write("Zadejte index prvku pole(0÷{0}): ", poctyLidi.Length - 1);
/*Test, zda proběhne konverze zadaného textu na číslo, pokud proběhla
 * konverze bude hodnota uložena do proměnné indexPrvku*/
if (int.TryParse(Console.ReadLine(), out int indexPrvku) == true)
    //Potenciálně nebezpečný kód na chybně zadaný index
    try
    {
        //Výpis hodnoty prvku jednorozměrného pole na základě načteného indexu
        Console.WriteLine("Prvek na pozici {0} má hodnotu: {1}",
            indexPrvku, poctyLidi[indexPrvku]);
    }
    //Ošetření výjimky
    catch (IndexOutOfRangeException ex)
    {
        Console.WriteLine("Nastala výjimka: {0}", ex.ToString());
    }
//Neproběhla konverze - chybně zadaný index
else
{
    Console.WriteLine("Zadal jste špatný formát čísla indexu");
    return;
}

Kód 3: Výpis obsahu prvku jednorozměrného pole poctyLidi s testem konverze a ošetřením výjimky

Na výpisu v konzoli vidíme zadání indexu 1 (tzn. druhý prvek pole) a následný výpis hodnoty prvku na specifikované pozici – viz Výstup programu 1 - PoleLidiVypisVyjimka_Main.

Zadejte index prvku pole(0÷4): 1
Prvek na pozici 1 má hodnotu: 5

Výstup programu 1 - PoleLidiVypisVyjimka_Main: Ukázka výpisu hodnoty prvku na specifikované pozici 

Zkusme zadat namísto čísla indexu text, který nelze konvertovat. Jak vidíme, příkaz TryParse nedokáže tento text konvertovat na celé číslo a je vykonán výpis varovného hlášení uživateli a metoda Main je ukončena – viz Výstup programu 2.

Zadejte index prvku pole(0÷4): bflm
Zadal jste špatný formát čísla indexu

Výstup programu 2 - PoleLidiVypisVyjimka_Main: Ukázka zadání textu namísto indexu prvku

Při pokusu zadat index prvku, mimo rozsah povolených mezí nastane ošetření výjimky a v konzoli je vypsán text uložený ve výjimce, který specifikuje příčinu chyby – viz Výstup programu 3.

Zadejte index prvku pole(0÷4): 5
Nastala výjimka: System.IndexOutOfRangeException: Index was outside the bounds of the array.

Výstup programu 3 - PoleLidiVypisVyjimka_Main: Ukázka výpisu výjimky při neplatném indexu prvku pole


Ilustrativní příklad PoleStrukturCas
Program PoleStrukturCas
  • Popis: Deklarace jednorozměrného pole obsahující jednotlivé struktury
  • Zadání: Zkuste deklarovat pole struktur, které bude obsahovat prvky, které obsahují strukturu Cas. Jednotlivé struktury jsou inicializovány vlastním konstruktorem. Struktura bude obsahovat tři celočíselné datové složky (datový typ int):
    • hodiny – počet hodin
    • minuty – počet minut
    • sekundy – počet sekund

      Konstruktor struktury bude přijímat tři formální parametry: hodiny, minuty, sekundy. Pomocí hodnot těchto parametrů nastavte datové složky struktury Cas. Vytvořte v metodě Main pole struktur poleStruktur obsahující dva prvky struktury Cas vytvořených pomocí zavolání konstruktoru struktury. Inicializujte první prvek (struktury) pole hodnotami: 12, 30, 50 a druhý prvek: 5, 30, 6. Vypište pomocí metod implementovaných ve struktuře VratHodiny, VratMinuty, VratSekundy časové hodnoty u obou prvků typu struktura Cas umístěných v poli
  • Řešení: PoleStrukturCas_Main

Následující příklad rozvíjí předchozí příklad PoleStrukturInicilazace, kde jsme vytvořili pole struktur pomocí volání konstruktoru u jednotlivých prvků, tzn. jednotlivých struktur. Jako první jsme deklarovali strukturu Cas, která má tři soukromé celočíselné datové složky hodiny, minuty, sekundy. Struktura obsahovala konstruktor, který inicializuje hodnoty všech datový složek pomocí formálních parametrů hodiny, minuty, sekundy – viz Kód 4.

//Deklarace datového typu struktura
struct Cas
{
    //Deklarace celočíselných datových složek
    private int hodiny, minuty, sekundy;
 
    //Deklarace konstruktoru
    public Cas(int hodiny, int minuty, int sekundy)
    {
        //Přiřazení hodnot celočíselným datovým složkám
        this.hodiny = hodiny;
        this.minuty = minuty;
        this.sekundy = sekundy;
    }
}

Kód 4: Deklarace struktury Cas včetně inicializace jejích datových složek v konstruktoru

Pro obdržení hodnoty uložené v datové složce např. hodiny, vytvoříme metodu VratHodiny, která nám navrací celočíselnou hodnotu počtu hodin (hodiny jsou datového typu int). Tato metoda je volně přístupná i mimo strukturu - přístupový modifikátor public. Tato metoda nemá žádný vstupní parametr, protože pouze potřebujeme získat výstup, tj. hodnotu příslušné datové složky. K té přistoupíme pomocí tečkové notace s využitím this. Pro přiřazení výstupu této metody využijeme příkaz return - viz Kód 5. Stejným způsobem budeme postupovat u dalších datových složek minuty a sekundy.

//Deklarace metody ve struktuře - navrací hodnotu datové složky 'hodiny'
public int VratHodiny()
{
    //Navrácení hodnoty datové složky
    return this.hodiny;
}

Kód 5: Deklarace metody VratHodiny - navrácení hodnoty datové složky

V metodě Main vytvoříme dva prvky pole s názvem poleStruktur obsahující jednotlivé struktury Cas . Jednotlivé struktury byly vytvořeny zavoláním konstruktorů struktury Cas, které jsou uzavřeny do složených závorek ve výrazu - viz Kód 6. Těmto konstruktorům jsou předány skutečné parametry definované v kulatých závorkách u každého konstruktoru.

//Vytvoření pole struktur Cas včetně jejich inicializace
Cas[] poleStruktur = { new Cas(12, 30, 50), new Cas(5, 30, 6) };

Kód 6: Příklad vytvoření instance poleStruktur včetně zavolání konstruktoru Cas pro jednotlivé struktury

Pro přístup k jednotlivým strukturám uložených jako prvky pole využijeme indexu v hranatých závorkách. K prvnímu prvku pole poleStuktur (tj. první instanci struktury Cas) přistoupíme pomocí indexu 0 uzavřeného v hranatých závorkách, tj. poleStuktur[0]. U každé instance necháme pomocí metod VratHodiny, VratMinuty, VratSekundy necháme vypsat hodnoty jednotlivých datových složek struktury - viz Kód 7.

/* Výpis jednotlivých hodnot v datových složkách první struktury uložené v prvním 
 * prvku pole (index 0) */ 
Console.WriteLine("První instance času: {0} hodin, {1} minut, {2} sekund", 
    poleStruktur[0].VratHodiny(), poleStruktur[0].VratMinuty(), poleStruktur[0].VratSekundy());

Kód 7: Výpis datových složek první instance uložené v prvním prvku pole struktur pomocí metod struktury

Na výpisu vidíme, jaké jsou hodnoty jednotlivých datových složek struktur uložených ve dvou prvcích pole - viz Výstup programu - PoleStrukturCas_Main.

První instance času: 12 hodin, 30 minut, 50 sekund
Druhá instance času: 5 hodin, 30 minut, 6 sekund

Výstup programu - PoleStrukturCas_Main: Ukázka výpisu obsahu datových složek struktur uložených v prvcích pole