Professional Documents
Culture Documents
C Zadania Z Programowania Z Przykladowymi Rozwiazaniami Wydanie III Miroslaw J Kubiak Helion
C Zadania Z Programowania Z Przykladowymi Rozwiazaniami Wydanie III Miroslaw J Kubiak Helion
Kubiak
C#
Zadania z programowania
z przykładowymi rozwiązaniami
WYDANIE III
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości
lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione.
Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie
książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie
praw autorskich niniejszej publikacji.
Helion S.A.
ul. Kościuszki 1c, 44-100 Gliwice
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/cshza3_ebook
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
ISBN: 978-83-283-8673-0
8ba61431c02548173fa6085d93015e5a
8
Spis treści
Od autora 5
Rozdział 1. Jak język C# komunikuje się z użytkownikiem? 9
Informacje ogólne 9
Obsługa sytuacji wyjątkowych 18
8ba61431c02548173fa6085d93015e5a
8
4 Spis treści
8ba61431c02548173fa6085d93015e5a
8
Od autora
Drugie wydanie książki C#. Zadania z programowania z przykładowymi roz-
wiązaniami ukazało się nakładem wydawnictwa Helion w 2018 roku.
W trzecim wydaniu wymieniłem wszystkie listingi programów i uaktual-
niłem je do wersji C# 8.0 i C# 9.0. Dodałem rozdział 8. poświęcony progra-
mowaniu funkcyjnemu w C#.
Wszystkie programy zawarte w tej książce zostały skompilowane w bezpłat-
nym, nowoczesnym i w pełni zintegrowanym środowisku programistycznym
Microsoft Visual Studio Community 20191.
Wyjściowy wzorzec kodu programu dla kompilatora Visual C# jest nastę-
pujący:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
8ba61431c02548173fa6085d93015e5a
8
6 C#. Zadania z programowania z przykładowymi rozwiązaniami
Mirosław J. Kubiak
8ba61431c02548173fa6085d93015e5a
8
Od autora 7
8ba61431c02548173fa6085d93015e5a
8
8 C#. Zadania z programowania z przykładowymi rozwiązaniami
pole = a * b;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 1.
Jak język C#
komunikuje się
z użytkownikiem?
W tym rozdziale zamieściłem proste zadania, wraz z przykładowymi rozwią-
zaniami, ilustrujące, w jaki sposób komputer komunikuje się z użytkownikiem
w języku C#.
Informacje ogólne
Każda aplikacja powinna mieć możliwość komunikowania się z użytkowni-
kiem. Za pomocą prostych przykładów pokażę, w jaki sposób program
napisany w języku C# komunikuje się z użytkownikiem poprzez standar-
dowe operacje wejścia – wyjścia.
Operacje wejścia – wyjścia w języku C# są realizowane przez strumienie.
Strumień jest pojęciem abstrakcyjnym. Może on wysyłać i pobierać infor-
macje i jest połączony z fizycznym urządzeniem (np. z klawiaturą czy ekra-
nem) poprzez system operacji wejścia – wyjścia.
W języku C# zdefiniowano dwa typy strumieni: bajtowe i znakowe. Trzy
predefiniowane strumienie są dostępne przez właściwości Console.In,
Console.Out i Console.Error dla wszystkich programów korzystających
8ba61431c02548173fa6085d93015e5a
8
10 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 1. ♦ Jak język C# komunikuje się z użytkownikiem? 11
8ba61431c02548173fa6085d93015e5a
8
12 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 1.1.
Efekt działania Program oblicza pole prostokąta.
programu Podaj bok a.
1,02
Zadanie 1.1
Podaj bok b.
2
Pole prostokąta o boku a = 1,02 i boku b = 2 wynosi 2,04.
Zadanie
1.2 Napisz program, który wyświetla na ekranie komputera wartość predefi-
niowanej stałej π = 3,14...; należy przyjąć format wyświetlania tej stałej
z dokładnością do pięciu miejsc po przecinku.
Listing 1.2. Przykładowe rozwiązanie
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 1. ♦ Jak język C# komunikuje się z użytkownikiem? 13
W programie zapis:
Console.WriteLine("Pi = {0:#.#####}.", Math.PI);
Rysunek 1.2.
Efekt działania Program wyświetla stałą pi z zadaną dokładnością.
programu Pi = 3,14159.
Zadanie 1.2
2 Zobacz rozdział 8.
8ba61431c02548173fa6085d93015e5a
8
14 C#. Zadania z programowania z przykładowymi rozwiązaniami
Zadanie
1.3 Napisz program, który wyświetla na ekranie komputera pierwiastek kwa-
dratowy z wartości predefiniowanej π = 3,14... z dokładnością do dwóch
miejsc po przecinku.
Listing 1.3. Przykładowe rozwiązanie
using System;
using static System.Math;
Rysunek 1.3.
Efekt działania Program wyświetla pierwiastek kwadratowy z liczby pi
programu z dokładnością do dwóch miejsc po przecinku.
Sqrt(pi) = 1,77.
Zadanie 1.3
Zadanie
1.4 Napisz program, który oblicza objętość kuli o promieniu r. Wartość promie-
nia r wprowadzamy z klawiatury. W programie należy przyjąć, że zmienne
promień r i objętość są typu double (typu rzeczywistego). Dla tych zmiennych
należy przyjąć format wyświetlania ich na ekranie z dokładnością do dwóch
miejsc po przecinku.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 1. ♦ Jak język C# komunikuje się z użytkownikiem? 15
Rysunek 1.4.
Efekt działania Program oblicza objętość kuli o promieniu r.
programu Podaj promień r.
1
Zadanie 1.4
Objętość kuli o promieniu r = 1 wynosi 4,19.
Zadanie
1.5 Napisz program, który oblicza wynik dzielenia całkowitego bez reszty dla
dwóch liczb całkowitych: a = 37 i b = 11.
8ba61431c02548173fa6085d93015e5a
8
16 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
Rysunek 1.5.
Efekt działania Program wyświetla wynik dzielenia całkowitego
programu bez reszty dla dwóch liczb całkowitych.
Zadanie 1.5
Dla liczb a = 37 i b = 11
37/11 = 3.
Zadanie
1.6 Napisz program, który oblicza resztę z dzielenia całkowitego dwóch liczb cał-
kowitych: a = 37 i b = 11.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 1. ♦ Jak język C# komunikuje się z użytkownikiem? 17
{
static void Main(string[] args)
{
int a = 37; int b = 11;
Rysunek 1.6.
Efekt działania Program oblicza resztę z dzielenia całkowitego
programu dwóch liczb całkowitych.
Zadanie 1.6
Dla liczb a = 37 i b = 11
37%11 = 4.
Zadanie
1.7 Napisz program, który oblicza sumę, różnicę, iloczyn i iloraz dla dwóch liczb,
x i y, wprowadzanych z klawiatury. W programie przyjmujemy, że zmienne
x i y są typu double (typu rzeczywistego). Wszystkie zmienne należy wyświetlić
z dokładnością do dwóch miejsc po przecinku.
Listing 1.7. Przykładowe rozwiązanie
using System;
8ba61431c02548173fa6085d93015e5a
8
18 C#. Zadania z programowania z przykładowymi rozwiązaniami
x = double.Parse(Console.ReadLine());
Console.WriteLine("Podaj y.");
y = double.Parse(Console.ReadLine());
suma = x + y;
różnica = x - y;
iloczyn = x * y;
iloraz = x / y;
Rysunek 1.7.
Efekt działania Program oblicza sumę, różnicę, iloczyn i iloraz
programu dla dwóch liczb x i y wprowadzanych z klawiatury.
Podaj x.
Zadanie 1.7
12
Podaj y.
5
Dla x = 12 i y = 5
suma = 17,
różnica = 7,
iloczyn = 60,
iloraz = 2,4.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 1. ♦ Jak język C# komunikuje się z użytkownikiem? 19
gdzie TypWyjątku jest typem wyjątku, który wystąpił. Określenie exOb jest
opcjonalne.
Przykładową obsługę sytuacji wyjątkowych zilustruję w zadaniu 1.8, które
jest modyfikacją zadania 1.1.
Zadanie
1.8 Napisz program, który oblicza pole prostokąta. Wartości boków a i b wprowa-
dzamy z klawiatury. W programie należy przyjąć, że zmienne a, b oraz pole
są typu double (typu rzeczywistego). Dodatkowo do programu wbuduj ob-
sługę sytuacji wyjątkowych4.
3 Zob. rozdział 5.
4 Zachęcam Czytelnika, aby w ramach dodatkowych ćwiczeń utrwalających wszystkie pozo-
stałe programy zawarte w książce wyposażył w obsługę sytuacji wyjątkowych.
8ba61431c02548173fa6085d93015e5a
8
20 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
try
{
Console.WriteLine("Program oblicza pole prostokąta.");
Console.WriteLine("Podaj bok a.");
a = double.Parse(Console.ReadLine());
Console.WriteLine("Podaj bok b.");
b = double.Parse(Console.ReadLine());
catch (FormatException)
{
Console.WriteLine("Nie wczytano liczby. Koniec
´programu.");
}
}
}
}
pole = a * b;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 1. ♦ Jak język C# komunikuje się z użytkownikiem? 21
Rysunek 1.8.
Efekt działania Program oblicza pole prostokąta.
programu Podaj bok a.
a
Zadanie 1.8 Nie wczytano liczby. Koniec programu.
8ba61431c02548173fa6085d93015e5a
8
22 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 2.
Instrukcje sterujące
przebiegiem programu
— instrukcje wyboru
W tym rozdziale przedstawiłem typowe zadania, wraz z przykładowymi roz-
wiązaniami, wykorzystujące instrukcje wyboru.
Instrukcje wyboru
Instrukcje sterujące przebiegiem programu są jednym z najważniejszych
elementów w każdym języku programowania. Instrukcje te, w połączeniu
z wyrażeniami, umożliwiają zapisanie dowolnego algorytmu programu.
Instrukcje sterujące w języku C# można podzielić na:
instrukcje wyboru,
instrukcje iteracyjne (znane jako pętle),
instrukcje skoku.
W niniejszym rozdziale przedstawiam typowe zadania z wykorzystaniem
instrukcji wyboru, w rozdziale 3. natomiast zadania z wykorzystaniem
instrukcji iteracyjnych.
8ba61431c02548173fa6085d93015e5a
8
24 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 2. ♦ Instrukcje sterujące przebiegiem programu — instrukcje wyboru 25
break;
default : instrukcje;
}
Instrukcja break przerywa wykonanie całego bloku case. UWAGA: jej brak
może doprowadzić do uzyskania nieoczekiwanych wyników i pojawienia się
błędów w programie.
Zadanie
2.1 Napisz program, który dla trzech liczb, a, b, c, wprowadzonych z klawiatury
sprawdza, czy tworzą one trójkę pitagorejską.
using System;
if ((a * a + b * b) == c * c)
{
Console.Write("Liczby ");
Console.Write("a = " + a + ", ");
Console.Write("b = " + b + ", ");
Console.Write("c = " + c);
Console.WriteLine(" są trójką pitagorejską.");
}
else
{
Console.Write("Liczby ");
8ba61431c02548173fa6085d93015e5a
8
26 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 2.1.
Efekt działania Program sprawdza, czy wczytane liczby a, b, c to trójka pitagorejska.
programu Podaj a.
9
Zadanie 2.1
Podaj b.
12
Podaj c.
15
Liczby a = 9, b = 12, c = 15 są trójką pitagorejską.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 2. ♦ Instrukcje sterujące przebiegiem programu — instrukcje wyboru 27
Zadanie
2.2 Napisz program, który z wykorzystaniem instrukcji if oblicza pierwiastki
równania kwadratowego ax2 + bx + c = 0, w którym zmienne a, b, c to
liczby rzeczywiste wprowadzane z klawiatury. Wszystkie zmienne wyświe-
tlamy na ekranie z dokładnością do dwóch miejsc po przecinku.
Listing 2.2. Przykładowe rozwiązanie
using System;
using static System.Math;
if (a == 0)
{
Console.WriteLine("Niedozwolona wartość współczynnika
´a.");
}
else
{
Console.WriteLine("Podaj b.");
b = double.Parse(Console.ReadLine());
Console.WriteLine("Podaj c.");
c = double.Parse(Console.ReadLine());
delta = b * b - 4 * a * c;
if (delta < 0)
{
Console.WriteLine();
Console.Write("Dla ");
Console.Write("a = {0}, ", a);
Console.Write("b = {0}, ", b);
Console.Write("c = {0} ", c);
Console.Write("brak pierwiastków rzeczywistych.");
}
else
{
8ba61431c02548173fa6085d93015e5a
8
28 C#. Zadania z programowania z przykładowymi rozwiązaniami
if (delta == 0)
{
x1 = - b / (2 * a);
Console.WriteLine();
Console.Write("Dla ");
Console.Write("a = {0}, ", a);
Console.Write("b = {0}, ", b);
Console.Write("c = {0} ", c);
Console.WriteLine("trójmian ma jeden pierwiastek
´podwójny x1 = {0:##.##}.", x1);
}
else
{
x1 = (- b - Sqrt(delta)) / (2 * a);
x2 = (- b + Sqrt(delta)) / (2 * a);
Console.WriteLine();
Console.Write("Dla ");
Console.Write("a = {0}, ", a);
Console.Write("b = {0}, ", b);
Console.Write("c = {0} ", c);
Console.WriteLine("trójmian ma dwa
´pierwiastki: x1 = {0:##.##},
´x2 = {1:##.##}.", x1, x2);
}
}
}
}
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 2. ♦ Instrukcje sterujące przebiegiem programu — instrukcje wyboru 29
Rysunek 2.2.
Efekt działania Program oblicza pierwiastki równania ax^2 + bx + c = 0.
programu Podaj a.
1
Zadanie 2.2
Podaj b.
5
Podaj c.
4
Zadanie
2.3 Napisz program, który z wykorzystaniem instrukcji switch oblicza pier-
wiastki równania kwadratowego ax2 + bx + c = 0, w którym zmienne a, b, c
to liczby rzeczywiste wprowadzane z klawiatury. Wszystkie zmienne wyświe-
tlamy z dokładnością do dwóch miejsc po przecinku.
8ba61431c02548173fa6085d93015e5a
8
30 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
using static System.Math;
if (a == 0)
{
Console.WriteLine("Niedozwolona wartość współczynnika
´a.");
}
else
{
Console.WriteLine("Podaj b.");
b = double.Parse(Console.ReadLine());
Console.WriteLine("Podaj c.");
c = double.Parse(Console.ReadLine());
delta = b * b - 4 * a * c;
switch (liczba_pierwiastków)
{
case 0:
{
Console.WriteLine();
Console.Write("Dla ");
Console.Write("a = {0}, ", a);
Console.Write("b = {0}, ", b);
Console.Write("c = {0} ", c);
8ba61431c02548173fa6085d93015e5a
8
Rozdział 2. ♦ Instrukcje sterujące przebiegiem programu — instrukcje wyboru 31
Console.Write("brak pierwiastków
´rzeczywistych.");
}
break;
case 1:
{
x1 = - b / (2 * a);
Console.WriteLine();
Console.Write("Dla ");
Console.Write("a = {0}, ", a);
Console.Write("b = {0}, ", b);
Console.Write("c = {0} ", c);
Console.WriteLine("trójmian ma jeden
´pierwiastek podwójny x1 = {0: ##.##}.",
´x1);
}
break;
case 2:
{
x1 = (- b - Sqrt(delta)) / (2 * a);
x2 = (- b + Sqrt(delta)) / (2 * a);
Console.WriteLine();
Console.Write("Dla ");
Console.Write("a = {0}, ", a);
Console.Write("b = {0}, ", b);
Console.Write("c = {0} ", c);
Console.Write("trójmian ma dwa pierwiastki
´x1 = {0: ##.##} i ", x1);
Console.WriteLine("x2 = {0: ##.##}.", x2);
}
break;
}
}
}
}
}
8ba61431c02548173fa6085d93015e5a
8
32 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 2.3.
Efekt działania Program oblicza pierwiastki równania ax^2 + bx + c = 0.
programu Podaj a.
1
Zadanie 2.3
Podaj b.
4
Podaj c.
4
Zadanie
2.4 Napisz program, który oblicza wartość niewiadomej x z równania ax + b = c.
Wartości a, b, c należą do zbioru liczb rzeczywistych i są wprowadzane
z klawiatury. Dodatkowo należy zabezpieczyć program na wypadek sytuacji,
kiedy wprowadzona wartość a = 0. Wszystkie zmienne wyświetlamy z dokład-
nością do dwóch miejsc po przecinku.
if (a == 0)
{
Console.WriteLine("Niedozwolona wartość współczynnika
´a.");
}
else
{
Console.WriteLine("Podaj b.");
b = double.Parse(Console.ReadLine());
Console.WriteLine("Podaj c.");
c = double.Parse(Console.ReadLine());
8ba61431c02548173fa6085d93015e5a
8
Rozdział 2. ♦ Instrukcje sterujące przebiegiem programu — instrukcje wyboru 33
x = (c - b) / a;
Console.WriteLine();
Console.Write("Dla ");
Console.Write("a = {0:##.##}, ", a);
Console.Write("b = {0:##.##}, ", b);
Console.Write("c = {0:##.##} ", c);
Console.WriteLine("wartość x = {0:##.##}.", x);
}
}
}
}
Rysunek 2.4.
Efekt działania Program oblicza wartość x z równania liniowego ax + b = 0.
programu Podaj a.
1
Zadanie 2.4
Podaj b.
6
Podaj c.
2
Zadanie
2.5 Napisz program, w którym użytkownik zgaduje całkowitą liczbę losową
z przedziału od 0 do 9 generowaną przez komputer.
using System;
using static System.Math;
8ba61431c02548173fa6085d93015e5a
8
34 C#. Zadania z programowania z przykładowymi rozwiązaniami
if (zgadnij_liczbę == losuj_liczbę)
{
Console.WriteLine("Gratulacje! Zgadłeś liczbę!");
}
else
{
Console.WriteLine("Bardzo mi przykro, ale wylosowana
´liczba to {0}.", losuj_liczbę);
}
}
}
}
Rysunek 2.5.
Efekt działania Program losuje liczbę od 0 do 9. Zgadnij ją.
programu 9
Gratulacje! Zgadłeś liczbę!
Zadanie 2.5
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3.
Instrukcje sterujące
przebiegiem programu
— instrukcje iteracyjne
W tym rozdziale przedstawiłem typowe zadania, wraz z rozwiązaniami,
wykorzystujące instrukcje iteracyjne, czyli popularne pętle. O ile początku-
jący programiści nie mają problemu z programami, w których zastosowano
instrukcję for, to zamiana tej instrukcji na do ... while oraz while nastręcza
pewnych trudności. Proste przykłady z instrukcją for zostały tu rozwiązane
zarówno z użyciem do ... while, jak i while.
Instrukcje iteracyjne
Iteracja (łac. iteratio — powtarzanie) jest to czynność powtarzania (najczę-
ściej wielokrotnego) tej samej instrukcji (albo wielu instrukcji) w pętli.
W języku C# istnieją cztery instrukcje iteracyjne:
for,
do ... while,
while,
foreach1.
8ba61431c02548173fa6085d93015e5a
8
36 C#. Zadania z programowania z przykładowymi rozwiązaniami
Pętla for
Pętlę for stosujemy, kiedy dokładnie wiemy, ile razy pętla ma zostać wyko-
nana. Istnieje wiele wariantów pętli for, ale zawsze możemy wyróżnić trzy
główne części:
1. Inicjalizacja jest to zwykle instrukcja przypisania stosowana
do ustawienia początkowej wartości zmiennej sterującej.
2. Warunek jest wyrażeniem relacyjnym, które określa moment
zakończenia wykonywanej pętli.
3. Inkrementacja (zwiększanie) lub dekrementacja (zmniejszanie)
definiuje sposób modyfikacji zmiennej sterującej pętlą
po zakończeniu każdego przebiegu (powtórzenia).
Te trzy główne składowe oddzielone są od siebie średnikami.
Pętla for wykonywana jest dopóty, dopóki wartość warunku wynosi true.
Kiedy warunek osiągnie wartość false, to działanie programu jest kontynuo-
wane od pierwszej instrukcji znajdującej się za pętlą.
W języku C# zmienna sterująca pętlą for nie musi być typu całkowitego,
znakowego czy logicznego — może być ona również typu double (typu
rzeczywistego).
Pętla for może być wykonywana tyle razy, ile wartości znajduje się
w przedziale:
inicjalizacja; warunek; zwiększanie
lub
inicjalizacja; warunek; zmniejszanie
lub
for (inicjalizacja; warunek; zmniejszanie)
{
.......... // Instrukcje do wykonania.
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 37
Pętla while
Następną instrukcją iteracyjną jest while. Oto jej ogólna postać:
while (warunek)
{
.......... // Instrukcje do wykonania.
}
Zadanie
3.1 Napisz program, który za pomocą instrukcji for dla danych wartości x
zmieniających się w przedziale od 0 do 10 obliczy wartość funkcji y = 3*x.
using System;
8ba61431c02548173fa6085d93015e5a
8
38 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
class Program
{
static void Main(string[] args)
{
int x, y;
W pętli:
for (x = 0; x <= 10; x++)
{
y = 3 * x;
Console.WriteLine("x = " + x + '\t' + " y = " + y);
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 39
Rysunek 3.1.
Efekt działania Program oblicza wartość funkcji y = 3*x
programu dla x zmieniającego się od 0 do 10.
Zadanie 3.1
x=0 y=0
x=1 y=3
x=2 y=6
x=3 y=9
x=4 y = 12
x=5 y = 15
x=6 y = 18
x=7 y = 21
x=8 y = 24
x=9 y = 27
x = 10 y = 30
Zadanie
3.2 Napisz program, który za pomocą instrukcji do ... while dla danych wartości
x zmieniających się w przedziale od 0 do 10 oblicza wartość funkcji y = 3*x.
using System;
do
{
y = 3 * x;
Console.WriteLine("x = " + x + '\t' + " y = " + y);
x++;
}
while (x <= 10);
}
}
}
8ba61431c02548173fa6085d93015e5a
8
40 C#. Zadania z programowania z przykładowymi rozwiązaniami
Pętla będzie tak długo powtarzana, aż zostanie spełniona zależność x <= 10.
Zwróćmy uwagę, że warunek sprawdzający zakończenie działania pętli,
tzn. while (x <= 10), znajduje się na jej końcu.
Zadanie
3.3 Napisz program, który za pomocą instrukcji while dla danych wartości x
zmieniających się w przedziale od 0 do 10 oblicza wartość funkcji y = 3*x.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 41
}
}
}
}
Pętla while:
while (x <= 10)
{
y = 3 * x;
Console.WriteLine("x = " + x + '\t' + " y = " + y);
x++;
}
Pętla będzie tak długo powtarzana, aż stanie się prawdziwa zależność x <= 10.
Zwróćmy uwagę, że warunek sprawdzający zakończenie działania pętli, tzn.
while (x <= 10), znajduje się na jej początku.
Zadanie
3.4 Napisz program, który za pomocą instrukcji for wyświetla liczby całko-
wite z przedziału od 1 do 20.
Listing 3.4. Przykładowe rozwiązanie
using System;
8ba61431c02548173fa6085d93015e5a
8
42 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
if (i < 20)
Console.Write(i + ", ");
else
Console.WriteLine(i + ".");
}
}
}
}
Rysunek 3.2.
Efekt działania Program wyświetla liczby całkowite od 1 do 20.
programu
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20.
Zadanie 3.4
Zadanie
3.5 Napisz program, który za pomocą instrukcji do ... while wyświetla liczby
całkowite z przedziału od 1 do 20.
using System;
do
{
if (i < 20)
Console.Write(i + ", ");
else
Console.WriteLine(i + ".");
i++;
}
while (i <= 20);
}
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 43
Zadanie
3.6 Napisz program, który za pomocą instrukcji while wyświetla liczby całko-
wite z przedziału od 1 do 20.
using System;
Zadanie
3.7 Napisz program, który za pomocą instrukcji for sumuje liczby całkowite
z przedziału od 1 do 100.
using System;
8ba61431c02548173fa6085d93015e5a
8
44 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 3.3.
Efekt działania Program sumuje liczby całkowite od 1 do 100.
programu
Suma liczb od 1 do 100 wynosi 5050.
Zadanie 3.7
Zadanie
3.8 Napisz program, który za pomocą instrukcji do ... while sumuje liczby
całkowite z przedziału od 1 do 100.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 45
do
{
suma += i; // suma + i;
i++;
}
while (i <= 100);
Zadanie
3.9 Napisz program, który za pomocą instrukcji while sumuje liczby całkowite
z przedziału od 1 do 100.
using System;
8ba61431c02548173fa6085d93015e5a
8
46 C#. Zadania z programowania z przykładowymi rozwiązaniami
Zadanie
3.10 Napisz program, który za pomocą instrukcji for sumuje liczby parzyste
z przedziału od 1 do 100.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 47
Rysunek 3.4.
Efekt działania Program sumuje liczby parzyste od 1 do 100.
programu
Suma liczb parzystych od 1 do 100 wynosi 2550.
Zadanie 3.10
Zadanie
3.11 Napisz program, który za pomocą instrukcji do ... while sumuje liczby
parzyste z przedziału od 1 do 100.
using System;
do
{
if (i % 2 == 0) suma += i;
i++;
}
while (i <= 100);
Zadanie
3.12 Napisz program, który za pomocą instrukcji while sumuje liczby parzyste
z przedziału od 1 do 100.
8ba61431c02548173fa6085d93015e5a
8
48 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
Zadanie
3.13 Napisz program, który za pomocą instrukcji for sumuje liczby nieparzyste
z przedziału od 1 do 100.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 49
int i, suma = 0;
Rysunek 3.5.
Efekt działania Program sumuje liczby nieparzyste od 1 do 100.
programu
Suma liczb nieparzystych od 1 do 100 wynosi 2500.
Zadanie 3.13
Zadanie
3.14 Napisz program, który za pomocą instrukcji do ... while sumuje liczby
nieparzyste z przedziału od 1 do 100.
8ba61431c02548173fa6085d93015e5a
8
50 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
do
{
if (!(i % 2 == 0)) suma += i;
i++;
}
while (i <= 100);
Zadanie
3.15 Napisz program, który za pomocą instrukcji while sumuje liczby nieparzyste
z przedziału od 1 do 100.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 51
Zadanie
3.16 Napisz program, który za pomocą instrukcji for znajduje największą i naj-
mniejszą liczbę ze zbioru n wylosowanych liczb całkowitych z przedziału
od 0 do 99 (w zadaniu n = 5) oraz oblicza średnią ze wszystkich wyloso-
wanych liczb.
using System;
using static System.Math;
8ba61431c02548173fa6085d93015e5a
8
52 C#. Zadania z programowania z przykładowymi rozwiązaniami
Console.WriteLine();
Console.Write("Wylosowano liczby: " + min + ", ");
max = min;
suma += max;
suma += liczba;
}
Console.WriteLine();
Console.WriteLine("Największa liczba to " + max + ".");
Console.WriteLine();
Console.WriteLine("Najmniejsza liczba to " + min + ".");
Console.WriteLine();
Console.WriteLine("Średnia wynosi " + suma / ilość_liczb +
´".");
}
}
}
Następnie w pętli:
for (i = 2; i <= ilość_liczb; i++)
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 53
Rysunek 3.6.
Efekt działania Program losuje 5 liczb całkowitych od 0 do 99,
programu a następnie znajduje najmniejszą i największą
oraz oblicza średnią ze wszystkich wylosowanych liczb.
Zadanie 3.16
Wylosowano liczby: 68, 60, 74, 31, 13.
Zadanie
3.17 Napisz program, który za pomocą instrukcji do ... while znajduje największą
i najmniejszą liczbę ze zbioru n wylosowanych liczb całkowitych z przedziału
od 0 do 99 (w zadaniu n = 5) oraz oblicza średnią ze wszystkich wyloso-
wanych liczb.
using System;
using static System.Math;
8ba61431c02548173fa6085d93015e5a
8
54 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
static void Main(string[] args)
{
int ilość_liczb = 5, i = 2;
double liczba, suma = 0, min, max;
max = min;
suma += max;
do
{
liczba = Round(100 * (r.NextDouble()));
if (i < ilość_liczb)
Console.Write(liczba + ", ");
else
{
Console.Write(liczba + ".");
Console.WriteLine();
}
suma += liczba;
i++;
}
while (i <= ilość_liczb);
Console.WriteLine();
Console.WriteLine("Największa liczba to " + max + ".");
Console.WriteLine();
Console.WriteLine("Najmniejsza liczba to " + min + ".");
Console.WriteLine();
Console.WriteLine("Średnia wynosi " + suma / ilość_liczb +
´".");
}
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 55
Zadanie
3.18 Napisz program, który za pomocą instrukcji while znajduje największą
i najmniejszą liczbę ze zbioru n wylosowanych liczb całkowitych z prze-
działu od 0 do 99 (w zadaniu n = 5) oraz oblicza średnią ze wszystkich
wylosowanych liczb.
using System;
using static System.Math;
max = min;
suma += max;
if (i < ilość_liczb)
Console.Write(liczba + ", ");
else
{
Console.Write(liczba + ".");
Console.WriteLine();
}
8ba61431c02548173fa6085d93015e5a
8
56 C#. Zadania z programowania z przykładowymi rozwiązaniami
suma += liczba;
i++;
}
Console.WriteLine();
Console.WriteLine("Największa liczba to " + max + ".");
Console.WriteLine();
Console.WriteLine("Najmniejsza liczba to " + min + ".");
Console.WriteLine();
Console.WriteLine("Średnia wynosi " + suma / ilość_liczb +
´".");
}
}
}
Zadanie
3.19 Napisz program wyświetlający tabliczkę mnożenia dla liczb z przedziału od
1 do 100 (tzn. 10 × 10) z wykorzystaniem podwójnej pętli for.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 57
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
using System;
do
{
kolumna = 1; // Wartość początkowa.
8ba61431c02548173fa6085d93015e5a
8
58 C#. Zadania z programowania z przykładowymi rozwiązaniami
do
{
Console.Write(wiersz * kolumna + "\t");
kolumna++;
}
while (kolumna <= n);
wiersz++;
Console.WriteLine();
}
while (wiersz <= n);
}
}
}
Zadanie
3.21 Napisz program wyświetlający tabliczkę mnożenia dla liczb z przedziału od
1 do 100 (tzn. 10 × 10) z wykorzystaniem podwójnej pętli while.
using System;
wiersz++;
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 59
}
}
}
}
Zadanie
3.22 Napisz program, który wyświetla duże litery alfabetu od A do Z i od Z do
A z wykorzystaniem pętli for.
using System;
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
60 C#. Zadania z programowania z przykładowymi rozwiązaniami
}
}
}
Rysunek 3.8.
Efekt działania Program wyświetla duże litery alfabetu od A do Z i od Z do A.
programu
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z.
Zadanie 3.22
Z, Y, X, W, V, U, T, S, R, Q, P, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A.
Zadanie
3.23 Napisz program, który wyświetla duże litery alfabetu od A do Z i od Z do A
z wykorzystaniem pętli do ... while.
using System;
do
{
if (znak < 'Z')
Console.Write(znak + ", ");
else
{
Console.Write(znak + ".");
Console.WriteLine();
}
znak++;
}
while (znak <= 'Z');
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 61
Console.WriteLine();
do
{
if (znak > 'A')
Console.Write(znak + ", ");
else
{
Console.Write(znak + ".");
Console.WriteLine();
}
znak--;
}
while (znak >= 'A');
}
}
}
Zadanie
3.24 Napisz program, który wyświetla duże litery alfabetu od A do Z i od Z do A
z wykorzystaniem pętli while.
using System;
8ba61431c02548173fa6085d93015e5a
8
62 C#. Zadania z programowania z przykładowymi rozwiązaniami
Console.WriteLine();
}
znak++;
}
Console.WriteLine();
Zadanie
3.25 Wiedząc, że 1233 = 122 + 332, napisz program, który znajduje wszyst-
kie liczby z przedziału od 1000 do 9999 spełniające taką ciekawą zależ-
ność. Program dodatkowo liczy ich ilość.
Listing 3.25. Przykładowe rozwiązanie
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 63
Console.WriteLine();
Console.WriteLine("Znaleziono " + j + " liczby.");
}
}
}
Rysunek 3.9.
Efekt działania 1233 = 12 * 12 + 33 * 33
programu 8833 = 88 * 88 + 33 * 33
Zadanie 3.25
Znaleziono 2 liczby.
using System;
8ba61431c02548173fa6085d93015e5a
8
64 C#. Zadania z programowania z przykładowymi rozwiązaniami
Console.WriteLine();
Console.WriteLine("Znaleziono " + j + " liczbę.");
}
}
}
Rysunek 3.10.
Efekt działania 990100 = 990 * 990 + 100 * 100
programu
Znaleziono 1 liczbę.
Zadanie 3.26
Zadanie
3.27 Liczbę π można obliczać na wiele sposobów. Napisz program, który za pomocą
metody Monte Carlo oblicza liczbę π z określoną dokładnością. Skorzystaj
z zamieszczonego rysunku i następującej listy kroków:
1. Wpisz koło o promieniu r w kwadrat o boku 2r.
2. Losowo wygeneruj punkty i umieść je w kwadracie.
3. Wyznacz liczbę punktów, które znajdują się jednocześnie
w kwadracie i kole.
4. Niech promień r będzie wyznaczony przez stosunek liczby punktów
znajdujących się w kole do liczby punktów znajdujących się
w kwadracie.
5. π~ 4.0 · r.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 65
using System;
using static System.Math;
Console.WriteLine("Proszę czekać...");
Random r = new Random();
if (x * x + y * y <= 1)
{
licznik += 1; // Liczy punkty znajdujące się w kole.
8ba61431c02548173fa6085d93015e5a
8
66 C#. Zadania z programowania z przykładowymi rozwiązaniami
}
}
Rysunek 3.11.
Efekt działania Proszę czekać...
programu Wartość pi = 3,14159265358979
Obliczona wartość pi = 3,14141548
Zadanie 3.27
Błąd obliczeń wynosi: 0,000177173589793078
Czas obliczeń: 8440 ms
Zadanie
3.28 Korzystając z dowolnej instrukcji iteracyjnej, napisz program, który gene-
ruje następujący ciąg liczb: 00112233445566778899.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 3. ♦ Instrukcje sterujące przebiegiem programu — instrukcje iteracyjne 67
{
x = i / 2;
Console.Write(x);
};
Console.WriteLine();
}
}
}
Rysunek 3.12.
Efekt działania Program generuje następujący ciąg liczb:
programu 00112233445566778899
Zadanie 3.28
8ba61431c02548173fa6085d93015e5a
8
68 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4.
Tablice i kolekcje
W tym rozdziale przedstawiłem typowe zadania, wraz z przykładowymi roz-
wiązaniami, wykorzystujące tablice jedno- i dwuwymiarowe oraz kolekcje.
Tablice
Tablice — zbiór zmiennych tego samego typu (np. typu całkowitego, typu
rzeczywistego), do których odwołujemy się poprzez jedną wspólną nazwę —
są bardzo praktyczne, ponieważ oferują wygodny sposób połączenia powiąza-
nych ze sobą zmiennych. Ich główną zaletą jest to, że łatwo można na nich
przeprowadzać różne operacje, np. sortowanie.
Mimo że tablice w języku C# mogą być używane tak jak w innych językach,
mają jeden specjalny atrybut: są zaimplementowane jako obiekty1. W deklaracji
tablicy musimy określić typ wartości, jaki ma przechowywać tablica, a także
liczbę elementów tablicy. W języku C# tablice mogą być jednowymiarowe,
dwuwymiarowe itd.
Kolekcje
Kolekcja jest to obiekt przechowujący inne obiekty, np. tablice. Najbardziej
znaną i najczęściej stosowaną kolekcją w języku C# jest lista ArrayList().
Tak jak tablica, może przechowywać wiele elementów, jest jednak łatwiejsza
i wygodniejsza w obsłudze. W przeciwieństwie do tablic lista ArrayList
8ba61431c02548173fa6085d93015e5a
8
70 C#. Zadania z programowania z przykładowymi rozwiązaniami
nie wymaga deklaracji ani określenia, z ilu elementów ma się składać. Kolejne
elementy dodajemy do listy lub z niej usuwamy, korzystając z metod Add()
i RemoveAt(). Kolekcja ArrayList() ma wiele innych metod, np. Sort(),
które upraszczają jej obsługę i zwiększają funkcjonalność. Przestrzenią nazw,
której będziemy używali w programach, stosując kolekcje, jest System.Col
´lections.
Tablice jednowymiarowe
Oto przykład zadeklarowania tablicy jednowymiarowej i związanej z nią
zmiennej:
typ_tablicy [] nazwa_tablicy= new typ_tablicy[rozmiar_tablicy];
0 1 2 3 4 5 6 7 8 9
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 71
Zadanie
4.1 Napisz program, który w 10-elementowej tablicy jednowymiarowej o nazwie
dane umieszcza liczby z przedziału od 0 do 9 (zobacz reprezentację gra-
ficzną tablicy zamieszczoną po tym poleceniu).
using System;
8ba61431c02548173fa6085d93015e5a
8
72 C#. Zadania z programowania z przykładowymi rozwiązaniami
}
}
}
Rysunek 4.1.
Efekt działania Program wyświetla zawartość tablicy jednowymiarowej 10-elementowej.
programu
dane[0] = 0
Zadanie 4.1
dane[1] = 1
dane[2] = 2
dane[3] = 3
dane[4] = 4
dane[5] = 5
dane[6] = 6
dane[7] = 7
dane[8] = 8
dane[9] = 9
Zadanie
4.2 Napisz program, który w 10-elementowej tablicy jednowymiarowej o nazwie
dane umieszcza liczby z przedziału od 9 do 0 (zobacz reprezentację gra-
ficzną tablicy zamieszczoną po tym poleceniu).
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 73
8ba61431c02548173fa6085d93015e5a
8
74 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 4.2.
Efekt działania Program wyświetla zawartość tablicy jednowymiarowej 10-elementowej.
programu
dane[0] = 9
Zadanie 4.2
dane[1] = 8
dane[2] = 7
dane[3] = 6
dane[4] = 5
dane[5] = 4
dane[6] = 3
dane[7] = 2
dane[8] = 1
dane[9] = 0
Tablice dwuwymiarowe
Tablice dwuwymiarowe w języku C# deklarujemy podobnie jak tablice
jednowymiarowe. Oto przykład zadeklarowania tablicy dwuwymiarowej:
typ_tablicy [,] nazwa_tablicy = new typ_tablicy[rozmiar_tablicy,
´rozmiar_tablicy];3
3 Drodzy Czytelnicy, jeśli programujecie w C/C++ lub w Javie, bądźcie ostrożni, deklarując
wielowymiarowe tablice w języku C# albo z nich korzystając. W C/C++ lub w Javie wymiar
tablicy oznaczany jest odrębną parą nawiasów kwadratowych, w C# zaś wymiary oddziela
się przecinkiem.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 75
1 2 0 0 0 0 0 0 0 0
3 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 7
Zadanie
4.3 Napisz program, który w zadeklarowanej tablicy dwuwymiarowej 10 × 10
o nazwie macierz umieszcza na przekątnej liczbę 1, a poza przekątną 0.
Dodatkowo program powinien obliczać sumę wyróżnionych w tablicy ele-
mentów, tzn. elementów znajdujących się na jej przekątnej.
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
using System;
8ba61431c02548173fa6085d93015e5a
8
76 C#. Zadania z programowania z przykładowymi rozwiązaniami
suma = 0;
Console.WriteLine();
Console.WriteLine("Suma wyróżnionych elementów w tablicy
´wynosi " + suma + ".");
}
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 77
8ba61431c02548173fa6085d93015e5a
8
78 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 4.3.
Efekt działania Program wyświetla zawartość tablicy dwuwymiarowej 10 x 10.
programu
1000000000
Zadanie 4.3
0100000000
0010000000
0001000000
0000100000
0000010000
0000001000
0000000100
0000000010
0000000001
Zadanie
4.4 Napisz program, który w zadeklarowanej tablicy dwuwymiarowej 10 × 10
o nazwie macierz umieszcza na przekątnej liczby z przedziału od 0 do 9,
a poza przekątną 0. Dodatkowo program powinien obliczać sumę wyróżnio-
nych w tablicy elementów, tzn. elementów znajdujących się na jej przekątnej.
0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0 0 0
0 0 0 3 0 0 0 0 0 0
0 0 0 0 4 0 0 0 0 0
0 0 0 0 0 5 0 0 0 0
0 0 0 0 0 0 6 0 0 0
0 0 0 0 0 0 0 7 0 0
0 0 0 0 0 0 0 0 8 0
0 0 0 0 0 0 0 0 0 9
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 79
suma = 0;
Console.WriteLine();
Console.WriteLine("Suma wyróżnionych elementów w tablicy
´wynosi " + suma + ".");
}
}
}
8ba61431c02548173fa6085d93015e5a
8
80 C#. Zadania z programowania z przykładowymi rozwiązaniami
Zadanie
4.5 Napisz program, który w zadeklarowanej tablicy dwuwymiarowej 10 × 10
o nazwie macierz umieszcza liczby 1 i 0 zgodnie z zamieszczoną po polece-
niu interpretacją graficzną. Program dodatkowo powinien obliczać sumę
wyróżnionych elementów.
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 81
następującymi:
for (i = 0; i < n; i++)
{
suma += macierz[i, n – i - 1];
}
using System;
// Wpisywanie do tablicy.
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (n == i + j + 1)
macierz[i, j] = 1;
else
macierz[i, j] = 0;
}
}
8ba61431c02548173fa6085d93015e5a
8
82 C#. Zadania z programowania z przykładowymi rozwiązaniami
suma = 0;
}
}
}
Rysunek 4.5.
Efekt działania Program wyświetla zawartość tablicy dwuwymiarowej 10 x 10.
programu
0000000001
Zadanie 4.5
0000000010
0000000100
0000001000
0000010000
0000100000
0001000000
0010000000
0100000000
1000000000
Zadanie
4.6 Napisz program, który w zadeklarowanej tablicy dwuwymiarowej 10 × 10
o nazwie macierz umieszcza liczby z przedziału od 0 do 9 zgodnie z zamiesz-
czoną po poleceniu interpretacją graficzną. Program dodatkowo powinien
obliczać sumę wyróżnionych elementów.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 83
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 2 0 0
0 0 0 0 0 0 3 0 0 0
0 0 0 0 0 4 0 0 0 0
0 0 0 0 5 0 0 0 0 0
0 0 0 6 0 0 0 0 0 0
0 0 7 0 0 0 0 0 0 0
0 8 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 0 0
// Wpisywanie do tablicy.
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
8ba61431c02548173fa6085d93015e5a
8
84 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
if (n == i + j + 1)
macierz[i, j] = i;
else
macierz[i, j] = 0;
}
}
suma = 0;
Console.WriteLine();
Console.WriteLine("Suma wyróżnionych elementów w tablicy
´wynosi " + suma + ".");
}
}
}
Rysunek 4.6.
Efekt działania Program wyświetla zawartość tablicy dwuwymiarowej 10 x 10.
programu
0000000000
Zadanie 4.6
0000000010
0000000200
0000003000
0000040000
0000500000
0006000000
0070000000
0800000000
9000000000
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 85
Zadanie
4.7 Napisz program, który w zadeklarowanej tablicy dwuwymiarowej 10 × 10
umieszcza w pierwszej kolumnie liczby z przedziału od 0 do 9, w drugiej
kolumnie kwadraty tych liczb, a w pozostałych kolumnach 0 (zobacz inter-
pretację graficzną tablicy zamieszczoną po poleceniu). Dodatkowo program
powinien obliczać sumę liczb znajdujących się w pierwszej kolumnie i sumę
liczb znajdujących się w drugiej kolumnie.
0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0
2 4 0 0 0 0 0 0 0 0
3 9 0 0 0 0 0 0 0 0
4 16 0 0 0 0 0 0 0 0
5 25 0 0 0 0 0 0 0 0
6 36 0 0 0 0 0 0 0 0
7 49 0 0 0 0 0 0 0 0
8 64 0 0 0 0 0 0 0 0
9 81 0 0 0 0 0 0 0 0
8ba61431c02548173fa6085d93015e5a
8
86 C#. Zadania z programowania z przykładowymi rozwiązaniami
if (j > 1) tablica[i, j] = 0;
}
}
// Obliczanie sumy.
suma = 0;
Console.WriteLine();
Console.WriteLine("Suma liczb znajdujących się w pierwszej
´kolumnie = " + suma + ".");
suma = 0;
Console.WriteLine();
Console.WriteLine("Suma liczb znajdujących się w drugiej
´kolumnie = " + suma + ".");
}
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 87
Rysunek 4.7.
Efekt działania Program wyświetla zawartość tablicy dwuwymiarowej 10 x 10.
programu 0 000000000
Zadanie 4.7 1 100000000
2 400000000
3 900000000
4 16 0 0 0 0 0 0 0 0
5 25 0 0 0 0 0 0 0 0
6 36 0 0 0 0 0 0 0 0
7 49 0 0 0 0 0 0 0 0
8 64 0 0 0 0 0 0 0 0
9 81 0 0 0 0 0 0 0 0
Suma liczb znajdujących się w pierwszej kolumnie = 45.
Suma liczb znajdujących się w drugiej kolumnie = 285.
8ba61431c02548173fa6085d93015e5a
8
88 C#. Zadania z programowania z przykładowymi rozwiązaniami
Zadanie
4.8 Dane są dwie tablice dwuwymiarowe 10 × 10 o nazwach a i b. Tablica a
zawiera następujące elementy:
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 89
class Program
{
static void Main(string[] args)
{
int n = 10, i, j;
int[,] a = new int[n, n];
int[,] b = new int[n, n];
Console.WriteLine();
// Wyświetlenie zawartości tablicy b.
Console.WriteLine("Wyświetlenie zawartości tablicy b.");
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
90 C#. Zadania z programowania z przykładowymi rozwiązaniami
}
}
}
}
Rysunek 4.8.
Efekt działania Wyświetlenie zawartości tablicy a.
programu
0123456789
Zadanie 4.8
0123456789
0123456789
0123456789
0123456789
0123456789
0123456789
0123456789
0123456789
0123456789
0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
Pętla foreach
Kolekcja jest grupą obiektów. Język C# definiuje kilka grup kolekcji, z których
jedna jest tablicą. Pętla foreach przełącza się kolejno pomiędzy elementami
kolekcji. Jej ogólna postać jest następująca:
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 91
Zadanie
4.9 Napisz program, który w 100-elementowej tablicy jednowymiarowej o nazwie
dane umieszcza liczby z przedziału od 1 do 100, a następnie je sumuje.
using System;
8ba61431c02548173fa6085d93015e5a
8
92 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 93
if ((x % 2) == 0)
suma_p += x; // Sumowanie liczb parzystych znajdujących się
// w tablicy.
else
suma_np += x; // Sumowanie liczb nieparzystych znajdujących się
// w tablicy.
}
Console.WriteLine();
Console.WriteLine("Suma liczb parzystych od 1 do 100 wynosi
´" + suma_p + ".");
Console.WriteLine();
Console.WriteLine("Suma liczb nieparzystych od 1 do 100
´wynosi " + suma_np + ".");
}
}
}
Rysunek 4.9.
Efekt działania Program sumuje liczby parzyste i nieparzyste
programu z przedziału od 1 do 100 znajdujące się w tablicy.
Zadanie 4.10 Suma liczb parzystych od 1 do 100 wynosi 2550.
Suma liczb nieparzystych od 1 do 100 wynosi 2500.
Zadanie
4.11 Korzystając z właściwości kolekcji ArrayList(), napisz program, który do
kolekcji tego typu dodaje sześć liczb, a następnie je sortuje. Po wykonaniu tej
operacji należy dokonać usunięcia drugiego elementu z listy, dodać nowy
element do listy i dokonać ponownego sortowania.
8ba61431c02548173fa6085d93015e5a
8
94 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
using System.Collections;
Console.WriteLine();
Console.Write("Elementy posortowane: ");
for (int i = 0; i < lista.Count; i++)
{
if (i < lista.Count - 1)
Console.Write(lista[i] + ", ");
else
Console.Write(lista[i] + ". ");
}
Console.WriteLine();
lista.RemoveAt(1); // Usunięto drugi element z listy.
Console.WriteLine("Usunięto drugi element z listy i dodano
´nowy element do listy.");
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 95
{
if (i < lista.Count - 1)
Console.Write(lista[i] + ", ");
else
Console.Write(lista[i] + ". ");
}
Console.WriteLine();
Console.Write("Elementy posortowane: ");
for (int i = 0; i < lista.Count; i++)
{
if (i < lista.Count - 1)
Console.Write(lista[i] + ", ");
else
Console.Write(lista[i] + ". ");
}
}
}
}
Rysunek 4.10.
Efekt działania Elementy nieposortowane: 20, 51, -72, 4, 14, -4.
programu Elementy posortowane: -72, -4, 4, 14, 20, 51.
Usunięto drugi element z listy i dodano nowy element do listy.
Zadanie 4.11
Elementy nieposortowane po usunięciu drugiego elementu z listy i dodaniu
nowego elementu: -72, 4, 14, 20, 51, 10.
Elementy posortowane: -72, 4, 10, 14, 20, 51.
Zadanie
4.12 Korzystając z właściwości kolekcji ArrayList(), napisz program, który
do kolekcji tego typu dodaje sześć imion, a następnie je sortuje.
using System;
using System.Collections;
8ba61431c02548173fa6085d93015e5a
8
96 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
static void Main(string[] args)
{
ArrayList lista = new ArrayList();
Console.WriteLine();
Console.Write("Elementy posortowane: ");
for (int i = 0; i < lista.Count; i++)
{
if (i < lista.Count - 1)
Console.Write(lista[i] + ", ");
else
Console.Write(lista[i] + ". ");
}
Console.WriteLine();
}
}
}
Rysunek 4.11.
Efekt działania Elementy nieposortowane: Tomek, Ania, Zenek, Jarek, Kasia, Dominika.
programu Elementy posortowane: Ania, Dominika, Jarek, Kasia, Tomek, Zenek.
Zadanie 4.12
Ćwiczenie dodatkowe
Uzupełnij program z zadania 4.12 o linijki kodu, które dokonują usunięcia
drugiego elementu z listy, a następnie dodają nowy element do listy i doko-
nują ponownego sortowania.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 97
Działania na macierzach
Macierz to w matematyce układ liczb, symboli lub wyrażeń zapisanych
w postaci prostokątnej lub kwadratowej tablicy.
Zadanie
4.13 Dane są dwie macierze 10 × 10 o nazwach a i b. Macierz a zawiera nastę-
pujące elementy:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
Macierz b ma postać:
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
8ba61431c02548173fa6085d93015e5a
8
98 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 99
// Dodawanie macierzy a + b.
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
c[i, j] = a[i, j] + b[i, j];
}
}
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
100 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 4.12.
Efekt działania Macierz a.
programu 1111111111
1111111111
Zadanie 4.13
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
Macierz b.
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
Macierz c = a + b.
3333333333
3333333333
3333333333
3333333333
3333333333
3333333333
3333333333
3333333333
3333333333
3333333333
Zadanie
4.14 Dane są dwie macierze 10 × 10 o nazwach a i b, których postać jest taka sama
jak w zadaniu 4.13. Napisz program, który oblicza różnicę tych macierzy:
c = b - a.
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 101
class Program
{
static void Main(string[] args)
{
int n = 10, i, j;
int[,] a = new int[n, n];
int[,] b = new int[n, n];
int[,] c = new int[n, n];
8ba61431c02548173fa6085d93015e5a
8
102 C#. Zadania z programowania z przykładowymi rozwiązaniami
// Odejmowanie macierzy b – a.
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
c[i, j] = b[i, j] - a[i, j];
}
}
Console.WriteLine();
}
}
}
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 103
Rysunek 4.13.
Efekt działania Macierz a.
programu 1111111111
1111111111
Zadanie 4.14 1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
Macierz b.
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
Macierz c = b - a.
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
class Program
{
static void Main(string[] args)
{
int n = 10, i, j;
8ba61431c02548173fa6085d93015e5a
8
104 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
for (j = 0; j < n; j++)
{
a[i, j] = 1;
}
}
// Wpisywanie liczb do macierzy b.
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
b[i, j] = 2;
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 105
}
Console.WriteLine();
Łańcuchy tekstowe
W wielu językach programowania typ łańcuchowy string jest tablicą zna-
ków, natomiast w C# typ string (łańcuch tekstowy) jest obiektem4. Dlatego
typ string jest typem referencyjnym. Łańcuchy tekstowe są bardzo uży-
teczne w programach, gdyż mogą przechowywać informacje takie jak nazwy
plików, tytuły książek, nazwiska pracowników i inne ciągi określonych
znaków. Klasa String oferuje kilka metod, które operują na łańcuchach
tekstowych.
4 Zob. rozdział 5.
8ba61431c02548173fa6085d93015e5a
8
106 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 4.14.
Efekt działania Macierz a.
programu 1111111111
1111111111
Zadanie 4.15 1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
Macierz b.
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
2222222222
Macierz c = a * b.
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 107
using System;
}
}
}
Rysunek 4.15.
Efekt działania Program mierzy długość łańcucha imię i nazwisko.
programu Podaj imię.
Kazimierz
Zadanie 4.16
Podaj nazwisko.
Nowakowski
Imię Kazimierz zawiera 9 liter(y).
Nazwisko Nowakowski zawiera 10 liter(y).
8ba61431c02548173fa6085d93015e5a
8
108 C#. Zadania z programowania z przykładowymi rozwiązaniami
Konkatenacja
Konkatenacja (łac. concatenatio) to łączenie ze sobą różnych/równych
tekstów. W programowaniu konkatenacja oznacza łączenie dwóch tek-
stów w jeden (ustawienie jednego za drugim) za pomocą operatora +
(znak plusa).
Zadanie
4.17 Napisz program, który składa dwa łańcuchy, a wynik tej operacji wyświetla
na ekranie komputera.
using System;
if (String.Compare(łańcuch_1, lancuch_2) == 0)
Console.WriteLine("Składanie dwóch równych łańcuchów jest
´przemienne.");
else
Console.WriteLine("Składanie dwóch różnych łańcuchów nie
´jest przemienne.");
}
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 109
Rysunek 4.16.
Efekt działania Program składa dwa łańcuchy.
programu Podaj pierwszy łańcuch.
ma
Zadanie 4.17
Podaj drugi łańcuch.
ta
ma + ta = mata
ta + ma = tama
Składanie dwóch różnych łańcuchów nie jest przemienne.
Programowanie uogólnione
i klasy generyczne
Programowanie uogólnione (lub inaczej generyczne, ang. generic program-
ming) jest jednym z paradygmatów programowania. Ten rodzaj programo-
wania pozwala pisać kod programu bez wcześniejszej znajomości typów
danych, na których kod ten będzie operował.
W języku C++ programowanie uogólnione umożliwiają szablony. W języku
C# służą do tego typy generyczne. Zapewniają one pełny mechanizm tworze-
nia struktur danych, które można przekształcić na wyspecjalizowaną wersję
w celu obsługi konkretnych typów. Programiści definiują typy parametryzo-
wane w taki sposób, by dla każdej zmiennej określonego typu generycznego
używany był ten sam wewnętrzny algorytm. Jednak typy danych i sygna-
tury metod mogą się zmieniać w zależności od podanego argumentu określa-
jącego typ. Aby ułatwić programistom naukę programowania, projektanci
języka C# zdecydowali się na zastosowanie składni pozornie podobnej do
składni szablonów z języka C++. W języku C# składnia tworzenia klas
i struktur generycznych wymaga użycia nawiasów ostrych do deklarowa-
nia parametrów w deklaracji typu i do podawania argumentów, gdy typ jest
używany.
8ba61431c02548173fa6085d93015e5a
8
110 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 111
}
}
Rysunek 4.17.
Efekt działania Max(10, 30) = 30.
programu Max(4,51, 1,89) = 4,51.
Max(Science, Fiction) = Science.
Zadanie 4.18
5 Interfejs jest podobny do klasy (zob. rozdział 5.), ale różni się od niej tym, że tylko opisuje
jej składowe.
8ba61431c02548173fa6085d93015e5a
8
112 C#. Zadania z programowania z przykładowymi rozwiązaniami
Na przykład:
class Typ_Generyczny<T>
{
public void Dodaj(T X)
{
Console.WriteLine("{0}", X);
}
}
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 113
{
Klasa_Generyczna<int> ob_Gen = new Klasa_Generyczna<int>();
// Tworzymy obiekt.
8ba61431c02548173fa6085d93015e5a
8
114 C#. Zadania z programowania z przykładowymi rozwiązaniami
tab.wyświetl_tablice(strony, 5);
tab1.wyświetl_tablice(ceny, 3);
tab2.wyświetl_tablice(tekst, 6);
}
}
}
Rysunek 4.18.
Efekt działania 10 20 30 40 50
programu 10,5 15,3 20,11
HELLO!
Zadanie 4.20
Listy generyczne
Zadanie
4.21 W zadaniach 4.11 i 4.12 korzystaliśmy z właściwości kolekcji ArrayList().
Napisz program, który jest kombinacją tych dwóch zadań i korzysta z listy
generycznej List<T> i jej metod.
using System;
using System.Collections.Generic;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 4. ♦ Tablice i kolekcje 115
{
class Program
{
static void Main(string[] args)
{
List<int> lista = new List<int>(); // Lista typu int.
List<string> lista1 = new List<string>(); // Lista1 typu string.
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
116 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 4.19.
Efekt działania Elementy nieposortowane: 20, 51, -72, 4, 14, -4,
programu Elementy posortowane: -72, -4, 4, 14, 20, 51,
Zadanie 4.21
Elementy nieposortowane: Tomek, Ania, Zenek, Jarek, Kasia, Dominika,
Elementy posortowane: Ania, Dominika, Jarek, Kasia, Tomek, Zenek,
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5.
Elementy
programowania
obiektowego
W tym rozdziale przedstawiłem typowe zadania, wraz z przykładowymi roz-
wiązaniami, wykorzystujące zasady i reguły programowania obiektowego.
Informacje ogólne
Programowanie obiektowe jest podstawą języka C#. Wszystkie obiektowe
języki programowania (w tym również C#) mają trzy podstawowe zasady:
hermetyzacja danych (enkapsulacja), polimorfizm i dziedziczenie.
W C# podstawową jednostką enkapsulacji jest klasa (ang. class), która de-
finiuje projekt i strukturę obiektu. Klasa to zdefiniowany przez programistę
typ danych, który zawiera w polach swoje wewnętrzne dane. Dodatkowo
klasa zawiera funkcje zwane metodami, które w określony sposób operują
na tych danych. Proste klasy zawierają albo same metody, albo same dane,
jednak większość klas zawiera zarówno metody, jak i dane.
8ba61431c02548173fa6085d93015e5a
8
118 C#. Zadania z programowania z przykładowymi rozwiązaniami
Zapis w programie:
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 119
Z kolei konstrukcja:
nazwa_klasy nazwa_zmiennej = new nazwa_klasy();
8ba61431c02548173fa6085d93015e5a
8
120 C#. Zadania z programowania z przykładowymi rozwiązaniami
}
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 121
using System;
8ba61431c02548173fa6085d93015e5a
8
122 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
Console.Write("Pole prostokąta o boku a = {0:##.##} i boku
´b = {1:##.##}", a , b);
Console.WriteLine(" wynosi {0:##.##}.", oblicz_pole);
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 123
using System;
8ba61431c02548173fa6085d93015e5a
8
124 C#. Zadania z programowania z przykładowymi rozwiązaniami
if (a == 0)
{
Console.WriteLine("Niedozwolona wartość współczynnika a.
´Naciśnij klawisz ENTER.");
Console.Read(); // Naciśnij klawisz Enter.
Environment.Exit(0); // Wyjście z programu.
}
else
{
Console.WriteLine("Podaj b.");
b = double.Parse(Console.ReadLine());
Console.WriteLine("Podaj c.");
c = double.Parse(Console.ReadLine());
}
}
switch (liczba_pierwiastków)
{
case 1:
x1 = -b / (2 * a);
break;
case 2:
{
x1 = (-b - Math.Sqrt(delta)) / (2 * a);
x2 = (-b + Math.Sqrt(delta)) / (2 * a);
}
break;
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 125
switch (liczba_pierwiastków)
{
case 0:
Console.WriteLine("brak pierwiastków
´rzeczywistych.");
break;
case 1:
Console.WriteLine("trójmian kwadratowy ma jeden
´pierwiastek podwójny: x1 = {0:##.##}.", x1);
break;
case 2:
{
Console.WriteLine("trójmian kwadratowy ma dwa
´pierwiastki: ");
Console.WriteLine("x1 = {0:##.##},", x1);
Console.WriteLine("x2 = {0:##.##}.", x2);
}
break;
}
}
trójmian1.czytaj_dane();
trójmian1.przetwórz_dane();
trójmian1.wyświetl_wynik();
}
}
}
Zadanie
5.3 Napisz zgodnie z zasadami programowania obiektowego program, który
w tablicy 10 × 10 umieszcza losowo na przekątnej liczby z przedziału od 0
do 9, a poza przekątną zera. Dodatkowo program oblicza sumę liczb znajdu-
jących się na przekątnej. Klasa powinna zawierać trzy metody:
czytaj_dane() — umieszcza liczby w tablicy.
8ba61431c02548173fa6085d93015e5a
8
126 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
using static System.Math;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 127
matrix1.czytaj_dane(tablica, rozmiar);
matrix1.przetwórz_dane(tablica, rozmiar);
matrix1.wyświetl_wynik(tablica, rozmiar);
}
}
}
Zadanie
5.4 Napisz zgodnie z zasadami programowania obiektowego program, który
sortuje n liczb (w programie jest ich sześć). Klasa powinna zawierać trzy
metody:
czytaj_dane() — czyta dane i umieszcza je w tablicy liczby.
przetwórz_dane() — sortuje wczytane dane według wybranego
algorytmu sortowania (w programie został wykorzystany algorytm
sortowania bąbelkowego).
wyświetl_wynik() — wyświetla zawartość posortowanej tablicy
liczby na ekranie komputera.
using System;
8ba61431c02548173fa6085d93015e5a
8
128 C#. Zadania z programowania z przykładowymi rozwiązaniami
if (i < n - 1)
Console.Write(liczby[i] + ", ");
else
Console.Write(liczby[i] + ".");
}
Console.WriteLine();
}
Console.WriteLine();
Console.Write("Liczby posortowane to: ");
liczby[0] = 57;
liczby[1] = 303;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 129
liczby[2] = 34;
liczby[3] = -1025;
liczby[4] = 8;
liczby[5] = 20;
bąbelki.czytaj_dane(liczby, n);
bąbelki.przetwórz_dane(liczby, n);
bąbelki.wyświetl_wynik(liczby, n);
}
}
}
Rysunek 5.1.
Efekt działania Liczby nieposortowane to: 57, 303, 34, -1025, 8, 20.
programu
Liczby posortowane to: -1025, 8, 20, 34, 57, 303.
Zadanie 5.4
Rekurencja
W języku C# metoda może wywołać samą siebie. Proces ten nazywa się
rekurencją (rekursją), a metoda taka nazywa się metodą rekurencyjną
(rekursywną).
Główną zaletą rekurencji jest możliwość utworzenia metod obliczających
niektóre algorytmy w sposób znacznie prostszy i czytelniejszy niż niektóre
ich odpowiedniki iteracyjne.
Zadanie
5.5 Napisz program, który rekurencyjnie oblicza kolejne wartości n!, gdzie
n > 0 (w programie należy przyjąć n = 15), i wyświetla wynik na ekranie
komputera.
Listing 5.5. Przykładowe rozwiązanie
using System;
8ba61431c02548173fa6085d93015e5a
8
130 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
long zwrot = 1;
if (liczba >= 2)
{
zwrot = liczba * silnia(liczba - 1);
}
return zwrot;
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 131
Rysunek 5.2.
Efekt działania Obliczanie silni dla dowolnej liczby całkowitej.
programu Podaj n.
15
Zadanie 5.5
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 6227020800
14! = 87178291200
15! = 1307674368000
#1 1
#2 2 1
#3 3 2 1
#4 4 3 2 1
#5 5 4 3 2 1
#6 6 5 4 3 2 1
8ba61431c02548173fa6085d93015e5a
8
132 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
public int trójkątne(int n)
{
if (n == 1)
return 1;
else
return (n + trójkątne(n - 1));
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 133
Rysunek 5.3.
Efekt działania Program znajduje 10 pierwszych liczb trójkątnych.
programu
#1 = 1
Zadanie 5.6
#2 = 3
#3 = 6
#4 = 10
#5 = 15
#6 = 21
#7 = 28
#8 = 36
#9 = 45
#10 = 55
using System;
8ba61431c02548173fa6085d93015e5a
8
134 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 5.4.
Efekt działania Program znajduje rekurencyjnie 10 pierwszych liczb Fibonacciego.
programu
0
Zadanie 5.7
1
1
2
3
5
8
13
21
34
Klasa Osoba
Zadanie
5.8 Utwórz klasę Osoba, która zawiera następujące pola: nazwisko, imię, ulica,
kod i miasto oraz dwie metody: wczytaj() i wyświetl(). Pierwsza z metod
umożliwia wprowadzanie danych, natomiast druga wyświetla je na ekranie
komputera.
Listing 5.8. Przykładowe rozwiązanie
using System;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 135
String nazwisko;
String imię;
String ulica;
String kod;
String miasto;
pracownik.wczytaj();
pracownik.wyświetl();
}
}
}
8ba61431c02548173fa6085d93015e5a
8
136 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 5.5.
Efekt działania Wprowadzamy dane.
programu ====================
Podaj nazwisko.
Zadanie 5.8
Nowak
Podaj imię.
Jan
Podaj ulicę.
Lipowa 14
Podaj kod.
00-960
Podaj miasto.
Warszawa
Wyświetlanie danych.
====================
Nazwisko: Nowak
Imię: Jan
Ulica: Lipowa 14
Kod: 00-960
Miasto: Warszawa
Dziedziczenie
Dziedziczenie (ang. inheritance) jest jedną z trzech podstawowych zasad
programowania obiektowego. Jest to mechanizm współdzielenia funk-
cjonalności pomiędzy klasami, który umożliwia tworzenie hierarchicznej
klasyfikacji. Dziedziczenie pozwala stworzyć ogólną klasę, która określa
wspólne cechy zbioru powiązanych klas. W języku C# klasa, po której się
dziedziczy, nazywa się klasą bazową (ang. base class), natomiast klasa dzie-
dzicząca nosi nazwę klasy wyprowadzonej (ang. derived class). Klasa wypro-
wadzona jest specjalną wersją klasy nadrzędnej i dziedziczy wszystkie zmienne
i metody zdefiniowane w klasie bazowej, dodając własne elementy.
Ogólna forma deklaracji klasy, która dziedziczy z klasy bazowej, jest nastę-
pująca:
class nazwa_klasa_wyprowadzonej : klasa_bazowa
{
......... // Ciało klasy.
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 137
Zadanie
5.9 Napisz program, który zawiera proces dziedziczenia — klasa wyprowadzona
Kadra dziedziczy właściwości po klasie bazowej Osoba i zawiera dwa dodat-
kowe pola: wykształcenie i stanowisko oraz dwie dodatkowe metody:
wczytaj1() i wyświetl1().
using System;
8ba61431c02548173fa6085d93015e5a
8
138 C#. Zadania z programowania z przykładowymi rozwiązaniami
String imię;
String ulica;
String kod;
String miasto;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 5. ♦ Elementy programowania obiektowego 139
class Program
{
static void Main(string[] args)
{
Kadra pracownik = new Kadra();
pracownik.wczytaj1();
pracownik.wyświetl1();
}
}
}
Rysunek 5.6.
Efekt działania Wprowadzamy dane.
programu ====================
Podaj nazwisko.
Zadanie 5.9
Nowak
Podaj imię.
Jan
Podaj ulicę.
Lipowa 14
Podaj kod.
00-960
Podaj miasto.
Warszawa
Podaj wykształcenie.
wyższe
Podaj stanowisko.
informatyk
Wyświetlanie danych.
====================
Nazwisko: Nowak
Imię: Jan
Ulica: Lipowa 14
Kod: 00-960
Miasto: Warszawa
Wykształcenie: wyższe
Stanowisko: informatyk
8ba61431c02548173fa6085d93015e5a
8
140 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6.
Pliki tekstowe i pliki
o dostępie swobodnym
W tym rozdziale przedstawiłem typowe zadania, wraz z przykładowymi
rozwiązaniami, zawierające podstawowe operacje wejścia – wyjścia na plikach
tekstowych i plikach o dostępie swobodnym oraz proces serializacji i deseriali-
zacji obiektów do pliku.
Informacje ogólne
W języku C# operacje wejścia – wyjścia na plikach realizowane są poprzez
strumienie. Strumień jest pojęciem abstrakcyjnym — może on wysyłać
i pobierać informacje z fizycznego urządzenia (np. z konsoli lub dysku).
W tym rozdziale prezentuję typowe zadania, w których zostały wykorzy-
stane dwa rodzaje plików:
tekstowe,
o dostępie swobodnym.
Pliki tekstowe
Pliki tekstowe zawierają informacje niezakodowane, bezpośrednio czytelne.
Są one plikami o dostępie sekwencyjnym.
8ba61431c02548173fa6085d93015e5a
8
142 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 143
StreamWriter(Stream strumień);
Zadanie
6.1 Napisz zgodnie z zasadami programowania obiektowego program, który
wczytuje z klawiatury imię i nazwisko, zapisuje te dane do pliku tekstowego
dane.txt, a następnie odczytuje je z pliku dane.txt i wyświetla na ekranie
komputera. Klasa powinna zawierać trzy metody:
czytaj_dane() — wczytuje z klawiatury imię i nazwisko.
zapisz_dane_do_pliku() — zapisuje imię i nazwisko do pliku
tekstowego o nazwie dane.txt.
czytaj_dane_z_pliku() — odczytuje dane z pliku dane.txt
i wyświetla je na ekranie komputera.
Listing 6.1. Przykładowe rozwiązanie
using System;
using System.IO; // Tutaj znajduje się FileStream.
8ba61431c02548173fa6085d93015e5a
8
144 C#. Zadania z programowania z przykładowymi rozwiązaniami
{
class Plik_tekstowy
{
String dane, dane1;
FileStream fout, fin;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 145
8ba61431c02548173fa6085d93015e5a
8
146 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 147
Rysunek 6.1.
Wpisujemy dane do pliku tekstowego.
Efekt działania
Podaj imię i nazwisko:
programu Tomasz Kowalski
Zadanie 6.1
Odczytujemy dane z pliku tekstowego.
Tomasz Kowalski
Zadanie
6.2 Napisz zgodnie z zasadami programowania obiektowego program, który
tablicę o wymiarach 10 × 10 w postaci:
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
8ba61431c02548173fa6085d93015e5a
8
148 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
using System.IO;
Console.WriteLine();
Console.WriteLine("Zapisujemy tablicę 10 x 10 do pliku
´tekstowego.");
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 149
{
for (j = 0; j < rozmiar; j++)
{
fstr_out.Write((char)tablica[i, j]);
// Rzutujemy i zapisujemy tablicę do pliku.
Console.Write(tablica[i, j] + " ");
}
Console.WriteLine();
}
fstr_out.Close();
fout.Close();
}
Console.WriteLine();
Console.WriteLine("Odczytujemy tablicę1 10 x 10 z pliku
´tekstowego.");
Console.WriteLine();
fstr_in.Close();
fin.Close();
}
8ba61431c02548173fa6085d93015e5a
8
150 C#. Zadania z programowania z przykładowymi rozwiązaniami
matrix1.czytaj_dane(tablica, rozmiar);
matrix1.zapisz_dane_do_pliku(tablica, rozmiar);
matrix1.czytaj_dane_z_pliku(tablica1, rozmiar);
}
}
}
i
tablica1[i, j] = (int)fstr_in.Read();
// Rzutujemy i odczytujemy zawartość pliku, którą umieszczamy
// w tablicy1.
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 151
Rysunek 6.2.
Efekt działania Tworzymy tablicę 10 x 10.
programu 1000000000
Zadanie 6.2 0100000000
0010000000
0001000000
0000100000
0000010000
0000001000
0000000100
0000000010
0000000001
Zapisujemy tablicę 10 x 10 do pliku tekstowego.
1000000000
0100000000
0010000000
0001000000
0000100000
0000010000
0000001000
0000000100
0000000010
0000000001
Odczytujemy tablicę1 10 x 10 z pliku tekstowego.
1000000000
0100000000
0010000000
0001000000
0000100000
0000010000
0000001000
0000000100
0000000010
0000000001
8ba61431c02548173fa6085d93015e5a
8
152 C#. Zadania z programowania z przykładowymi rozwiązaniami
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
using System;
using System.IO;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 153
Console.WriteLine();
Console.WriteLine("Przepisujemy zawartość tablicy
´a do tablicy b.");
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Zapisujemy tablicę b do pliku
´tekstowego.");
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
154 C#. Zadania z programowania z przykładowymi rozwiązaniami
}
fstr_out.Close();
fout.Close();
}
Console.WriteLine();
Console.WriteLine("Odczytujemy tablicę c z pliku
´tekstowego.");
Console.WriteLine();
tab.czytaj_dane(a, n);
tab.przetwórz_dane(a, b, n);
tab.zapisz_dane_do_pliku(b, n);
tab.czytaj_dane_z_pliku(c, n);
}
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 155
Rysunek 6.3.
Efekt działania Tworzymy tablicę a.
programu 0000000000
Zadanie 6.3 1111111111
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
Przepisujemy zawartość tablicy a do tablicy b.
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
Zapisujemy tablicę b do pliku tekstowego.
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
Odczytujemy tablicę c z pliku tekstowego.
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
0100000000
8ba61431c02548173fa6085d93015e5a
8
156 C#. Zadania z programowania z przykładowymi rozwiązaniami
using System;
using System.IO;
char[] litery = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 157
tab.zapisz_czytaj_dane();
}
}
}
Rysunek 6.4.
Efekt działania
Dane odczytane z pliku to: A, B, C, D, E, F, G, H.
programu
Zadanie 6.4
Serializacja
Serializacja (ang. serialization) to proces przekształcania obiektów w strumień
bajtów z zachowaniem aktualnego stanu obiektu. Proces ten może zostać
utrwalony, np. w pamięci zewnętrznej komputera, np. poprzez zapisywanie
8ba61431c02548173fa6085d93015e5a
8
158 C#. Zadania z programowania z przykładowymi rozwiązaniami
Zadanie
6.5 Napisz program, który w pliku o dostępie swobodnym zamieszcza dane
z przeprowadzonych pomiarów typu double, a następnie wyświetla co drugi
pomiar na ekranie komputera. Dokonaj serializacji i deserializacji.
Listing 6.5. Przykładowe rozwiązanie
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
2 Proces taki może również zostać przesłany do innego procesu lub innego komputera np.
poprzez sieć.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 6. ♦ Pliki tekstowe i pliki o dostępie swobodnym 159
Console.WriteLine();
Console.WriteLine("Co drugi pomiar odczytany z pliku
´pomiary.dat: ");
pomiary = (double[])BinaryReader.Deserialize(StreamRead);
// Deserializacja i rzutowanie.
ser.zapisz_czytaj_dane();
}
}
}
Rysunek 6.5.
Efekt działania Wszystkie pomiary:
programu 10,17
12,83
Zadanie 6.5
11,78
15,23
11,08
13,67
8ba61431c02548173fa6085d93015e5a
8
160 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7.
Wprowadzenie
do współbieżności
W tym rozdziale omówiłem na przykładzie zadań wybrane zagadnienia
dotyczące paradygmatu programowania współbieżnego.
Informacje ogólne
Paradygmat programowania (ang. programming paradigm) jest wzorcem
programowania komputerów stosowanym przez programistów i preferowa-
nym w danym okresie rozwoju informatyki lub w pewnych okoliczno-
ściach bądź zastosowaniach. Paradygmat programowania definiuje sposób
patrzenia programisty na przepływ sterowania i wykonywania programu
komputerowego. Zależności między paradygmatami programowania mogą
przybierać skomplikowane formy, ponieważ jeden język programowania
może wspierać wiele różnych paradygmatów.
Przetwarzanie współbieżne (ang. concurrent computing) to coraz modniejszy
i niewątpliwie atrakcyjniejszy paradygmat programowania, oparty na współ-
istnieniu wielu wątków lub procesów operujących na współdzielonych danych.
Współbieżność to robienie więcej niż jednej rzeczy naraz. Program współ-
bieżny jest zbiorem programów sekwencyjnych wykonywanych równolegle.
Aplikacje współbieżne odgrywają coraz ważniejszą rolę we współczesnym
świecie informatyki. Panuje trend polegający na tym, że producenci
nowoczesnych procesorów dokładają nowe rdzenie zamiast zwiększać moc
8ba61431c02548173fa6085d93015e5a
8
162 C#. Zadania z programowania z przykładowymi rozwiązaniami
Wprowadzenie
do programowania równoległego
Programowanie równoległe powinno być stosowane w sytuacji, gdy istnieje
duża ilość pracy obliczeniowej, którą można podzielić na niezależne frag-
menty. Istnieją dwie formy równoległości: równoległość danych i równole-
głość zadań.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 163
Typ Obliczenia() jest zgodny z każdą metodą o typie zwrotnym int przyj-
mującą jeden parametr typu int, np.:
static int Kwadrat (int x) => x * x;
8ba61431c02548173fa6085d93015e5a
8
164 C#. Zadania z programowania z przykładowymi rozwiązaniami
Nawias jest opcjonalny, jeżeli parametr typu jest dokładnie jeden, np.:
x => x * x;
using System;
using System.Threading.Tasks;
Console.WriteLine("Rozpoczynam obliczenia...");
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 165
// Obliczenia sekwencyjne.
for (int i = 0; i < rozmiar; i++)
{
a[i] = 1;
}
// Obliczenie równoległe.
start = System.Environment.TickCount; // Zliczanie taktów procesora.
stop = System.Environment.TickCount;
Czas obliczeń może się różnić i być inny dla różnych konfiguracji kompu-
tera. W zadaniu nie jest wyświetlany wynik dodawania dwóch wektorów, lecz
tylko czas obliczeń sekwencyjnych i czas obliczeń równoległych.
Rezultat działania programu można zobaczyć na rysunku 7.1.
8ba61431c02548173fa6085d93015e5a
8
166 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.1.
Efekt działania Rozpoczynam obliczenia...
programu Obliczenia sekwencyjne trwały 499 ms.
Obliczenia równoległe trwały 172 ms.
Zadanie 7.1
Zadanie
7.2 Napisz program, który na bazie modyfikacji zadania 4.15 sekwencyjnie i rów-
nolegle mnoży dwie macierze kwadratowe typu int. Dodatkowo program
powinien zmierzyć czas obliczeń sekwencyjnych i czas obliczeń równoległych.
Listing 7.2. Przykładowe rozwiązanie
using System;
using System.Threading.Tasks;
Console.WriteLine("Rozpoczynam obliczenia...");
// Obliczenia sekwencyjne.
// Wpisywanie liczb do macierzy a.
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
a[i, j] = 1;
}
}
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 167
}
}
// Obliczenia równoległe.
start = System.Environment.TickCount; // Zliczanie taktów procesora.
8ba61431c02548173fa6085d93015e5a
8
168 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.2.
Efekt działania Rozpoczynam obliczenia...
programu
Obliczenia sekwencyjne trwały 1326 ms.
Zadanie 7.2
Obliczenia równoległe trwały 390 ms.
Zadanie
7.3 Napisz program, który za pomocą pętli Parallel.For sprawdza, czy wczytana
liczba jest liczbą pierwszą.
using System;
using static System.Math;
using System.Threading.Tasks;
Console.WriteLine("Podaj liczbę.");
n = Int32.Parse(Console.ReadLine());
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 169
if (pierwsza)
{
Console.WriteLine("Liczba {0} jest liczbą pierwszą.", n);
}
else
{
Console.WriteLine("Liczba {0} nie jest liczbą pierwszą.",
´n);
};
}
}
}
using System;
using static System.Math;
using System.Linq;
8ba61431c02548173fa6085d93015e5a
8
170 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.3.
Efekt działania Program sprawdza, czy wczytana liczba jest liczbą pierwszą.
programu Podaj liczbę.
Zadanie 7.3
34000
34000 dzieli się przez 2.
34000 dzieli się przez 4.
34000 dzieli się przez 25.
34000 dzieli się przez 34.
34000 dzieli się przez 40.
34000 dzieli się przez 68.
34000 dzieli się przez 80.
34000 dzieli się przez 100.
34000 dzieli się przez 125.
34000 dzieli się przez 136.
34000 dzieli się przez 10.
34000 dzieli się przez 16.
34000 dzieli się przez 17.
34000 dzieli się przez 50.
34000 dzieli się przez 170.
34000 dzieli się przez 85.
34000 dzieli się przez 5.
34000 dzieli się przez 8.
34000 dzieli się przez 20.
Liczba 34000 nie jest liczbą pierwszą.
using System.Threading.Tasks;
Console.WriteLine("Podaj liczbę.");
n = Int32.Parse(Console.ReadLine());
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 171
if ((n % (int)i) == 0)
{
Console.WriteLine("{0} dzieli się przez {1}.", n, i);
pierwsza = false;
}
});
if (pierwsza)
{
Console.WriteLine("Liczba {0} jest liczbą pierwszą.", n);
}
else
{
Console.WriteLine("Liczba {0} nie jest liczbą pierwszą.",
´n);
};
}
}
}
Rysunek 7.4.
Efekt działania Program sprawdza, czy wczytana liczba jest liczbą pierwszą.
programu Podaj liczbę.
1013
Zadanie 7.4
Liczba 1013 jest liczbą pierwszą.
8ba61431c02548173fa6085d93015e5a
8
172 C#. Zadania z programowania z przykładowymi rozwiązaniami
Wielowątkowość
Wątek (ang. thread) umożliwia wykonanie dodatkowych operacji równo-
cześnie. Jest to część programu realizowana współbieżnie w obrębie jed-
nego procesu. Można uruchomić wiele wątków w ramach jednego procesu.
Wątki obsługiwane są przez klasę Thread znajdującą się w przestrzeni
nazw System.Threading, którą trzeba dodatkowo włączyć do programu
poleceniem:
using System.Threading;
using System;
using System.Threading;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 173
Rysunek 7.5.
Efekt działania
Mój pierwszy wątek.
programu
Zadanie 7.5
Zadanie
7.6 Napisz program, który tworzy jeden wątek i go uruchamia. Metoda urucho-
miona w wątku będzie realizowała pętlę wypisującą na ekranie komputera
określoną liczbę znaków 0 (w programie jest ich 100). W programie głównym
będzie realizowana pętla wypisująca na ekranie taką samą ilość znaków 1.
Listing 7.6. Przykładowe rozwiązanie
using System;
using System.Threading;
8ba61431c02548173fa6085d93015e5a
8
174 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.6.
Efekt działania 11111111111111111111111111111100000000000000000000000000000000000
programu 00000000000000000000000000000000000000000000000000000000000000000
1111111111111111111………
Zadanie 7.6
Zadanie
7.7 Napisz program, który oblicza liczbę π w osobnym wątku.
using System;
using static System.Math;
using System.Threading;
Int32 i;
int licznik = 0;
double x, y, pi;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 175
if (x * x + y * y <= 1)
{
licznik += 1; // Liczy punkty znajdujące się w kole.
}
}
8ba61431c02548173fa6085d93015e5a
8
176 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.7.
Efekt działania Proszę czekać...
programu Obliczenia, wątek nr 3...
Wartość pi = 3,14159265358979
Zadanie 7.7
Obliczona wartość pi = 3,14165732
Błąd obliczeń wynosi: 6,46664102070815E-05
Obliczenia zakończone, wątek nr 3...
Czas obliczeń: 8814 ms
Praca z wątkami
Zadanie
7.8 Napisz program, który tworzy trzy odrębne wątki. Każdy z wątków reali-
zuje inne zadanie: pierwszy oblicza sumę dwóch macierzy kwadratowych
(zob. zadanie 4.13), drugi oblicza różnicę dwóch macierzy kwadratowych
(zob. zadanie 4.14). Trzeci wątek oblicza iloczyn dwóch macierzy kwadrato-
wych (zob. zadanie 4.15).
using System;
using System.Threading;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 177
{
a[i, j] = 1;
}
}
// Dodawanie macierzy a + b.
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
c[i, j] = a[i, j] + b[i, j];
}
}
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
178 C#. Zadania z programowania z przykładowymi rozwiązaniami
// Odejmowanie macierzy b – a
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
c[i, j] = b[i, j] - a[i, j];
}
}
Console.WriteLine();
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 179
}
}
// Mnożenie macierzy c = a * b.
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
c[i, j] = 0;
Console.WriteLine();
rm.Start();
rm.Join();
im.Start();
Thread.Sleep(250); // Usypiamy wątek na 250 milisekund.
8ba61431c02548173fa6085d93015e5a
8
180 C#. Zadania z programowania z przykładowymi rozwiązaniami
}
}
}
Linijka kodu:
Thread.Sleep(250); // Usypiamy wątek na 250 milisekund.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 181
Priorytety wątków
Zadanie
7.9 Napisz program, który oblicza liczbę π w n osobnych wątkach, gdzie n jest
liczbą logicznych rdzeni procesora1.
using System;
using static System.Math;
using System.Threading;
Int32 i;
int licznik = 0;
double x, y, pi;
if (x * x + y * y <= 1)
{
licznik += 1; // Liczy punkty znajdujące się w kole.
}
}
8ba61431c02548173fa6085d93015e5a
8
182 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 183
Klasa Task
Wątek to niskiego poziomu narzędzie przeznaczone do zapewnienia współ-
bieżności. Ma on jednak pewne ograniczenia, które utrudniają przygoto-
wanie dużych operacji współbieżnych przez połączenie mniejszych. Z tego
rodzaju problemami można sobie poradzić za pomocą klasy Task (czyli
zadanie). Klasa ta stanowi abstrakcję wyższego poziomu, gdyż przedstawia
współbieżną operację, która nie musi być wykonywana w oddzielnym wątku.
8ba61431c02548173fa6085d93015e5a
8
184 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.9 a.
Efekt działania Proszę czekać...
programu Liczba rdzeni logicznych = 8
Pi = 3,1416448, błąd = 5,21464102067881E-05, wątek nr 4
Zadanie 7.9
Czas obliczeń: 1389 ms.
— procesor Pi = 3,1416448, błąd = 5,21464102067881E-05, wątek nr 5
4-rdzeniowy Czas obliczeń: 1467 ms.
Pi = 3,1418852, błąd = 0,000292546410206818, wątek nr 3
Czas obliczeń: 1763 ms.
Pi = 3,1416512, błąd = 5,85464102069722E-05, wątek nr 7
Czas obliczeń: 1528 ms.
Pi = 3,141578, błąd = 1,46535897931344E-05, wątek nr 10
Czas obliczeń: 1389 ms.
Pi = 3,1406956, błąd = 0,000897053589793195, wątek nr 6
Czas obliczeń: 1841 ms.
Pi = 3,1417936, błąd = 0,00020094641020707, wątek nr 8
Czas obliczeń: 1685 ms.
Pi = 3,1417936, błąd = 0,00020094641020707, wątek nr 9
Czas obliczeń: 1778 ms.
using System;
using System.Threading.Tasks;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 185
Rysunek 7.9 b.
Efekt działania Proszę czekać...
Liczba rdzeni logicznych = 16.
programu Pi = 3,141508, błąd = 8,465358979314885E-05, wątek nr 12.
Zadanie 7.9 Pi = 3,1418636, błąd = 0,00027094641020708465, wątek nr 10.
— procesor Pi = 3,1417496, błąd = 0,0001569464102066931, wątek nr 18.
8-rdzeniowy Pi = 3,143332, błąd = 0,001739346410206899, wątek nr 6.
Czas obliczeń: 453 ms.
Czas obliczeń: 391 ms.
Czas obliczeń: 453 ms.
Czas obliczeń: 453 ms.
Pi = 3,1418636, błąd = 0,00027094641020708465, wątek nr 14.
Czas obliczeń: 454 ms.
Pi = 3,1425192, błąd = 0,0009265464102070631, wątek nr 17.
Czas obliczeń: 407 ms.
Pi = 3,1423096, błąd = 0,000716946410206809, wątek nr 11.
Czas obliczeń: 484 ms.
Pi = 3,1422652, błąd = 0,0006725464102070866, wątek nr 15.
Czas obliczeń: 485 ms.
Pi = 3,142284, błąd = 0,0006913464102069611, wątek nr 7.
Czas obliczeń: 500 ms.
Pi = 3,1417952, błąd = 0,00020254641020667208, wątek nr 13.
Czas obliczeń: 500 ms.
Pi = 3,1410944, błąd = 0,0004982535897930518, wątek nr 16.
Czas obliczeń: 500 ms.
Pi = 3,1412496, błąd = 0,0003430535897930298, wątek nr 8.
Czas obliczeń: 515 ms.
Pi = 3,1427388, błąd = 0,0011461464102069385, wątek nr 5.
Czas obliczeń: 515 ms.
Pi = 3,141554, błąd = 3,8653589792936316E-05, wątek nr 19.
Czas obliczeń: 469 ms.
Pi = 3,1419452, błąd = 0,0003525464102067666, wątek nr 20.
Czas obliczeń: 406 ms.
Pi = 3,1410696, błąd = 0,0005230535897933208, wątek nr 21.
Czas obliczeń: 375 ms.
{
Console.WriteLine("Moje pierwsze zadanie.");
});
8ba61431c02548173fa6085d93015e5a
8
186 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.10.
Efekt działania
Moje pierwsze zadanie.
programu
Zadanie 7.10
Praca z zadaniami
Klasa zadania Task oferuje wiele udogodnień dotyczących języka C# i pro-
gramowania obiektowego — od tworzenia list aż po korzystanie z nowych
algorytmów równoległych zaimplementowanych np. w metodach ForEach
klasy List<>. Ilustruje to zadanie 7.11.
Zadanie
7.11 Napisz program, który tworzy pewną liczbę zadań (Task), gdzie liczba_za
´dań = 4. Działanie tego programu polega na wypisaniu na ekranie infor-
macji o rozpoczęciu pracy zadania, wypisaniu wartości wylosowanej liczby
z przedziału od 0 do 100 oraz wypisaniu informacji o zakończeniu zadania.
Listing 7.11. Przykładowe rozwiązanie
using System;
using static System.Math;
using System.Collections.Generic;
using System.Threading.Tasks;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 187
Delegat Action (akcja) stosujemy, jeśli chcemy zapisać metodę, która nie
zwraca żadnej wartości. W naszym przypadku ten delegat ma postać:
Action zadanie = () =>
{
Console.WriteLine("Start zadania nr " + Task.CurrentId +
´".");
double liczba = Round(100 * (r.NextDouble()));
Console.WriteLine(" Wylosowana liczba to {0}.",
´liczba);
Console.WriteLine("Koniec zadania nr " + Task.CurrentId +
´".");
Console.WriteLine();
};
8ba61431c02548173fa6085d93015e5a
8
188 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.11.
Efekt działania Start zadania nr 1.
programu Wylosowana liczba to 11.
Koniec zadania nr 1.
Zadanie 7.11
Start zadania nr 2.
Wylosowana liczba to 17.
Koniec zadania nr 2.
Start zadania nr 3.
Wylosowana liczba to 80.
Koniec zadania nr 3.
Start zadania nr 4.
Wylosowana liczba to 93.
Koniec zadania nr 4.
Synchronizacja zadań
Przedstawię teraz metodę WaitAll(), która synchronizuje wykonywane
zadania.
Zadanie
7.12 Napisz program, który tworzy trzy dowolne zadania, a następnie je syn-
chronizuje.
using System;
using System.Threading.Tasks;
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 189
Task[] zadania =
{
zadanie_1, zadanie_2, zadanie_3
};
Task.WaitAll(zadania); // lub
// Task.WaitAll(zadanie_1, zadanie_2, zadanie_3);
// Obie linijki kodu są sobie równoważne.
}
}
}
lub
Task.WaitAll(zadania);
Rysunek 7.12.
Efekt działania Zadanie nr 1 o identyfikatorze 1 zakończone.
programu Zadanie nr 2 o identyfikatorze 2 zakończone.
Zadanie nr 3 o identyfikatorze 3 zakończone.
Zadanie 7.12
8ba61431c02548173fa6085d93015e5a
8
190 C#. Zadania z programowania z przykładowymi rozwiązaniami
Zadanie
7.13 Napisz program, który symuluje wyścig zadań w formie sztafety. Na starcie
znajdują się dwa zadania, zadanie_1 i zadanie_2, które rozpoczynają swój
bieg. Po chwili do biegu włączają się kolejno zadanie_3 i zadanie_4. Rolę
sędziego sztafety pełni metoda WaitAll(), która zgłasza komunikat o zakoń-
czeniu wyścigu wszystkich czterech zadań.
using System;
using System.Threading.Tasks;
zadanie_1.Start();
zadanie_2.Start();
8ba61431c02548173fa6085d93015e5a
8
Rozdział 7. ♦ Wprowadzenie do współbieżności 191
i akcja_2:
Action<Task> akcja_2 = (z) =>
{
Console.WriteLine("Zawodnik nr {0} wystartował
´po zawodniku nr {1}.", Task.CurrentId, z.Id);
Console.WriteLine("Zawodnik nr {0} zakończył bieg.",
´Task.CurrentId);
};
8ba61431c02548173fa6085d93015e5a
8
192 C#. Zadania z programowania z przykładowymi rozwiązaniami
Rysunek 7.13.
Efekt działania Zawodnik nr 1 wystartował.
programu Zawodnik nr 1 zakończył bieg.
Zawodnik nr 2 wystartował.
Zadanie 7.13
Zawodnik nr 2 zakończył bieg.
Zawodnik nr 3 wystartował po zawodniku nr 1.
Zawodnik nr 3 zakończył bieg.
Zawodnik nr 4 wystartował po zawodniku nr 2.
Zawodnik nr 4 zakończył bieg.
8ba61431c02548173fa6085d93015e5a
8
Rozdział 8.
Podążając
w kierunku funkcyjnego
paradygmatu
programowania
W tym rozdziale omawiam zarys funkcyjnego paradygmatu programowania.
Przedstawiam różnice pomiędzy imperatywnym a funkcyjnym paradygma-
tem, ilustrując je przykładem.
Wstęp
C# to współbieżny, oparty na klasach, nowoczesny obiektowy język pro-
gramowania i ogólnego zastosowania. Od wersji 8.0 i 9.0 język ten zyskał
wiele wygodnych mechanizmów znanych z paradygmatu programowania
funkcyjnego1.
1
Ostatnio na polskim rynku księgarskim pojawiła się książka dotycząca funkcyjnego pro-
gramowania w języku C# [2].
8ba61431c02548173fa6085d93015e5a
8
194 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Rozdział 8. ♦ Podążając w kierunku funkcyjnego paradygmatu programowania 195
Rysunek 8.1.
Podział głównych
paradygmatów
programowania
8ba61431c02548173fa6085d93015e5a
8
196 C#. Zadania z programowania z przykładowymi rozwiązaniami
namespace Linq_00
{
class Program
{
static void Main(string[] args)
{
var list = Enumerable.Range(1, 100).
Where(i => i % 20 == 0).OrderBy(i => i).Select(i =>
´$"{i}%");
Console.WriteLine();
}
}
}
Rysunek 8.2.
Efekt działania 20% 40% 60% 80% 100%
programu
8ba61431c02548173fa6085d93015e5a
8
Rozdział 8. ♦ Podążając w kierunku funkcyjnego paradygmatu programowania 197
Dla danego ciągu i predykatu filtrowanie daje nowy ciąg złożony z elemen-
tów danego ciągu, które są zgodne z predykatem (w LINQ jest to metoda
Where()), np.:
var list = Enumerable.Range(1, 20).Where(i => i % 4 == 0); // => [4 8 12 16 20]
Mając dany ciąg i funkcję klucza wyboru, sortowanie daje nowy ciąg upo-
rządkowany zgodnie z kluczem (w LINQ są to metody: OrderBy i OrderBy
´Descending), np.:
var list = Enumerable.Range(1, 6).OrderBy(i => -i); // => [6 5 4 3 2 1]
8ba61431c02548173fa6085d93015e5a
8
198 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
Polecana literatura
1. Z. Czech, Wprowadzenie do obliczeń równoległych, Wydawnictwo
Naukowe PWN, Warszawa 2010.
2. M. Herlihy, N. Shavit, Sztuka programowania wieloprocesorowego,
Wydawnictwo Naukowe PWN, Warszawa 2010.
3. P. Majdzik, Programowanie współbieżne. Systemy czasu rzeczywistego,
Helion, Gliwice 2012.
4. Praca zbiorowa, Programowanie równoległe i rozproszone, Oficyna
Wydawnicza Politechniki Warszawskiej, Warszawa 2009.
Bibliografia
1. J. Albahari, B. Albahari, C# 8.0. Leksykon kieszonkowy, Helion,
Gliwice 2020.
2. E. Buonanno, Programowanie funkcyjne w języku C#. Jak pisać lepszy
kod, Wydawnictwo Naukowe PWN, Warszawa 2019.
3. S. Cleary, Współbieżność w języku C#. Receptury, Helion, Gliwice 2017.
8ba61431c02548173fa6085d93015e5a
8
200 C#. Zadania z programowania z przykładowymi rozwiązaniami
8ba61431c02548173fa6085d93015e5a
8
8ba61431c02548173fa6085d93015e5a
8
8ba61431c02548173fa6085d93015e5a
8