Tablice w języku C#

Tablice w C# są strukturami danych, które pozwalają na przechowywanie wielu elementów tego samego typu w uporządkowany sposób. Umożliwiają one dostęp do danych za pomocą indeksów, co pozwala na efektywne przetwarzanie dużych zbiorów danych.

Deklaracja i inicjalizacja tablicy

Aby zadeklarować tablicę, należy określić jej typ oraz użyć nawiasów kwadratowych []:

typ[] nazwaTablicy;

Przykład:

int[] liczby; // Deklaracja tablicy liczb całkowitych

Inicjalizacja tablicy polega na przypisaniu jej rozmiaru lub wartości początkowych:

liczby = new int[5]; // Inicjalizacja tablicy o rozmiarze 5

Można również połączyć deklarację z inicjalizacją:

int[] liczby = new int[5];

Inicjalizacja z wartościami początkowymi

Tablicę można od razu wypełnić wartościami:

int[] liczby = new int[] {1, 2, 3, 4, 5};

Lub jeszcze prościej:

int[] liczby = {1, 2, 3, 4, 5};

Przykłady z różnymi typami danych

// Tablica liczb zmiennoprzecinkowych
double[] ceny = {19.99, 15.50, 8.75, 25.00};

// Tablica tekstów
string[] imiona = {"Anna", "Piotr", "Maria", "Jan"};

// Tablica wartości logicznych
bool[] odpowiedzi = {true, false, true, false};

// Tablica znaków
char[] litery = {'A', 'B', 'C', 'D'};

Zapisywanie danych do tablicy

Elementy tablicy są indeksowane od 0 do n-1, gdzie n to rozmiar tablicy.

Przykład:

int[] liczby = new int[5];
liczby[0] = 10;
liczby[1] = 20;
liczby[2] = 30;
liczby[3] = 40;
liczby[4] = 50;

Użycie pętli do zapisu danych

for (int i = 0; i < liczby.Length; i++)
{
    liczby[i] = (i + 1) * 10;
}

Pobieranie danych od użytkownika

int[] oceny = new int[5];

Console.WriteLine("Wprowadź 5 ocen:");
for (int i = 0; i < oceny.Length; i++)
{
    Console.Write($"Ocena {i + 1}: ");
    oceny[i] = int.Parse(Console.ReadLine());
}

Właściwość Length w tablicach

Właściwość Length jest wbudowaną właściwością tablic w C#, która zwraca liczbę elementów w tablicy. Dzięki niej możemy łatwo dowiedzieć się, ile elementów zawiera tablica, bez konieczności ręcznego liczenia czy zapamiętywania jej rozmiaru.

Przykład:

int[] liczby = new int[5];
Console.WriteLine(liczby.Length); // Wyświetli 5

Użycie Length w pętlach

Właściwość Length jest często używana w pętlach, aby przejść przez wszystkie elementy tablicy, niezależnie od jej rozmiaru.

Przykład: Iterowanie przez tablicę za pomocą pętli for

for (int i = 0; i < liczby.Length; i++)
{
    Console.WriteLine($"Indeks {i}: {liczby[i]}");
}

Dlaczego używamy liczby.Length zamiast stałej liczby?

  • Elastyczność: Jeśli zmienimy rozmiar tablicy, nie musimy modyfikować warunku w pętli. Kod automatycznie dostosuje się do nowej długości tablicy.
  • Bezpieczeństwo: Unikamy błędów typu IndexOutOfRangeException, które mogą wystąpić, gdy próbujemy uzyskać dostęp do indeksu poza zakresem tablicy.
  • Czytelność: Użycie Length jasno wskazuje, że pętla ma iterować przez całą tablicę.

Odczyt danych z tablicy

Aby odczytać wartości z tablicy, używamy indeksów tak samo jak przy zapisie.

Przykład:

Console.WriteLine(liczby[0]); // Wyświetli 10
Console.WriteLine(liczby[1]); // Wyświetli 20

Odczyt wszystkich elementów przy użyciu pętli

for (int i = 0; i < liczby.Length; i++)
{
    Console.WriteLine(liczby[i]);
}

Odczyt kontrolowany przez instrukcję if

Możemy kontrolować odczyt danych z tablicy za pomocą instrukcji warunkowych.

Przykład: Wyświetlanie tylko liczb większych od 25

for (int i = 0; i < liczby.Length; i++)
{
    if (liczby[i] > 25)
    {
        Console.WriteLine(liczby[i]);
    }
}

Przykład: Wyświetlanie liczb parzystych

for (int i = 0; i < liczby.Length; i++)
{
    if (liczby[i] % 2 == 0)  // Reszta z dzielenia przez 2 = 0
    {
        Console.WriteLine($"Liczba parzysta: {liczby[i]}");
    }
}

Szukanie elementu w tablicy

Podstawowe wyszukiwanie

Aby znaleźć konkretny element w tablicy, przeszukujemy ją, porównując każdy element z poszukiwaną wartością.

Przykład: Szukanie liczby 30 w tablicy

int szukana = 30;
bool znaleziono = false;

for (int i = 0; i < liczby.Length; i++)
{
    if (liczby[i] == szukana)
    {
        znaleziono = true;
        Console.WriteLine($"Znaleziono liczbę {szukana} na indeksie {i}.");
        break; // Opcjonalnie przerywamy pętlę po znalezieniu
    }
}

if (!znaleziono)
{
    Console.WriteLine($"Liczba {szukana} nie została znaleziona w tablicy.");
}

Wyszukiwanie wszystkich wystąpień

int[] oceny = {5, 3, 4, 5, 2, 5, 4};
int szukanaOcena = 5;
int liczbaWystapien = 0;

Console.WriteLine($"Szukam oceny {szukanaOcena}:");

for (int i = 0; i < oceny.Length; i++)
{
    if (oceny[i] == szukanaOcena)
    {
        Console.WriteLine($"Znaleziono na pozycji {i}");
        liczbaWystapien++;
    }
}

Console.WriteLine($"Ocena {szukanaOcena} wystąpiła {liczbaWystapien} razy.");

Wyszukiwanie w tablicy tekstowej

string[] miasta = {"Warszawa", "Kraków", "Gdańsk", "Wrocław", "Poznań"};
string szukaneMiasto = "Kraków";
bool znaleziono = false;

for (int i = 0; i < miasta.Length; i++)
{
    if (miasta[i] == szukaneMiasto)
    {
        Console.WriteLine($"Miasto {szukaneMiasto} jest na pozycji {i}");
        znaleziono = true;
        break;
    }
}

if (!znaleziono)
{
    Console.WriteLine($"Miasto {szukaneMiasto} nie zostało znalezione");
}

Sprawdzanie czy tablica zawiera element

Możemy stworzyć funkcję, która sprawdza czy tablica zawiera określony element (podobnie do metody Contains):

// Funkcja sprawdzająca czy tablica zawiera element
static bool CzyTablicaZawiera(int[] tablica, int szukanyElement)
{
    for (int i = 0; i < tablica.Length; i++)
    {
        if (tablica[i] == szukanyElement)
        {
            return true; // Znaleziono element
        }
    }
    return false; // Nie znaleziono
}

// Użycie funkcji
static void Main()
{
    int[] liczby = {10, 20, 30, 40, 50};
    
    if (CzyTablicaZawiera(liczby, 30))
    {
        Console.WriteLine("Tablica zawiera liczbę 30");
    }
    else
    {
        Console.WriteLine("Tablica nie zawiera liczby 30");
    }
}

Funkcja dla tablicy tekstowej

static bool CzyTablicaZawieraTekst(string[] tablica, string szukanyTekst)
{
    for (int i = 0; i < tablica.Length; i++)
    {
        if (tablica[i] == szukanyTekst)
        {
            return true;
        }
    }
    return false;
}

// Przykład użycia
string[] przedmioty = {"Matematyka", "Polski", "Angielski", "Historia"};

if (CzyTablicaZawieraTekst(przedmioty, "Matematyka"))
{
    Console.WriteLine("Matematyka jest w planie lekcji");
}

Wbudowane metody klasy Array

C# oferuje wiele przydatnych metod wbudowanych w klasę Array, które ułatwiają pracę z tablicami. Oto najważniejsze z nich na poziomie podstawowym:

Array.Sort() – sortowanie tablicy

int[] liczby = {5, 2, 8, 1, 9, 3};
Console.WriteLine("Przed sortowaniem:");
for (int i = 0; i < liczby.Length; i++)
{
    Console.Write(liczby[i] + " ");
}

Array.Sort(liczby); // Sortuje tablicę rosnąco

Console.WriteLine("\nPo sortowaniu:");
for (int i = 0; i < liczby.Length; i++)
{
    Console.Write(liczby[i] + " ");
}
// Wynik: 1 2 3 5 8 9

Sortowanie działa również z tekstem:

string[] imiona = {"Zofia", "Anna", "Piotr", "Barbara"};
Array.Sort(imiona);

Console.WriteLine("Posortowane imiona:");
for (int i = 0; i < imiona.Length; i++)
{
    Console.WriteLine(imiona[i]);
}
// Wynik: Anna, Barbara, Piotr, Zofia

Array.Reverse() – odwracanie tablicy

int[] liczby = {1, 2, 3, 4, 5};
Console.WriteLine("Przed odwróceniem:");
for (int i = 0; i < liczby.Length; i++)
{
    Console.Write(liczby[i] + " ");
}

Array.Reverse(liczby);

Console.WriteLine("\nPo odwróceniu:");
for (int i = 0; i < liczby.Length; i++)
{
    Console.Write(liczby[i] + " ");
}
// Wynik: 5 4 3 2 1

Array.IndexOf() – znajdowanie pozycji elementu

string[] kolory = {"czerwony", "zielony", "niebieski", "żółty"};
string szukanyKolor = "niebieski";

int pozycja = Array.IndexOf(kolory, szukanyKolor);

if (pozycja >= 0)
{
    Console.WriteLine($"Kolor {szukanyKolor} znajduje się na pozycji {pozycja}");
}
else
{
    Console.WriteLine($"Kolor {szukanyKolor} nie został znaleziony");
}
// Wynik: Kolor niebieski znajduje się na pozycji 2

Array.Copy() – kopiowanie tablicy

int[] oryginalna = {1, 2, 3, 4, 5};
int[] kopia = new int[oryginalna.Length];

Array.Copy(oryginalna, kopia, oryginalna.Length);

Console.WriteLine("Tablica oryginalna:");
for (int i = 0; i < oryginalna.Length; i++)
{
    Console.Write(oryginalna[i] + " ");
}

Console.WriteLine("\nKopia tablicy:");
for (int i = 0; i < kopia.Length; i++)
{
    Console.Write(kopia[i] + " ");
}

Sprawdzanie czy tablica zawiera element

Używając Array.IndexOf()

int[] liczby = {10, 20, 30, 40, 50};
int szukanaLiczba = 30;

// Jeśli IndexOf zwraca -1, element nie został znaleziony
if (Array.IndexOf(liczby, szukanaLiczba) >= 0)
{
    Console.WriteLine($"Tablica zawiera liczbę {szukanaLiczba}");
}
else
{
    Console.WriteLine($"Tablica nie zawiera liczby {szukanaLiczba}");
}

Praktyczny przykład z sprawdzaniem zawartości

using System;

class Program
{
    // Uniwersalna funkcja sprawdzająca zawartość dla liczb
    static bool CzyZawiera(int[] tablica, int element)
    {
        return Array.IndexOf(tablica, element) >= 0;
    }
    
    static void Main()
    {
        int[] ulubioneLiczby = {7, 13, 21, 42, 99};
        
        Console.WriteLine("Twoje ulubione liczby:");
        for (int i = 0; i < ulubioneLiczby.Length; i++)
        {
            Console.Write(ulubioneLiczby[i] + " ");
        }
        
        Console.Write("\nPodaj liczbę do sprawdzenia: ");
        int liczba = int.Parse(Console.ReadLine());
        
        if (CzyZawiera(ulubioneLiczby, liczba))
        {
            Console.WriteLine($"Tak! {liczba} jest w twoich ulubionych liczbach.");
        }
        else
        {
            Console.WriteLine($"Nie, {liczba} nie ma wśród twoich ulubionych liczb.");
        }
    }
}

Array.Clear() – czyszczenie tablicy

int[] liczby = {10, 20, 30, 40, 50};

Console.WriteLine("Przed wyczyszczeniem:");
for (int i = 0; i < liczby.Length; i++)
{
    Console.Write(liczby[i] + " ");
}

Array.Clear(liczby, 0, liczby.Length); // Wyczyść całą tablicę

Console.WriteLine("\nPo wyczyszczeniu:");
for (int i = 0; i < liczby.Length; i++)
{
    Console.Write(liczby[i] + " ");
}
// Wynik: 0 0 0 0 0 (wartości domyślne)

Można też wyczyścić część tablicy:

int[] liczby2 = {1, 2, 3, 4, 5};
Array.Clear(liczby2, 1, 3); // Wyczyść 3 elementy zaczynając od indeksu 1

for (int i = 0; i < liczby2.Length; i++)
{
    Console.Write(liczby2[i] + " ");
}
// Wynik: 1 0 0 0 5

Praktyczny przykład z metodami wbudowanymi

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Program do zarządzania ocenami");
        
        // Pobierz oceny od użytkownika
        Console.Write("Ile ocen chcesz wprowadzić? ");
        int iloscOcen = int.Parse(Console.ReadLine());
        
        int[] oceny = new int[iloscOcen];
        
        for (int i = 0; i < oceny.Length; i++)
        {
            Console.Write($"Podaj ocenę {i + 1}: ");
            oceny[i] = int.Parse(Console.ReadLine());
        }
        
        // Pokaż wprowadzone oceny
        Console.WriteLine("\nTwoje oceny:");
        for (int i = 0; i < oceny.Length; i++)
        {
            Console.Write(oceny[i] + " ");
        }
        
        // Znajdź konkretną ocenę
        Console.Write("\n\nJaką ocenę chcesz znaleźć? ");
        int szukanaOcena = int.Parse(Console.ReadLine());
        
        int pozycja = Array.IndexOf(oceny, szukanaOcena);
        if (pozycja >= 0)
        {
            Console.WriteLine($"Ocena {szukanaOcena} znajduje się na pozycji {pozycja + 1}");
        }
        else
        {
            Console.WriteLine($"Ocena {szukanaOcena} nie została znaleziona");
        }
        
        // Posortuj oceny
        int[] ocenySortowane = new int[oceny.Length];
        Array.Copy(oceny, ocenySortowane, oceny.Length);
        Array.Sort(ocenySortowane);
        
        Console.WriteLine("\nOceny posortowane rosnąco:");
        for (int i = 0; i < ocenySortowane.Length; i++)
        {
            Console.Write(ocenySortowane[i] + " ");
        }
        
        // Pokaż oceny od najwyższej
        Array.Reverse(ocenySortowane);
        Console.WriteLine("\nOceny posortowane malejąco:");
        for (int i = 0; i < ocenySortowane.Length; i++)
        {
            Console.Write(ocenySortowane[i] + " ");
        }
    }
}

Przydatne operacje na tablicach

Znajdowanie minimum i maksimum

int[] liczby = {15, 8, 23, 4, 16, 42, 7, 19};

// Znajdź minimum
int minimum = liczby[0];
for (int i = 1; i < liczby.Length; i++)
{
    if (liczby[i] < minimum)
    {
        minimum = liczby[i];
    }
}

// Znajdź maksimum
int maksimum = liczby[0];
for (int i = 1; i < liczby.Length; i++)
{
    if (liczby[i] > maksimum)
    {
        maksimum = liczby[i];
    }
}

Console.WriteLine($"Minimum: {minimum}");
Console.WriteLine($"Maksimum: {maksimum}");

Sumowanie i średnia

int[] oceny = {5, 4, 3, 5, 4, 2, 5};
int suma = 0;

// Oblicz sumę
for (int i = 0; i < oceny.Length; i++)
{
    suma += oceny[i];
}

// Oblicz średnią
double srednia = suma / (double)oceny.Length;

Console.WriteLine($"Suma ocen: {suma}");
Console.WriteLine($"Średnia: {srednia:F2}");

Kopiowanie tablicy

int[] oryginalna = {1, 2, 3, 4, 5};
int[] kopia = new int[oryginalna.Length];

// Skopiuj element po elemencie
for (int i = 0; i < oryginalna.Length; i++)
{
    kopia[i] = oryginalna[i];
}

// Sprawdź czy skopiowano poprawnie
for (int i = 0; i < kopia.Length; i++)
{
    Console.WriteLine($"Element {i}: {kopia[i]}");
}

Praktyczny przykład

Poniżej znajduje się kompletny program demonstrujący wykorzystanie tablic w praktyce.

using System;

class Program
{
    static void Main()
    {
        // Deklaracja i inicjalizacja tablicy
        int[] liczby = new int[5];

        // Zapisywanie danych do tablicy (wprowadzanie przez użytkownika)
        for (int i = 0; i < liczby.Length; i++)
        {
            Console.Write($"Podaj liczbę dla indeksu {i}: ");
            liczby[i] = int.Parse(Console.ReadLine());
        }

        // Odczyt danych z tablicy (wyświetlanie wszystkich elementów)
        Console.WriteLine("\nZawartość tablicy:");
        for (int i = 0; i < liczby.Length; i++)
        {
            Console.WriteLine($"Indeks {i}: {liczby[i]}");
        }

        // Odczyt kontrolowany przez instrukcję if (wyświetlanie liczb parzystych)
        Console.WriteLine("\nLiczby parzyste w tablicy:");
        for (int i = 0; i < liczby.Length; i++)
        {
            if (liczby[i] % 2 == 0)
            {
                Console.WriteLine($"Indeks {i}: {liczby[i]}");
            }
        }

        // Szukanie elementu w tablicy
        Console.Write("\nPodaj liczbę do wyszukania: ");
        int szukana = int.Parse(Console.ReadLine());
        bool znaleziono = false;

        for (int i = 0; i < liczby.Length; i++)
        {
            if (liczby[i] == szukana)
            {
                znaleziono = true;
                Console.WriteLine($"Znaleziono liczbę {szukana} na indeksie {i}.");
                break;
            }
        }

        if (!znaleziono)
        {
            Console.WriteLine($"Liczba {szukana} nie została znaleziona w tablicy.");
        }

        // Dodatkowo - oblicz sumę i średnią
        int suma = 0;
        for (int i = 0; i < liczby.Length; i++)
        {
            suma += liczby[i];
        }
        
        double srednia = suma / (double)liczby.Length;
        Console.WriteLine($"\nSuma wszystkich liczb: {suma}");
        Console.WriteLine($"Średnia: {srednia:F2}");
    }
}

Wyjaśnienie programu

  1. Deklaracja tablicy: Tworzymy tablicę liczby o rozmiarze 5.
  2. Zapisywanie danych: Użytkownik wprowadza 5 liczb, które są zapisywane do tablicy.
  3. Odczyt danych: Wyświetlamy wszystkie wprowadzone liczby wraz z ich indeksami.
  4. Odczyt kontrolowany: Wyświetlamy tylko liczby parzyste z tablicy.
  5. Szukanie elementu: Użytkownik podaje liczbę do wyszukania, a program sprawdza, czy znajduje się ona w tablicy.
  6. Obliczenia: Program oblicza sumę i średnią wszystkich liczb w tablicy.

Dodatkowe informacje

  • Indeksowanie: Pamiętaj, że indeksy w tablicach zaczynają się od 0.
  • Dostęp poza zakresem: Próba dostępu do elementu poza zakresem tablicy spowoduje błąd IndexOutOfRangeException.
  • Tablice wielowymiarowe: C# obsługuje również tablice wielowymiarowe, np. tablice dwuwymiarowe (matryce).
  • Metody pomocnicze: Klasa Array oferuje wiele metod, takich jak Sort(), IndexOf(), czy Length, które ułatwiają pracę z tablicami.

Najczęstsze błędy

Dostęp do nieistniejącego indeksu

int[] liczby = {1, 2, 3}; // Indeksy: 0, 1, 2

// BŁĄD! Indeks 3 nie istnieje
// Console.WriteLine(liczby[3]); // IndexOutOfRangeException

Używanie rozmiaru zamiast ostatniego indeksu

int[] liczby = new int[5]; // Rozmiar: 5, ostatni indeks: 4

Console.WriteLine($"Rozmiar: {liczby.Length}");        // 5
Console.WriteLine($"Ostatni indeks: {liczby.Length - 1}"); // 4

// POPRAWNIE: dostęp do ostatniego elementu
liczby[liczby.Length - 1] = 99;

Ćwiczenia

  1. Sumowanie elementów: Napisz program, który sumuje wszystkie elementy w tablicy liczb całkowitych.
  2. Średnia arytmetyczna: Oblicz średnią arytmetyczną wartości w tablicy.
  3. Maksimum i minimum: Znajdź największą i najmniejszą wartość w tablicy.
  4. Odwracanie tablicy: Napisz program, który odwraca kolejność elementów w tablicy.
  5. Tablica znaków: Stwórz tablicę typu char[] i wypisz jej zawartość w odwrotnej kolejności.
  6. Wyszukiwanie zaawansowane: Napisz program, który znajdzie wszystkie pozycje określonego elementu w tablicy.