CodeGym /Kursy /C# SELF /Wprowadzenie do tablic

Wprowadzenie do tablic

C# SELF
Poziom 7 , Lekcja 1
Dostępny

1. Tablica — to kontener elementów

Pewnie już słyszałeś, że komputery potrafią przetwarzać ogromne ilości informacji. Instrukcja warunkowa (if-else) i pętle (for, while) oczywiście w tym pomagają. Ale daleko na tym nie zajedziesz, bo przetwarzane dane trzeba gdzieś przechowywać.

Na taką okazję w C#, jak i praktycznie we wszystkich językach programowania, jest taka świetna rzecz jak tablice (Array). Często nazywa się je też tabelami.

Tablica — to specjalny obiekt, w którym można przechowywać nie jedną wartość, a kilka.

Arrays (Array) C#

Jeśli wcześniej porównywaliśmy zmienną do pudełka (gdzie można przechowywać jakąś wartość), to tablica to raczej pudełko podzielone w środku na sekcje. Każda sekcja w „pudełku-tablicy” ma swój numer. Numeracja oczywiście zaczyna się od zera...

Albo można zrobić jeszcze inne porównanie. Porównajmy zwykły dom jednorodzinny i blok mieszkalny. W zwykłym domu mieszka jedna rodzina, a blok jest podzielony na mieszkania. Żeby napisać list do rodziny mieszkającej w zwykłym domu, trzeba podać jej unikalny adres. A żeby napisać do rodziny z mieszkania, trzeba podać unikalny adres domu i jeszcze numer mieszkania.

No właśnie, zmienna-tablica to taka zmienna-blok. Można w niej przechowywać nie jedną wartość, a kilka. W takiej zmiennej jest kilka mieszkań (komórek), do każdej z których można się odwołać po jej numerze (indeksie).

W tym celu po nazwie zmiennej w nawiasach kwadratowych trzeba podać indeks komórki, do której się odwołujemy. To całkiem proste:


array[indeks] = wartość;
Przypisanie wartości do komórki tablicy według indeksu

Gdzie array — to nazwa zmiennej-tablicy, indeks — numer komórki w tablicy, a wartość — wartość, którą chcemy umieścić w danej komórce.

Ale najpierw zobaczmy, jak tworzyć tablice.

2. Tworzenie tablicy elementów w C#

Tworzenie tablicy elementów w C#

Załóżmy, że twoja aplikacja musi gdzieś przechowywać 100 liczb całkowitych. Najprawdopodobniej do tego nada się tablica. Jak ją utworzyć?

Gdybyśmy chcieli przechowywać jedną liczbę całkowitą, wystarczyłby nam typ int, ale jeśli chcemy przechowywać 100 liczb całkowitych, najpewniej potrzebujemy tablicy typu int. Tak wygląda kod jej tworzenia:

int[] array = new int[100];
Tworzenie tablicy 100 liczb całkowitych

Zobaczmy, co tu jest napisane.

Jak już pewnie się domyślasz, po lewej stronie znaku równości mamy deklarację zmiennej o nazwie array i typu int[]. Po typie int są nawiasy kwadratowe, które sugerują, że w „pudełkach” tego typu można przechowywać nie jedną wartość, a kilka.

Po prawej stronie znaku równości mamy „tworzenie obiektu” (słowo new) na 100 elementów (komórek) typu int. Też nie jest to zbyt trudne.

Gdybyśmy chcieli na przykład utworzyć tablicę na 20 komórek do przechowywania liczb rzeczywistych, kod jej tworzenia wyglądałby tak:

double[] vals = new double[20];
Tworzenie tablicy 20 liczb rzeczywistych

Liczbę komórek w tablicy nazywa się rozmiarem tablicy lub długością tablicy. A przez to, że mogą przechowywać wiele wartości, tablice nazywa się też kontenerami.

Ważny fakt: rozmiaru kontenera tablicy nie można zmienić po utworzeniu.

Można utworzyć nową, ale długości już utworzonego kontenera nie da się zmienić.

3. Praca z komórkami tablicy

Praca z komórkami tablicy

Ok, już umiemy tworzyć tablice, ale jak z nimi poprawnie pracować?

Prawie tak samo jak ze zwykłymi zmiennymi, tylko po nazwie zmiennej-tablicy zawsze trzeba podać numer komórki, z którą pracujemy.

Numeracja komórek tablicy zawsze zaczyna się od zera. Jeśli mamy tablicę na 10 elementów, to numery (indeksy) jej komórek to 0..9, jeśli tablica na 200 elementów, to 0..199. I tak dalej.

Przykłady:

int[] a = new int[10];	// Tworzymy tablicę na 10 elementów typu int.

a[2] = 4;				// Do komórki o indeksie 2 wpisujemy wartość 4.

a[7] = 9;				// Do komórki o indeksie 7 wpisujemy wartość 9.

a[9] = a[2] + a[5];		// Do komórki o indeksie 9 wpisujemy sumę wartości, które są w komórkach 2 	
                        // (jest tam 4) i 5 (jest tam 0). 

Oto co będzie przechowywane w pamięci po wykonaniu tego kodu:

Working with int array cells

Kolumna po lewej stronie tablicy (szary kolor) — to numery (indeksy) komórek. W komórkach przechowywane są wpisane wartości: 4, 9 i 4. Zaraz po utworzeniu komórki tablicy są wypełnione zerami.

Ważne. Wszystkie komórki tablicy mają ten sam typ danych. Jeśli utworzyliśmy tablicę stringów string, w jej komórkach można przechowywać tylko stringi. Typ danych tablicy ustala się przy jej tworzeniu. Ani typu danych, ani długości tablicy nie można potem zmienić.

4. Tablice w pamięci

Obrazki w poprzednich przykładach są trochę niedokładne.

Podczas tworzenia tablic (tak samo jak przy tworzeniu stringów) w pamięci są przydzielane dwa bloki pamięci: jeden do przechowywania samej tablicy (kontenera), a drugi — na zmienną, która przechowuje jej adres. Dokładniejsza sytuacja pokazana jest na obrazku poniżej:

Arrays in memory

Na zielono pokazana jest tablica na 10 elementów typu int i zmienna typu int[], która przechowuje adres (referencję) tablicy typu int w pamięci.

Dla porównania na niebiesko zaznaczona jest zwykła zmienna typu int, która przechowuje wartość 199.

Trochę to przypomina przechowywanie stringów w pamięci, nie sądzisz?

Dokładnie, stringi. I tak jak przy pracy ze stringami, „zmienne typu tablica” można przypisywać sobie nawzajem:

int[] a = new int[10];		// Tworzymy tablicę na 10 elementów typu int.

a[2] = 4;					// Do komórki o indeksie 2 wpisujemy wartość 4.
a[7] = 9;					// Do komórki o indeksie 7 wpisujemy wartość 9.

int[] b = a;				// Do zmiennej b zapisujemy adres, który jest w zmiennej a.
                            // Teraz a i b wskazują na ten sam obiekt-tablicę w pamięci.

a[9] = b[2] + a[7];			// Do komórki o indeksie 9 obiektu-tablicy wpisujemy sumę wartości, 
                            // które są w komórkach 2 (jest tam 4) i 7 (jest tam 9). 

Przy tym obiekt-tablica zostanie tam, gdzie był, a zmienne a i b będą przechowywać te same adresy (referencje) do tego samego obiektu. Zobacz obrazek:

Arrays in memory 2

5. Praca z tablicą bardziej szczegółowo

Tablicę można utworzyć z dowolnego typu. Wystarczy po nazwie typu napisać nawiasy kwadratowe. Ogólny wzór tworzenia tablicy wygląda tak:

typ[] nazwa = new typ[ilość];
Kanoniczna forma tworzenia tablicy

Gdzie typ — to typ elementów (komórek) tablicy, które będziemy przechowywać w tablicy. Nazwa — to nazwa zmiennej, przez którą będziemy się do tablicy odwoływać, a ilość — to liczba komórek w tablicy.

W powyższym przykładzie pokazana jest kanoniczna forma: tworzenie zmiennej-tablicy i tworzenie obiektu-tablicy. W rzeczywistości to dwie niezależne konstrukcje. Można utworzyć zmienną-tablicę i obiekt-tablicę osobno:


typ[] nazwa;
nazwa = new typ[ilość];
        
Osobno tworzymy zmienną i tablicę

I jeszcze jedna ważna rzecz

Jako indeks tablicy i jako ilość elementów tablicy mogą występować zmienne, a nawet całe wyrażenia.

Przykłady:

int n = 100;
int[] a = new int[n];			// 	Tworzenie tablicy z n elementów

int n = 100;
int[] a = new int[n * 2 + 3];	// 	Tworzenie tablicy na 203 elementy

int n = 100;
int[] a = new int[n];
a[n-1] = 2;					// a[99] = 2;
a[n-2] = 3;					// a[98] = 3;
a[n/5] = a[n-1] + a[n-2];	// a[20] = a[99] + a[98];

Wyjście poza granice tablicy

Przy okazji, zwracamy uwagę, że jeśli spróbujesz odwołać się do komórki tablicy pod indeksem, którego nie ma w tablicy (w naszym przypadku to wszystkie liczby całkowite poza 0..99), program zakończy się błędem IndexOutOfRangeException — indeks poza granicami tablicy.

6. Długość tablicy

Jak widzieliśmy w poprzednim przykładzie, można osobno utworzyć zmienną typu tablica i potem gdzieś w kodzie przypisać jej wartość (referencję do obiektu-tablicy). Można nawet tak:

int[] array;			//	Tworzymy zmienną-tablicę typu int[]
if (a < 10)				// Jeśli zmienna a jest mniejsza niż 10,
   array = new int[10];	// to utwórz tablicę z 10 elementów.
else					// W przeciwnym razie
   array = new int[20];	// utwórz tablicę z 20 elementów 

I jak dalej pracować z taką tablicą? Jak sprawdzić, ile ma elementów?

Do tego tablica ma specjalną właściwość (zmienną) — length. I długość tablicy można sprawdzić za pomocą takiego wyrażenia:

array.Length;
Pobieranie długości tablicy przez właściwość Length

Gdzie array — to nazwa zmiennej-tablicy, a Length — to nazwa właściwości obiektu-tablicy. Wartości w właściwości Length nie można zmienić: samą właściwość Length można przypisywać innym zmiennym, ale jej nie można przypisać niczego (program po prostu się nie skompiluje).

Tak można kontynuować poprzedni przykład:

int[] array;			//	Tworzymy zmienną-tablicę typu int[]
if (a < 10)				// Jeśli zmienna a jest mniejsza niż 10,
   array = new int[10];	// to utwórz tablicę z 10 elementów.
else					// W przeciwnym razie
   array = new int[20];	// utwórz tablicę z 20 elementów 

for (int i = 0; i < array.Length; i++)	// Pętla po wszystkich elementach tablicy: od 0 do array.Length — 1
{
   Console.WriteLine(array[i]);
}

7. Fakty o tablicach w C#

Podsumujmy znane fakty o tablicach:

  • Fakt 1. Tablica składa się z wielu komórek.
  • Fakt 2. Dostęp do konkretnej komórki odbywa się przez podanie jej numeru.
  • Fakt 3. Wszystkie komórki są tego samego typu.
  • Fakt 4. Wartość początkowa dla wszystkich komórek to 0 i null (jeśli w komórce przechowywany jest adres), false (dla typu bool).
  • Fakt 5. string[] list — to tylko deklaracja zmiennej: sam kontener (obiekt-tablica) jeszcze nie został utworzony. Żeby z niego korzystać, trzeba utworzyć tablicę (kontener) i przypisać ją do tej zmiennej, a potem już jej używać. Patrz przykład poniżej.
  • Fakt 6. Gdy tworzymy obiekt-tablicę (kontener), trzeba podać, jakiej jest długości — ile ma komórek. Robi się to poleceniem: new TypeName[n];
  • Fakt 7. Długość tablicy można sprawdzić przez właściwość .Length.
  • Fakt 8. Po utworzeniu tablicy nie można zmienić ani typu jej elementów, ani ich ilości.
string s;				// s równa się null
string[] list;			// list równa się null

list = new string[10];	// Zmienna list przechowuje referencję do obiektu – tablicy stringów z 10 elementów.
int n = list.Length;	// n równa się 10

list = new string[0];	// Teraz list zawiera tablicę z 0 elementów. 
                        // Tablica istnieje, ale nie może przechowywać elementów.

list = null;
Console.WriteLine(list[1]); // Wygenerowany zostanie błąd programu — program zakończy się awaryjnie. 
                            // list zawiera pustą referencję — null

list = new string[10];
Console.WriteLine(list[10]);	// Wygenerowany zostanie błąd — wyjście poza granice tablicy.
//	Jeśli list zawiera 10 elementów/komórek, to dozwolone indeksy: 0 1 2 3 4 5 6 7 8 9 — razem 10 sztuk. 	
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION