background image

 

Tablice 

  

background image

 

Przegląd zagadnień 

 

 

W module tym zostanie zaprezentowana pierwsza z struktur danych 
omawianych w tym kursie - tablica. Tablice bardzo się przydają, gdy trzeba 
wykonać szereg operacji na pewnej grupie zmiennych tego samego typu. 

Po skończeniu tego modułu studenci powinni: 

 

Widzieć, co to jest tablica. 

 

Potrafić zdefiniować tablice w języku C#. 

 

Potrafić korzystać z tablic. 

 

Potrafić używać pętli foreach. 

background image

 

Definicja tablicy 

 

 

Tablica jest ciągiem zmiennych tego samego typu, które będziemy dalej 
nazywać elementami tablicy. Każdy element tablicy może być wybrany w 
dowolnej kolejności i jest dostępny w tym samym czasie. Właściwość, że 
tablica jest zbudowana z elementów tego samego typu, nazywamy 
jednorodnością. Typ elementu nazywamy typem podstawowym tablicy. 
Struktury danych, której wszystkie składowe są jednakowo dostępne, 
określamy jako struktury o dostępie swobodnym (random access). Liczba 
elementów tablicy jest stała. Nie może być zmieniana w czasie działania 
programu i musi być podana w czasie jej tworzenia. Zmianę liczby elementów 
tablicy jest pozorowana przez utworzenie nowej tablicy i skopiowanie 
odpowiednich elementów tablicy źródłowej do nowo utworzonej tablicy. 
Dodatkową właściwością wynikającą z implementacji jest ciągłość, czyli 
elementy (zmienne) z których zbudowana jest tablica, zajmują ciągły obszar 
pamięci.  

Uwaga: 
Ciągłość tablicy w przypadku tablicy, której typem podstawowym jest typ 
referencyjny, nie pociąga za sobą ciągłości obszaru pamięci zajmowanej przez 
obiekty danego typu. Występuje tylko ciągłość pamięci zajmowanej przez 
zmienne - odwołania. 

W celu wybrania pojedynczego elementu tablicy posługujemy się tzw. 
indeksem. 

background image

 

Tworzenie tablic w C# 

 

 

Zmienną typu tablicowego definiuje się przez podanie typu podstawowego 
tablicy, następnie występują nawiasy kwadratowe, po których umieszcza się 
nazwę zmienne tablicowej. Nazwa ta podlega tym samym regułom, co nazwy 
zwykłych zmiennych, czyli może składać się z cyfr, liter, znaku podkreślenia; 
nie może zaczynać się od cyfry; nie może być słowem kluczowym; musi być 
unikalna w danym bloku kodu: 

typ [] nazwa; 

Typ tablicowy jest typem referencyjnym. Deklaracja zmiennej tablicowej nie 
tworzy więc automatycznie tablicy - obiektu tablicy. Do utworzenia obiektu 
tablicy używa się operatora new. Obiekt tablicy można utworzyć zarówno w 
miejscu deklaracji zmiennej tablicowej: 

typ [] nazwa = new typ[ilosc_Elementow]; 

jak również w dalszej części programu, po deklaracji zmiennej tablicowej: 

typ [] nazwa; 
... 
nazwa = new typ[ilosc_Elementow]; 

Podczas definicji obiektu tablicowego musimy podać ilość elementów, z 
których składa się tablica - wyrażenie ilosc_Elementow. Wartość 
wyrażenie ilosc_Elementow musi być liczbą całkowitą większą lub równą 
zero. Wartość ta nie musi być znana w czasie kompilacji, czyli wyrażenie 
ilosc_Elementow może zawierać odwołanie do zmiennych 

Przykłady definicji tablic: 

background image

 

1. 

Tablica sześciu liczb rzeczywistych: 
 
double [] liczby = new double[6]; 

2.  Tablica n elementowa obiektów typu string, gdzie n jest liczbą podaną 

przez użytkownika: 
 
Console.Write("Podaj liczbę elementów tablicy: "); 
uint n = Convert.ToUInt32(Console.ReadLine()); 
string [] napisy = new string[n]; 

W przypadku definicji tablicy, w pierwszy nawiasach kwadratowych nie wolno 
umieszczać żadnych wyrażeń. Nawisy kwadratowe muszą występować między 
nazwa typu a nazwą zmiennej. Poniższa linijki spowodują błąd kompilacji: 

short [

3

] tab1 = new short[3]; 

short tab2

[]

 = new short[3]; 

Uwaga: 
Istnieje również możliwość alokacji bloku pamięci na stosie przy pomocy 
słowa stackalloc. Więcej informacji na temat słowa kluczowego 
stackalloc można znaleźć w MSDN Library  

 

background image

 

Tablice wielowymiarowe 

 

 

W języku C# oprócz tablic jednowymiarowych, którą możemy wyobrazić sobie 
jako wektor, istnieją również tablice wielowymiarowe. Tablicę dwuwymiarową 
możemy przedstawić w postaci macierzy. Wymiar tablicy możemy określić 
jako liczbę indeksów związanych z elementem tablicy. Przykładem tablicy 
wielowymiarowej może być tablica zawierająca oceny różnych uczniów z 
różnych przedmiotów, którzy uczęszczają do różnych klas w różnych szkołach. 
Poszczególne indeksy w takiej tablicy będą związane z wyborem szkoły, 
wyborem klasy oraz określeniem przedmiotu i ucznia. 

Zmienną zawierającą odwołanie do tablicy wielowymiarowej deklarujemy 
umieszczając przecinki w nawiasach kwadratowych. Wymiar tablicy będzie 
równy liczbie przecinków plus jeden. 

int [,] tab2; 

//tablica dwuwymiarowa 

int [,,] tab3; 

//tablica trójwymiarowa 

int [,,,] tab; 

//tablica czteromiarowa 

Do utworzenia obiektu tablicy wielowymiarowej, podobnie jak w przypadku 
tablicy jednowymiarowej, używa się operatora new i można go utworzyć 
zarówno w miejscu deklaracji zmiennej tablicowej: 

typ [,] nazwa = new typ[wyrazenie1, wtrazenie2]; 

jak również w dalszej części programu, po deklaracji zmiennej tablicowej: 

typ [,] nazwa; 
... 
nazwa = new typ[wyrazenie1, wyrazenie2]; 

background image

 

Gdzie wyrazenie1 oraz wyrazenie2 określają rozmiar tablicy w 
poszczególnych wymiarach, czyli liczbę elementów w poszczególnych 
wymiarach. 

Ilość elementów tablicy wielowymiarowej można uzyskać mnożąc przez siebie 
rozmiary tablicy w poszczególnych wymiarach. W powyższym przykładzie 
liczba wszystkich elementów tablicy jest równa iloczynowi: 
wyrazenie1*wyrazenie2. 

W języku C# istnieje również możliwość utworzenia tablicy nieregularnej, czyli 
np. w przypadku tablicy dwuwymiarowej, takiej tablicy, która ma różną liczbę 
elementów w poszczególnych wierszach. 

Zmienną takiej tablicy tworzymy w następujący sposób: 

typ [][] nazwa; 

Powyższa instrukcja deklaruje zmienną tablicową, która może zawierać 
odwołanie do tablicy jednowymiarowej, której elementy są tablicami. Czyli 
tablica nieregularna w języku C# traktowana jest jako tablica jednowymiarowa, 
której elementy są tablicami. Ponieważ jednak przy zmiennej tablicowej 
nieregularnej może wystąpić wiele indeksów, będziemy mówili o wielu 
wymiarach tablicy nieregularnej. 

Obiekty tablic nieregularnych możemy również tworzyć w miejscu deklaracji 
zmiennej tablicowej, jak i w dalszej części programu. W przypadku tworzenia 
tablic nieregularnych rozmiar podajemy tylko dla pierwszego wymiaru. Podanie 
rozmiaru dla większej ilości wymiarów powoduje błąd kompilatora. 

typ [][] nazwa2 = new typ[2][]; 

Powyższa instrukcja tworzy tablicę dwuelementową, której elementami są 
tablice. Tablice składowe, wiersze macierzy, tworzymy w następnych 
instrukcjach.  

nazwa2[0] = new typ[4];  
nazwa2[1] = new typ[3]; 

Pierwszy wiersz macierzy, w wyniku wykonania powyższego kodu, będzie 
miał cztery elementy, drugi natomiast trzy. Więcej na temat odwołania się do 
poszczególnych elementów tablicy będzie przedstawione w dalszej części tego 
modułu. 

Można również łączyć definicję tablic regularnych z nieregularnymi np.: 

double [][,] t1 = new double[2][,]; 
double [,][] t2 = new double[3,2][]; 

background image

 

Inicjalizacja tablic 

 

 

Podczas tworzenia tablicy (obiektu tablicowego), wszystkim jej elementom 
przypisywana jest niejawnie wartość reprezentująca zero danego typu. Dla 
typów liczbowych jest to 0, dla typu logicznego false, dla typów 
referencyjnych null. W języku C# podczas tworzenia tablicy, można również 
nadać własne wartości poszczególnym elementom tablicy. Jeżeli 
zdecydowaliśmy się na ustawienie wartości elementów tablicy, musimy podać 
wartości dla wszystkich elementów tablicy. Poszczególne wartości oddzielamy 
przecinkami i umieszczamy w nawiasach klamrowych np.: 

string [] zwierzeta = new string[3]{"lis", "lew",  
 

 

 

 

 

 

 

"kot"}; 

Pierwszemu elementowi tablicy zostanie nadana wartość lis, drugiemu lew, 
trzeciemu kot. W przypadku, gdy podczas tworzenia tablicy podajemy 
wartości elementów tablicy, rozmiar musi być znany w czasie kompilacji - musi 
być wartością stałą. Rozmiar można jednak pominąć, kompilator sam wyliczy 
rozmiar: 

string [] zwierzeta = new string[]{"lis", "lew",  
 

 

 

 

 

 

 

"kot"}; 

Zapis utworzenia zainicjalizowanej tablicy można jeszcze bardziej uprościć, 
pomijając część new typ[rozmiar]: 

string [] zwierzeta = {"lis", "lew", "kot"}; 

W przypadku, gdy tablicę nie tworzymy w miejscu deklaracji zmiennej 
tablicowej, ale w dalszej części programu, dopuszczalne są formy:  

background image

 

const int IloscZwierzat = 3; 
string [] zwierzeta; 
... 
zwierzeta = new string[IloscZwierzat]{"lis", 
 

 

 

 

 

 

"lew", "kot"}; 

oraz 

string [] zwierzeta; 
... 
zwierzeta = new string[]{"lis", "lew", "kot"}; 

Poniższy zapis natomiast spowoduje błąd kompilatora: 

string [] zwierzeta; 
... 
zwierzeta = {"lis", "lew", "kot"};  

//błąd 

Tablice wielowymiarowe można również inicjalizować. Wykonuje się to w 
następujący sposób: 

string [,] zwierzeta = { 
 

{"kruk", "bocian", "orzeł"},  

 

{"lis", "lew", "kot"}, 

 

{"pszczoła", "osa", "komar"} 

}; 

 

// tablica 3x3 

lub (z tym że przykład dla tablicy trójwymiarowej) 

string [,,] zwierzeta; 
... 
zwierzeta = new string[,,]{ 
 

{{"kura", "gęś"}, {"orzeł", "sokół"}}, 

 

{{"pies", "kot"}, {"lew", "tygrys"} },  

 

{{"pszczoła","jedwabnik"},{"osa","komar"}} 

}; 

 

// tablica 3x2x2 

W przypadku tablic regularnych oczywiście trzeba pamiętać o jednakowej 
liczbie elementów w poszczególnych wymiarach 

Tablice nieregularne tworzymy w następujący sposób: 

string [][] zwierzeta = { 
 

new string[]{"lew","tygrys"}, 

 

new string[]{"kruk", "sęp", "orzeł", "gil"}, 

 

new string[]{"osa"} 

}; 

lub (z tym że przykład dla tablicy trójwymiarowej) 

string [][][] zwierzeta; 
... 
zwierzeta = new string[][][]{ 
 

new string[][]{ 

 

 

new string[]{"pies", "kot","koń"}, 

 

 

new string[]{"tygrys"} 

 

 

new string[][]{ 

 

 

new string[]{"kura", "gęś", "indyk"} 

background image

 

 

}; 

Jak widać w powyższym przykładzie, podtablice tablicy tablic, czyli składowe 
tablicy nieregularnej, musimy tworzyć przy pomocy operatora new. 

 

background image

 

Korzystanie z tablic 

 

 

Do pojedynczego elementu tablicy uzyskuje się dostęp przy pomocy operatora 
indeksowania. W języku C# operatorem indeksowania są nawiasy kwadratowe 
[]. W każdym wymiarze elementy tablicy indeksujemy od wartości zero do 
rozmiaru danego wymiaru minus jeden. Czyli jeżeli utworzymy tablicę 
jednowymiarową o trzech elementach: 

char tab = new char[3]; 

to:  

 

tab[0] - pierwszy element tablicy 

 

tab[1] - drugi element tablicy 

 

tab[2] - trzeci, ostatni element tablicy 

Jeżeli w programie nastąpi odwołanie do nieistniejącego elementu tablicy, czyli 
do elementu o indeksie mniejszym od zera albo o wartości indeksu większej lub 
równej liczbie elementów w danym wymiarze, spowoduje to zgłoszenie 
wyjątku IndexOutOfRangeException. 

W przypadku tablic wielowymiarowych regularnych, aby uzyskać dostęp do 
elementu tablicy stosujemy następującą notację: 

int [,] tab1 = {{1,2,3},{4,5,6}}; 
tab1[0,0] = 10; 
Console.WriteLine(tab1[1,1]); 

//5 

//tab[2][0] //nie ma takiego elementu 
 

 

 

//byłby zgłoszony wyjątek 

background image

 

Dla tablic nieregularnych używamy następującą notację 
 
int [][] tab2 = { 
  

new int[]{1,2,3}, 

  

new int[]{4,5,6} 

}; 
tab2[0][0] = 10; 
Console.WriteLine(tab1[1][2]); 

//6 

//tab[1][3] //nie ma takiego elementu, 
  

 

//byłby zgłoszony wyjątek 

Uwaga: 
W języku C# istnieje możliwość utworzenia tablicy, której dolny indeks jest 
różny od wartości zero. Można to wykonać przy pomocy jednej z metod 
CreateInstance klasy Array. 

 

background image

 

Właściwości tablic 

 

 

O tablicach w języku C#, można powiedzieć, że są strukturami samo 
opisującymi się. Przy pomocy nazwy zmiennej tablicowej, można uzyskać 
informację na temat liczby jej wszystkich elementów, liczby wymiarów tablicy, 
liczby elementów w poszczególnych rozmiarach.  

Uwaga: 
Informacje opisane powyżej możemy uzyskać przy pomocy właściwości lub 
wywołania metody na rzecz jakiegoś obiektu tablicowego. Właściwości oraz 
metody wywoływane na rzecz obiektu danej klasy zostaną dokładnie omówione 
w kursie "Programowanie obiektowe". 

W celu uzyskania informacji na temat liczby wymiarów korzystamy z 
właściwości Rank. 

int [] tab1 = new int[3]; 
Console.WriteLine(tab1.Rank); 

int [,,] tab2 = new int[3,2,2]; 
Console.WriteLine(tab2.Rank); 

Na ekranie zostanie wypisane: 


W przypadku tablic nieregularnych, tablica jest traktowana jako tablica 
jednowymiarowa, której elementami są tablice. Poniższy kod spowoduje, więc 
wypisanie na ekranie wartości 1

background image

 

int [][][] tab3 = new int[4][][]; 
Console.WriteLine(tab3.Rank); 

 

Właściwość Length oraz LongLength służą do otrzymania liczby 
wszystkich elementów tablicy.  

int [] tab1 = new int[3]; 
Console.WriteLine(tab1.Length); 

int [,,] tab2 = new int[3,2,2]; 
Console.WriteLine(tab2.Length); 

Na ekranie zostanie wypisane: 


12 

W przypadku tablic nieregularnych, podobnie jak wcześniej, tablica jest 
traktowana jako tablica jednowymiarowa, której elementami są tablice. 
Właściwość Length zawiera, więc liczbę podtablic. Poniższy kod spowoduje 
wypisanie na ekranie wartości 2

int [][]tab3 = new int[2][]{ 
 

new int[4], new int[7]}; 

Console.WriteLine(tab3.Length); 

I oczywiście 

... 
Console.WriteLine(tab3[0].Length); 
Console.WriteLine(tab3[1].Length); 

spowoduje pojawienie się na ekranie: 


 

W celu uzyskania liczby elementów w poszczególnych wymiarach korzysta się 
z metody GetLength lub GetLongLength. Wymiary indeksujemy od 
wartości zero: 

int [,,] tab2 = new int[3,8,2]; 
Console.WriteLine(tab2. GetLength(0)); //pierwszy wym. 
Console.WriteLine(tab2. GetLength(1)); //drugi wym. 
Console.WriteLine(tab2. GetLength(2)); //trzeci wym. 

Na ekranie zostanie wypisane: 



Odwołanie się do nieistniejącego wymiaru spowoduje zgłoszenie wyjątku 
IndexOutOfRangeException. 

background image

 

Użycie tablicy z pętlą foreach 

 

 

Załóżmy, że jest potrzebne wypisanie wartości wszystkich elementów tablicy. 
Kod przy pomocy instrukcji for mógłby wyglądać następująco: 

int [] t = new int[10]; 
... 
for(int i = 0; i<t.Length; i++) 

   Console.Write ("{0}, ",t[i]); 

Dla tablicy dwuwymiarowej natomiast: 

int [,] tt = new int[10,20]; 
... 
for(int i = 0; i<tt.GetLength(0); i++) 

   for(int j = 0; j<tt.GetLength(1); j++) 
   { 
      Console.Write("{0}, ", tt[i,j]); 
   } 

Powyższy kod można również zapisać przy pomocy instrukcji foreach 

int [] t = new int[10]; 
... 
foreach(int element in t) 

background image

 

   Console.WriteLine("{0}", element); 

oraz dla tablicy dwuwymiarowej regularnej: 

int [,] tt = new int[10,20]; 
... 
foreach(int element in tt) 

   Console.Write("{0}, ",element); 

Korzystając z pętli foreach, myślimy raczej o wykonaniu pewnej grupy 
instrukcji dla każdego elementu tablicy, niż o wykonaniu pewnej grupy 
instrukcji określoną ilość razy.  

W nawiasach okrągłych, występujących obok słowa foreach, deklarujemy 
zmienną, która w bloku instrukcji reprezentuje aktualnie przetwarzany element 
tablicy. Zmienną tą nazywamy zmienną iteracyjną pętli foreach. Typ 
zmiennej iteracyjnej musi być identyczny z typem elementu tablicy lub musi 
istnieć do niego konwersja niejawna z typu elementu tablicy. Jako zmiennej 
iteracyjnej nie można użyć zmiennej zadeklarowanej wcześniej w programie. 
Wartości zmiennej iteracyjnej nie można zmieniać, jest tylko do odczytu. 

Uwaga: 
W nawiasach okrągłych, występujących obok słowa foreach, po słowie in, 
mogą występować zmienne zawierające uchwyt do obiektów klas kolekcji. 
Klasy kolekcji w języku C#, są to klasy, które implementują interfejs 
IEnumerable lub posiadają odpowiednią metodę GetEnumerator. 
Więcej na temat interfejsów można znaleźć w kursie "Programowanie 
obiektowe". 

background image

 

Pytania sprawdzające 

 

 

1.  Jak są indeksowane tablice w języku C#? 

 
Odp. 
Tablice w języku C# indeksowane są od wartości zero do n, gdzie n jest 
rozmiarem danego wymiaru. 

2.  Jaki błąd popełniono w poniższym kodzie? 

 
string [] jeziora; 
jeziora = {"Śniardwy", "Mamry", "Bajkał"}; 
 
Odp. 
Tablice można tworzyć bez użycia słowa new, tylko w miejscu deklaracji 
zmiennej tablicowej. Powyższy kod należy zapisać: 
 
string [] jeziora; 
jeziora=new string[]{"Śniardwy","Mamry","Bajkał"}; 
 
lub 
 
string [] jeziora={"Śniardwy", "Mamry", "Bajkał"}; 

3.  Co się stanie, gdy odwołamy się do nieistniejącego elementu tablicy? 

 
Odp. 
W momencie próby odwołania się do nieistniejącego elementu tablicy 
zostanie zgłoszony wyjątek IndexOutOfRangeException. 

background image

 

4. 

Utwórz pięcioelementową tablicę liczb całkowity i zainicjalizuj ją kolejnymi 
liczbami naturalnymi nieparzystymi. 
 
Odp. 
byte [] liczby = {1,3,5,7,9}; 

5.  Jaki błąd popełniono w poniższym kodzie? 

 
int [] numery = {13, 44, 777, 818}; 
... 
foreach(int el in numery) 
 

el++; 

 
Odp. 
Zmienna iteracyjna pętli foreach jest zmienną tylko do odczyt i nie 
można zmieniać jej wartości. 

background image

 

Laboratorium 

 

 

Ćwiczenie 1: 
Napisz program, który znajduje największy i najmniejszy element tablicy. 
Tablicę zainicjalizuj liczbami pseudolosowymi, korzystając z generatora liczb 
pseudolosowych: 

Random r = new Random();  //utworzenie obiektu  
 

 

 

//generatora liczb pseudolosowych 

int n = r.Next(0,101);    //losowanie liczby z  
 

 

 

//przedziału <0;100> 

 

1.  Uruchom Visual Studio 

Naciśnij przycisk Start systemu Windows, wybierz Wszystkie Programy 
następnie Microsoft Visual Studio 2005/ Microsoft Visual Studio 2005

2.  Utwórz nowy projekt 

a.  Z menu File wybierz New/Project... 

b.  W oknie dialogowym New Project określ następujące właściwości: 

i.  typu projektu: Visual C#/Windows  

ii.  szablon: Console Application  

iii.  lokalizacja: Moje Dokumenty\Visual Studio 2005\Projects\ 

iv.  nazwa projektu: MaxMin.  

v.  nazwa rozwiązania: Lab6 

background image

 

3.  Wewnątrz metody Main napisz następujący kod: 

a.  Utwórz obiekt tablicy piętnastoelementowej liczb całkowitych. 

 
int [] tablica = new int[15]; 

b.  Nadaj elementom tablicy wartości losowe z przedziału od zera do stu, 

korzystając z generatora liczb pseudolosowych.  
 
Random generator = new Random(); 
for(int i = 0; i < tablica.Length; i++) 

   tablica[i] = generator.Next(0,101); 

c.  Wypisz wartości elementów tablicy korzystając z pętli foreach. 

 
Console.WriteLine("Wylosowano następujące  
 

 

¬wartości"); 

foreach(int i in tablica) 

   Console.Write("{0}, ", i); 

d.  Zadeklaruj zmienną indexMax i ustaw jej wartość na wartość zero. 

Dla każdego elementu tablicy sprawdzaj, czy jego wartość jest większa 
od wartości elementu tablicy o indeksie indexMax. Jeżeli jest 
większa, ustaw wartość zmiennej indexMax na numer jego indeksu. 
 
int indexMax = 0; 
for(int i = 1; i < tablica.Length; i++) 

   if(tablica[indexMax] < tablica[i]) 
   { 
      indexMax = i; 
   } 

e.  Zadeklaruj zmienną indexMin i ustaw jej wartość na wartość zero. 

Dla każdego elementu tablicy sprawdzaj, czy jego wartość jest 
mniejsza od wartości elementu tablicy o indeksie indexMin. Jeżeli 
jest mniejsza, ustaw wartość zmiennej indexMin na numer jego 
indeksu. 
 
int indexMin = 0; 
for(int i = 1; i < tablica.Length; i++) 

   if(tablica[indexMin] > tablica[i]) 
   { 
      indexMin = i; 
   } 

 

f.  Uwaga: 

Wyznaczenie numeru indeksu elementu maksymalnego i minimalnego 
można oczywiście wykonać w pojedynczej pętli: 
 

background image

 

int indexMax = 0; 
int indexMin = 0; 
for(int i = 1; i < tablica.Length; i++) 

   if(tablica[indexMin] > tablica[i]) 
   { 
      indexMin = i; 
   } 
   if(tablica[indexMax] < tablica[i]) 
   { 
      indexMax = i; 
   } 

g.  Wypisz na ekranie wartości elementu największego i najmniejszego 

oraz numery ich indeksów. Zatrzymaj program, aby użytkownik mógł 
obejrzeć wyniki: 
 
Console.WriteLine("\n\nElemnt najmniejszy o  
 

 

¬indeksie {0} posiada wartość {1}.", 

 

 

 

indexMin, tablica[indexMin]); 

Console.WriteLine("Elemnt największy o indeksie  
 

 

¬{0} posiada wartość {1}.", 

 

 

 

indexMax, tablica[indexMax]); 

Console.ReadKey(); 

4.  Skompiluj i uruchom program. 

Ćwiczenie 2 
Utwórz programu, który oblicza iloczyn dwóch macierzy. Wartości elementów 
macierzy są podawane przez użytkownika.  

Wartości elementów macierzy C = A x B, można wyliczyć ze wzoru: 

 

 

N - liczba wierszy macierzy A i C. 
M - liczba kolumn macierzy B i C 
K - liczba kolumn macierzy A i liczba wierszy macierzy B 

 

1.  Dodaj do bieżącego rozwiązania nowy projekt 

a.  Z menu File wybierz Add/New Project... 

b.  W oknie dialogowym Add New Project określ następujące 

właściwości: 

i. 

typu projektu: Visual C#/Windows  

ii. 

szablon: Console Application  

iii. 

nazwa projektu: MnozenieMacierzy. 

2.  Uczyń nowo utworzony projekt projektem startowym 

a.  Zaznacz projekt MnozenieMacierzy w okienku Solution Explorer i z 

menu kontekstowego wybierz Set as StartUp Project. 

M

j

N

i

gdzie

b

a

c

K

k

kj

ik

ij

...

1

;

...

1

,

1

background image

 

albo, gdy rozpoczynasz laboratorium od tego ćwiczenia 

1.  Uruchom Visual Studio 

Naciśnij przycisk Start systemu Windows, wybierz Wszystkie Programy 
następnie Microsoft Visual Studio 2005/ Microsoft Visual Studio 2005

2.  Utwórz nowy projekt 

a.  Z menu File wybierz New/Project... 

b.  W oknie dialogowym New Project określ następujące właściwości: 

i.  typu projektu: Visual C#/Windows  

ii.  szablon: Console Application  

iii.  lokalizacja: Moje Dokumenty\Visual Studio 2005\Projects\ 

iv.  nazwa projektu: MnozenieMacierzy.  

v.  nazwa rozwiązania: Lab6 

3.  Wewnątrz metody Main napisz następujący kod: 

a.  Zadeklaruj trzy stałe całkowite reprezentujące odpowiednio 

i.  N - liczba wierszy macierzy A i C. 

ii.  M - liczba kolumn macierzy B i C 

iii.  K - liczba kolumn macierzy A i liczba wierszy macierzy B 

 
const int N = 3; 
const int M = 3; 
const int K = 2; 

b.  Zdefiniuj trzy tablice dwuwymiarowe o rozmiarach: NxK, KxM oraz 

NxM. 
 
double [,] macierzA = new double[N,K]; 
double [,] macierzB = new double[K,M]; 
double [,] macierzC = new double[N,M]; 

c. 

Pobierz od użytkownika wartości elementów macierzy A oraz 
macierzy B. 
 
Console.WriteLine("Podaj elementy macierzy A."); 
for(int i=0; i<N; i++) 

   for(int j=0; j<K; j++) 
   { 
      Console.Write("A[{0},{1}] = ", i+1,j+1); 
      macierzA[i,j] = Convert.ToDouble(  
 

 

 

Console.ReadLine() ); 

   } 

Console.WriteLine("Podaj elementy macierzy B."); 
for(int i=0; i<K; i++) 

   for(int j=0; j<M; j++) 
   { 

background image

 

      Console.Write("B[{0},{1}] = ", i+1,j+1); 
      macierzB[i,j] = Convert.ToDouble(  
 

 

 

Console.ReadLine() ); 

   } 

d. 

Oblicz elementy macierzy C. 
 
for(int i = 0; i<N; i++) 

  for(int j = 0; j<M; j++) 
  { 
    macierzC[i,j] = 0; 
    for(int k=0; k<K; k++) 
    { 
      macierzC[i,j]+=macierzA[i,k]*macierzB[k,j]; 
    } 
  } 

Uwaga: 
W bieżącym programie linijka macierzC[i,j] = 0; jest zbyteczna, 
ponieważ domyślnie wszystkie elementy macierzy C zostały 
zainicjalizowane wartością zero. Umieszczenie jej ma na celu pokazanie 
ogólnego algorytmu mnożenia macierzy, również wtedy, gdy elementy 
macierzy wynikowej nie mają wartości zero. 

e.  Wypisz elementy macierzy C. Zatrzymaj program, aby użytkownik 

mógł obejrzeć wyniki: 
 
Console.WriteLine("\nWynikiem mnożenia podanych  
 

 

¬macierzy jest macierz:"); 

for(int i = 0; i<macierzC.GetLength(0); i++) 

  for(int j = 0; j<macierzC.GetLength(1); j++) 
  { 
    Console.Write("{0,10}, ", macierzC[i, j]); 
  } 
  Console.WriteLine(); 

Console.ReadKey(); 

4.  Skompiluj i uruchom program. 

Ćwiczenie 3 
Napisz program, które losuje sześć różnych liczb całkowitych z przedziału 
<1;49>. 
 

1.  Dodaj do bieżącego rozwiązania nowy projekt 

a.  Z menu File wybierz Add/New Project... 

b.  W oknie dialogowym Add New Project określ następujące 

właściwości: 

i. 

typu projektu: Visual C#/Windows  

ii. 

szablon: Console Application  

background image

 

iii. 

nazwa projektu: TotoLotek. 

2.  Uczyń nowo utworzony projekt projektem startowym 

a.  Zaznacz projekt TotoLotek w okienku Solution Explorer i z menu 

kontekstowego wybierz Set as StartUp Project. 

albo, gdy rozpoczynasz laboratorium od tego ćwiczenia 

1.  Uruchom Visual Studio 

Naciśnij przycisk Start systemu Windows, wybierz Wszystkie Programy 
następnie Microsoft Visual Studio 2005/ Microsoft Visual Studio 2005

2.  Utwórz nowy projekt 

a.  Z menu File wybierz New/Project... 

b.  W oknie dialogowym New Project określ następujące właściwości: 

i.  typu projektu: Visual C#/Windows  

ii.  szablon: Console Application  

iii.  lokalizacja: Moje Dokumenty\Visual Studio 2005\Projects\ 

iv.  nazwa projektu: TotoLotek.  

v.  nazwa rozwiązania: Lab6 

3.  Wewnątrz metody Main napisz następujący kod: 

a.  Zdefiniuj tablicę jednowymiarową, która będzie zawierać sześć 

wylosowanych liczb: 
 
byte [] numery = new byte[6]; 

b.  Wypełnij tablicę liczbami wylosowanymi przez generator liczb 

pseudolosowych. Zanim przejdziesz do losowania następnej liczby 
sprawdź, czy wylosowana liczba, nie była wylosowana wcześniej. 
Jeżeli dana liczba była już wylosowana wcześniej, powtórz losowanie 
dla danego elementu tablicy. 
 
Random generator = new Random(); 
int index = 0; 

//ile wylosowano liczb 

int i; 
bool flaga; 
do 

   numery[index] = (byte)generator.Next(1,50); 
   flaga = true; 
   for(i=0; i<index; i++) 
   { 
      if(numery[index] == numery[i]) 
      { 
         flaga = false; 
         break; 
      } 
   } 
   if(flaga) 
   { 
      index++; 

background image

 

   } 

while(index<6); 

c.  Wypisz wylosowane liczby. Zatrzymaj program, aby użytkownik mógł 

obejrzeć wyniki. 
 
Console.WriteLine("Wylosowane liczby to:"); 
foreach(int numer in numery) 

   Console.Write("{0}, ",numer); 

Console.ReadKey(); 

4.  Skompiluj i uruchom program. 

Ćwiczenie 4 
Napisz programu, który będzie wyznaczał wszystkie liczby pierwsze w 
zadanym przedziale. Program będzie korzystał z algorytmu zwanego sitem 
Eratostenesa. Algorytm ten polega na tym, że tworzymy zbiór wszystkich liczb 
naturalnych z danego przedziału większych lub równych dwa. Następnie 
wybieramy ze zbioru najmniejszą liczbę, czyli dwa i usuwamy wszystkie jej 
wielokrotności. Wybrana liczba jest liczbą pierwszą. Po usunięciu ze zbioru 
wszystkich wielokrotności liczby dwa, wybieramy kolejną najmniejszą liczbę. 
Będzie to kolejna liczba pierwsza. Usuwamy jej wszystkie wielokrotności i 
znowu wybieramy najmniejszą liczbą ze zbioru i usuwamy jej wielokrotności. 
Czynności wybierania i usuwania powtarzamy, dopóki nie opróżnimy zbioru. 
Wybrane liczby będą szukanymi liczbami pierwszymi. 

Implementacja tego algorytmu polega na utworzeniu tablicy logicznej o liczbie 
elementów równej ilości liczb naturalnych większych lub równych dwa w 
danym przedziale. Pierwszy element tablicy odpowiada liczbie dwa, drugi 
liczbie trzy itd. Zakładamy, że wszystkie liczby są liczbami pierwszymi, co 
realizujemy przez ustalenie jednakowej wartości dla wszystkich elementów 
tablicy - np. false gdyż tak domyślnie są inicjalizowane elementy tablic 
logicznych. Wybieramy pierwszy element tablicy, który ma wartość false. 
Jest to oczywiście pierwszy element tablicy, który reprezentuje liczbę dwa. 
Usunięcie wielokrotności liczby dwa, będzie polegało na nadaniu elementom 
tablicy reprezentującym te wielokrotności wartości true, bez zmieniania 
wartości wybranego elementu. Po nadaniu wszystkim elementom tablicy 
reprezentującym wielokrotność liczby dwa wartości true, wybieramy kolejny 
element tablicy o wartości false. Wartość elementów tablicy 
reprezentujących wielokrotności wybranego elementu ustawiamy na true. 
Czynności wyboru elementu i ustawienia wartości elementów reprezentujących 
jego wielokrotności na true, powtarzamy aż do momentu, gdy nie mamy do 
wyboru następnego elementu tablicy, którego wartość jest równa false. 
Elementy tablicy, które mają wartość false, reprezentują liczby pierwsze w 
danym przedziale. 

Do algorytmu powyższego warto dodać pewne usprawnienia. Niektóre liczby 
są wielokrotnościami kilku liczb i nadawanie elementom je reprezentującym 
wartości true (usuwanie) wykonywane jest wiele razy. Zupełnie nie uda nam 
się tego zlikwidować, ale można to zoptymalizować.  
Pierwszą wielokrotnością, którą będziemy "usuwać", będzie wartość równa 
kwadratowi wybranej liczby pierwszej, ponieważ mniejsze wielokrotności 
musiały być równe iloczynowi wybranej liczby pierwszej i liczby od niej 
mniejszej, więc musiały juz być "usunięte" wcześniej.  

background image

 

Wybieranie liczb pierwszych należy zakończyć po osiągnięciu pierwiastka 
kwadratowego końca przedziału. Wybór większej liczby nie powoduje już 
"usunięcia" więcej wielokrotności - patrz pierwsza optymalizacja. 

 

1.  Dodaj do bieżącego rozwiązania nowy projekt 

a.  Z menu File wybierz Add/New Project... 

b.  W oknie dialogowym Add New Project określ następujące 

właściwości: 

i.  typu projektu: Visual C#/Windows  

ii.  szablon: Console Application  

iii.  nazwa projektu: LiczbyPierwsze. 

2.  Uczyń nowo utworzony projekt projektem startowym 

a.  Zaznacz projekt LiczbyPierwsze w okienku Solution Explorer i z 

menu kontekstowego wybierz Set as StartUp Project. 

albo, gdy rozpoczynasz laboratorium od tego ćwiczenia 

1.  Uruchom Visual Studio 

Naciśnij przycisk Start systemu Windows, wybierz Wszystkie Programy 
następnie Microsoft Visual Studio 2005/ Microsoft Visual Studio 2005

2.  Utwórz nowy projekt 

a.  Z menu File wybierz New/Project... 

b.  W oknie dialogowym New Project określ następujące właściwości: 

i.   typu projektu: Visual C#/Windows  

ii.   szablon: Console Application  

iii.  lokalizacja: Moje Dokumenty\Visual Studio 2005\Projects\ 

iv.  nazwa projektu: LiczbyPierwsze.  

v.  nazwa rozwiązania: Lab6 

3.  Wewnątrz metody Main napisz następujący kod: 

a.  Pobierz od użytkownika górną granicę przedziału, z którego chce 

wypisać wszystkie liczby pierwsze. 
 
ulong n; 
Console.WriteLine("Podaj górną granicę 
 

 

¬ przedziału, z którego chcesz wypisać 

 

 

¬ wszystkie liczby pierwsze."); 

Console.Write("Liczba nie może być większa od  
 

 

¬{0}: ", ulong.MaxValue); 

n = Convert.ToUInt64(Console.ReadLine()); 

b.  Zadeklaruj tablicę logiczną o n-1 elementach. 

 
bool[] liczby = new bool[n-1]; 
 

background image

 

W wyniku powyższej deklaracji, każdy element tablicy ma nadaną 
domyślnie wartość false. Tablica o rozmiarze n-1, bo nie bierzemy 
pod uwagę liczby jeden. 

c.  Dla wszystkich liczb całkowitych od liczby dwa do liczby równej 

pierwiastkowi kwadratowemu z wartości końca przedziału, wykonuj co 
następuje: 

i.  Sprawdź czy wartość elementu reprezentującą wybraną liczbę jest 

równa false. 

ii.  Jeżeli wartość jest równa false, ustaw wartości elementów tablicy 

reprezentujących wielokrotności wybranej liczby na wartość 
false. Rozpocznij od liczby równej kwadratowi wybranej liczby. 

iii.  Następnie przejdź do następnej liczby. 

ulong m = (uint)Math.Sqrt(n); 
ulong index; 
for (ulong i = 2; i <= m; i++) 

   if (!liczby[i - 2]) 
   { 
      index = i * i - 2; 
      while (index < n - 1) 
      { 
         liczby[index] = true; 
         index += i; 
      } 
   } 

d. 

Wypisz liczby pierwsze z zadanego przedziału: 
 
Console.WriteLine("Liczby pierwsze z podanego 
 

 

¬ przedziału to:"); 

int j=0; 
for(ulong i=0;i<n-1;i++) 

   if(!liczby[i]) 
   { 
      Console.Write("{0,22}, ", i + 2); 
      j++; 
      if (j % 2 == 0) 
         Console.WriteLine(); 
      if (j % (2*Console.WindowHeight) == 0) 
         Console.ReadKey(); 
   } 

Console.Write("\nLiczb pierwszych w podanym  
 

 

¬zakresie jest {0}", j); 

Console.ReadKey(); 

4.  Skompiluj i uruchom program.