background image

 

Funkcje - wstęp 

background image

 

Przegląd zagadnień 

 

 

Wyodrębnioną część programu, stanowiącą pewną całość, mającą ustalony 
sposób wymiany danych (informacji) z pozostałymi częściami programu, która 
jest reprezentowana przez jednoznaczną nazwę i może być wywołana dowolną 
ilość razy w innej części programu nazywamy funkcją. Prościej można 
powiedzieć, że funkcja to ciąg instrukcji, który posiada nazwę, czyli jest to 
podprogram. 
W języku C# funkcje możemy tylko definiować wewnątrz klasy lub struktury. 
Funkcję zdefiniowaną w bloku kodu klasy lub struktury nazywamy metodą

Używanie funkcji w programie posiada następujące zalety: 

 

Możliwość wykorzystania wielokrotnie tego samego kodu bez 
konieczności jego przepisania. 

 

Uproszczenie kodu przez podział złożonego problemu na mniejsze i 
spójne logicznie fragmenty. 

 

Możliwość powtórnego użycia kodu w innym programie, dzięki 
tworzeniu bibliotek funkcji. 

 

Łatwiejsze testowanie i wykrywanie błędów logicznych - łatwiej 
przetestować mniejsze kawałki kodu, które mają realizować konkretne 
zadania. 

 

Program staje się mniejszy, mniej linii kodu, przez co staje się 
łatwiejszy do zrozumienia. 

 

Możliwość rozdzielenia pracy przy tworzeniu programu wśród kilku 
osób. 

 

Zmniejszenie rozmiaru pliku wynikowego. 

background image

 

Po zakończeniu tego rozdziału studenci nauczą się: 

 

Definiować metody w języku C#. 

 

Wywoływać metodę. 

 

Określać wartość przekazywaną przez metodę. 

 

Wymieniać informację między metodami przy pomocy zmiennych 
współdzielonych. 

 

Rozumieć mechanizm obsługi wyjątków w przypadku zgłoszenia 
wyjątku wewnątrz metody. 

 

Tworzyć bibliotekę własnych metod przy pomocy Visual Studio i z 
niej korzystać. 

Uwaga: 
W kursie tym omawiane jest tylko tworzenie metod statycznych. Metody nie 
statyczne i różnice miedzy metodami statycznymi i nie statycznymi jest 
dokładnie omówione w kursie "Programowanie obiektowe". 

background image

 

Definicja metody w języku C# 

 

 

W celu zdefiniowania metody stosujemy następującą notację: 

static typ_zwracany Nazwa(lista_argumentów) 

 

//ciało metody 

W powyższym zapisie jako typ_zwracany można podać dowolny typ, 
zarówno typ wartości jak i typ referencyjny. Przekazywanie wartości przez 
metodę zostanie dokładnie omówione w dalszej części tego rozdziału. Do tego 
czasu będziemy zakładać, że funkcja nie zwraca żadnej wartości. Realizuje się 
to przez podanie jako typ_zwracany słowa kluczowego void.  
Słowo nazwa oznacza nazwę metody, która w jednoznaczny sposób 
identyfikuje metodę. Nadawanie nazw metodom podlega tym samym regułom, 
co tworzenie identyfikatorów zmiennych, czyli nazwa może składać się z cyfr, 
liter i znaku podkreślenia, nazwa nie może rozpoczynać się od cyfry, nie może 
być słowem kluczowym i musi być unikalna w danym bloku kodu. Ostatnia 
reguła w przypadku metod ma jednak pewne wyjątki. Zostanie dokładnie to 
omówione w następnym rozdziale przy omawianiu tematu "Przeciążenie nazwy 
metody". Przy tworzeniu nazw metod należy stosować format PascalCase.  
Po nazwie metody umieszczamy nawisy okrągłe. Jeżeli metoda przyjmuje 
jakieś argumenty, to należy ich definicję umieści wewnątrz tych nawiasów. 
Przekazywanie argumentów do funkcji zostanie przedstawione w rozdziale 
dziewiątym " Przesyłanie argumentów do metody".  
Następnie po nawiasach okrągłych umieszczana jest definicja - przepis, co 
metoda ma realizować, czyli ciąg instrukcji które metoda wykonuje. Instrukcje 
te umieszcza się w nawiasach klamrowych. Czynność tę wykonywałeś już 
wielokrotnie definiując metodę Main.  

background image

 

W przedstawionej definicji metody występuje jeszcze słowo kluczowe 
static

. Dokładna jego interpretacja zostanie przedstawiona w kursie 

"Programowanie obiektowe". Na potrzeby tego kursu należy przyjąć, że musi 
ono występować. 
W przypadku metod, które będą wywoływane z metod definiowanych w innej 
klasie przed słowem static należy umieścić jeszcze słowo kluczowe 
public

. Dokładne znaczenie słowa kluczowego public zostanie równie 

omówione w kursie "Programowanie obiektowe". 

Poniżej przedstawiono przykładowy kod definiujący dwie metody: metodę 
Main oraz metodę Powitanie.  

class Program 

 

static void Main() 

 

 

 

//ciało metody Main  

 

 

public static void Powitanie() 

 

 

 

Console.WriteLine("Cześć!!!"); 

 

Wszystkie funkcje w języku C# są metodami, czyli muszą być definiowane 
wewnątrz klasy lub struktury.  
Metod nie wolno definiować wewnątrz innej metody, muszą być definiowane 
bezpośrednio w bloku kodu klasy lub struktury. 

 

background image

 

Wywołanie metody 

 

 

Wywołanie metody polega na wykonaniu ciągu instrukcji podanych w bloku 
kodu metody w miejscu wywołania. Metodę wywołuje się przez podanie jej 
nazwy zakończonej parą nawiasów okrągłych. W przypadku, gdy metoda 
pobiera argumenty, odpowiednie wartości lub zmienne należy podać wewnątrz 
nawiasów okrągłych. Więcej na temat przesyłania argumentów do metody 
będzie podane w rozdziale dziewiątym "Przesyłanie argumentów do metody". 
Przykład wywołania metody Powitanie w metodzie Main przedstawiono 
poniżej. 

class Program 

 

static void Main() 

 

 

 

Powitanie(); 

 

 

Console.ReadKey() 

 

 

public static void Powitanie() 

 

 

 

Console.WriteLine("Cześć!!!"); 

 

W wyniku działania powyższego programu na ekranie pojawi się napis: 

Cześć!!! 

W przypadku gdy metoda jest zdefiniowana w innej klasie niż metoda ją 
wywołująca, przy wywołaniu nazwę metody należy poprzedzić nazwą klasy, w 

background image

 

której jest zdefiniowana. Między nazwą klasy, a nazwą metody umieszczamy 
znak kropki (operator dostępu do składowej). Ilustruje to poniższy przykład. 

 

class Program 

 

static void Main() 

 

 

 

KlasaPomocnicza.Powitanie(); 

 

 

Console.ReadKey() 

 

class KlasaPomocnicza 

 

public static void Powitanie() 

 

 

 

Console.WriteLine("Cześć!!!"); 

 

Oczywiście, co już było wspominane wcześniej w tym rozdziale, w przypadku 
metod które będą wywoływane z metod definiowanych w innej klasie, przed 
słowem static koniecznie trzeba umieścić słowo kluczowe public. 
W przypadku gdy definicja klasy znajduje się w innej przestrzeni nazw, należy 
również uwzględnić nazwę przestrzeni nazw: 

NazwaPrzestrzeniNazw.NazwaKlasy.NazwaMetody(); 

lub użyć dyrektywy using. 

background image

 

Wartość zwracana przez metodę 

 

 

Wartość przekazana lub inaczej zwrócona przez metodę jest to wartość, która 
jest wstawiana w miejscu wywołania metody i jest to wartość wyrażenia 
występującego z prawej strony instrukcji return, należącej do instrukcji 
danej metody. Nazwa typu umieszczona przed nazwą metody określa typ 
wartości przekazanej. Typ wartości przekazanej musi być zgodny z typem 
wyniku wyrażenia stojącego obok instrukcji return - musi być identyczny 
lub musi istnieć konwersja niejawna z typu wyniku wyrażenia do typu wartości 
zwracanej. Rozważmy to na przykładzie. Napiszmy metodę, która przekazuje 
liczbę lat, które upłynęły od chrztu Polski. W celu uzyskania bieżącego roku 
użyjemy następującej konstrukcji: DateTime.Now.Year. Metoda 
przekazuje liczbę całkowitą i jej definicja może wyglądać następująco: 

static int LiczbaLat()  

//brak średnika!!! 


   int iloscLat = DateTime.Now.Year - 966; 
   return iloscLat; 

Metoda LiczbaLat przekazuje liczbę całkowitą i obok instrukcji return 
stoi zmienna typu całkowitego. Powyższą funkcję można zapisać krócej: 

static int LiczbaLat() 

   return DateTime.Now.Year - 966; 

Powyższą metodę możemy wykorzystać w następujący sposób: 

background image

 

int n = LiczbaLat(); 
Console.WriteLine("Liczba lat od chrztu Polski: {0}",  
 

 

n); 

lub krócej: 

Console.WriteLine("Liczba lat od chrztu Polski: {0}",  
 

 

LiczbaLat()); 

W obu przypadkach na ekranie pojawi się napis (zakładając że obecny rok to 
2006) 

Liczba lat od chrztu Polski: 1040 

Funkcję również możemy wywołać wewnątrz wyrażenia. Załóżmy, że od 
chrztu Polski rozpoczęto usypywać kopiec i co roku do kopca dodawano 243 
kamienie. W celu wypisania na ekranie z ilu kamieni aktualnie składa się 
kopiec możemy użyć następującego kodu. 

int liczbaKamieni = 243 * LiczbaLat(); 
Console.WriteLine("Ilość komieni z których składa się  
 

¬kopiec wynosi: {0}", liczbaKamieni); 

lub krócej 

Console.WriteLine("Ilość komieni z których składa się  
 

¬kopiec wynosi: {0}", 243 * LiczbaLat()); 

 

Instrukcja return oprócz zwrócenia wartości powoduje natychmiastowe 

wyjście z funkcji. Rozważmy na przykład funkcję obliczającą silnię. Można ją 
zaimplementować w następujący sposób: 

Uwaga: 
Silnia dla liczby n całkowitej nieujemnej oznaczamy znakiem wykrzyknika i 
określamy następującym wzorem: 

 

 

 

static long Silnia() 

 

uint n; 

 

Console.Write("Podaj n: "); 

 

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

 

if(n<2) 

 

 

return 1; 

 

long iloczyn = 1; 

 

for(uint i = 2;i <= n; i++) 

 

 

 

iloczyn *= i; 

 

 

return iloczyn; 

W powyższym przykładzie, jeżeli użytkownik nada zmiennej n wartość jeden 
lub zero, to metoda wykona instrukcję return 1, która spowoduje wyjście z 
metody oraz przekazanie wartości 1 przez metodę. Instrukcje zaznaczone 
czcionką pogrubioną nie zostaną wykonane. 

,...

3

,

2

,

1

*

)

1

(

*

...

*

2

*

1

0

1

!

n

dla

n

n

n

dla

n

background image

 

W przypadku gdy jako nazwa typu przekazywanego przez metodę pojawi się 
słowo void, przyjmuje się, że metoda nie zwraca żadnej wartości. W bloku 
kodu "metody void" może pojawić się instrukcja return. Oznacza ona tylko 
wyjście z metody i nie może obok niej pojawić się żadne wyrażenie. Za słowem 
return trzeba od razu postawić średnik.  

 

background image

 

 

Zmienne współdzielone i lokalne 

 

 

Zmienne zdefiniowane wewnątrz bloku metody lub jej podblokach noszą nazwę 
zmiennych lokalnych. Zmienne lokalne są dostępne tylko w bloku metody 
gdzie zostały zdefiniowane, a dokładniej można je używać od miejsca definicji 
do końca bloku gdzie zostały zdefiniowane. 

static void Metoda() 

 

... 

 

int x = 2; 

 

... 

 

 

  ... 

 

  int y = 1; 

 

  ... 

 

 

... 

W miejscu końca bloku kodu, pamięć zajmowana przez zmienne lokalne 
zdefiniowane w danym bloku zostaje zwolniona, dlatego też często fragment 
kodu od miejsca definicji zmiennej do końca bloku, w którym została 
zdefiniowana, nazywamy czasem życia zmiennej. Należy pamiętać, że 
zwolnienie pamięci zajmowanej przez zmienną typu referencyjnego, nie jest 
równoznaczne z zwolnieniem obiektu, do którego zmienna zawierała 
odwołanie. 

Zmienne możemy również definiować bezpośrednio w bloku klasy lub 
struktury. Zmienne takie definiujemy podobnie jak zmienne lokalne, z tym że 
całą definicję poprzedzamy słowem static. Zmienne te są wspólne dla 

"Czas życia" 
zmiennej y 

"Czas życia" 
zmiennej x 

background image

 

wszystkich metod danej klasy, dlatego można je nazwać zmiennymi 
współdzielonymi. Troszeczkę upraszczając możemy założyć, że zmienne 
współdzielone są dostępne od początku działania programu do jego końca we 
wszystkich metodach danej klasy. Mogą służyć one  do wymiany informacji 
między różnymi metodami. 

... 
class Program 
{  
   static int  Main(string[] args) 
   { 
      Console.Write("Podaj liczbę n: "); 
      n = Convert.ToUInt32(Console.ReadLine()); 
      Console.WriteLine("{0}! = {1}",n,Silnia()); 
      Console.ReadKey(); 
      return 0; 
   } 
 
   static uint n; //definicja zmiennej współdzielonej 
 
   static ulong Silnia() 
   { 
      ulong iloczyn = 1; 
      for(uint i = 2;i<=n;i++) 
         iloczyn*=i; 
      return iloczyn; 
   } 

W powyższym przykładzie zmienna współdzielona n jest używana zarówno w 
metodzie Silnia jak i metodzie Main. Jak widać nie ważna jest kolejność 
definicji metody i zmiennej współdzielonej. Zmienna współdzielona jest 
dostępna dla wszystkich metod danej klasy.  

Zmienna współdzielona może być również dostępna dla metod innych klas. 
Definicję takiej zmiennej należy wtedy poprzedzić słowem kluczowym 
public

. Odwołując się do zmiennej współdzielonej zdefiniowanej w innej 

klasie, jej nazwę należy poprzedzić nazwą klasy, w której jest zdefiniowana i 
znakiem kropki. W przypadku gdy klasy znajdują się w różnych przestrzeniach 
nazw nie wolni zapomnieć o nazwie przestrzeni nazw lub jej "zaimportowaniu" 
przy pomocy dyrektywy using . 

NazwaPrzestrzeni.NazwaKlasy.NazwaZmiennej; 

 

Zmienna lokalna może mieć tą samą nazwę co zmienna współdzielona. 

Jest to wyjątek od zasady, że w danym bloku kodu, dotyczy to również bloków 
zagnieżdżonych, nie można nadać jednego identyfikatora dwóm różnym 
elementom. Nadanie zmiennej lokalnej nazwy takiej samej jak nazwa zmiennej 
współdzielonej nazywamy przesłonięciem nazwy. W metodzie wewnątrz której 
zdefiniowana jest zmienna lokalna o identycznym identyfikatorze, jaki ma 
zmienna współdzielona, w celu odwołania się do zmiennej współdzielonej 
należy użyć konstrukcji: 
NazwaKlasy.NazwaZmiennejWspoldzielonej. 

class Klasa 

   ... 
   static int nazwa = 10; 

background image

 

... 
   static int Metoda() 
   { 
      ... 
      int nazwa = 200; 
      Console.WriteLine(nazwa); 

//200 

      Console.WriteLine(Klasa.nazwa); 

//10 

 

... 

   } 

Uwaga: 
Zmienne współdzielone najczęściej nazywane są polami statycznymi. Pola 
statyczne i ich prawdziwa istota i zastosowanie zostanie dokładnie omówione w 
kursie "Programowanie obiektowe". 

 

background image

 

Zgłoszenie wyjątku w metodzie 

 

 

W przypadku gdy wewnątrz metody zostanie zgłoszony wyjątek, na początku 
sprawdzane jest, czy instrukcja powodująca zgłoszenie wyjątku znajduje się w 
bloku try i z tym blokiem związany jest blok catch obsługujący zgłoszony 
wyjątek. Jeżeli taki blok istnieje wyjątek zostaje obsłużony. Natomiast gdy 
instrukcja powodująca wyjątek nie znajduje się w żadnym bloku try lub z 
żadnym blokiem try w którym znajduje się kod zgłaszający wyjątek nie jest 
skojarzony blok catch obsługujący dany wyjątek, program wraca w miejsce 
wywołania danej metody i traktuje instrukcję wywołania metody, jako 
instrukcję powodującą zgłoszenie wyjątku. Podczas powrotu do miejsca 
wywołania metody, wszystkie zmienne lokalne danej metody są usuwane - 
pamięć przez nie zajmowana jest zwalniana. Poszukiwanie bloku catch 
obsługującego zgłoszony wyjątek, odbywa się przez łańcuch funkcji 
wywołujących aż do metody Main. Jeżeli również w metodzie Main 
zgłoszony wyjątek nie jest przechwycony program kończy działanie. 

Proces przeglądania łańcucha wywołań funkcji w celu znalezienia 
odpowiedniego bloku catch, wraz ze zwolnieniem pamięci zajmowanej przez 
zmienne lokalne poszczególnych funkcji nazywamy zwijaniem stosu. 

 

 

background image

 

Pytania sprawdzające 

 

 

1.  Co to jest metoda? 

 
Odp. 
Najprościej metoda to funkcja zdefiniowana w klasie, czyli jest to 
wyodrębnioną część programu, stanowiącą pewną całość, mającą ustalony 
sposób wymiany danych (informacji) z pozostałymi częściami programu, 
która jest reprezentowana przez jednoznaczną nazwę i może być wywołana 
dowolną ilość razy w innej części programu oraz jest składową klasy lub 
struktury. 

2.  Kiedy zwalniana jest pamięć zajmowana przez zmienne lokalne? 

 
Odp. 
Pamięć zajmowana przez zmienne lokalne, zwalniana jest na końcu bloku w 
którym zdefiniowano daną zmienną. 

3.  Do czego służy instrukcja return? 

 
Odp. 
Instrukcja return ma dwa cele. Pierwszy, przekazanie do metody 
wywołującej wartości, drugi wyjście z (zakończenie) metody. 

4.  Jakim słowem oznaczamy, że funkcja nie przekazuje żadnej wartości? 

 
Odp. 
Jako typ zwracany w przypadku gdy metoda nie przekazuje żadnej wartości, 
używamy słowa void. 

background image

 

5.  Jak wywołujemy metodę która jest zdefiniowana w innej klasie? 

 
Odp. 
W przypadku gdy definicja metody znajduje się w innej klasie, aby ją 
wywołać, trzeba jej nazwę poprzedzić nazwą klasy w której jest 
zdefiniowana i znakiem kropki. Dodatkowo jeśli klasa, w której 
zdefiniowano metodę, znajduje się w innej przestrzeni nazw niż klasa 
metody wywołującej, nazwę klasy poprzedzamy nazwą przestrzeni nazw i 
znakiem kropki. 

6.  Co to jest proces zwijania stosu? 

 
Odp. 
Proces przeglądania łańcucha wywołań funkcji w celu znalezienia 
odpowiedniego bloku catch, wraz ze zwolnieniem pamięci zajmowanej 
przez zmienne lokalne poszczególnych funkcji nazywamy zwijaniem stosu. 

 

background image

 

Laboratorium 

 

 

Ćwiczenie 1: 
Napisz program wspierający pracę kasjera. Program pobiera cenę towaru 
zakupionego przez klienta oraz kwotę którą wpłaca klient, następnie wypisuje 
cenę brutto i kwotę podatku od danej ceny brutto oraz minimalną ilość 
banknotów i monet którą należy wydać klientowi w postaci reszty. Program 
podziel na metody: 

 

metodę pobierającą cenę netto i obliczającą cenę brutto. Po obliczeniu 
ceny brutto wypisuje ją na ekranie i pobiera kwotę wpłaconą przez 
klienta. W przypadku gdy cena brutto towaru jest większa od kwoty 
wpłaconej zgłoś wyjątek. Stawkę podatku przechowuj w stałej 
nazwanej StawkaPodatku. 

 

metodę wypisującą na ekranie cenę brutto, cenę netto, kwotę wpłaconą 
przez klienta i kwotę podatku.  

 

metodę wypisującą jak wydać resztę klientowi. Zakładamy, że chcemy 
resztę wydać przy użyciu minimalnej ilości banknotów i monet. 
Najpierw wydajemy banknot lub monetę o największym 
dopuszczalnym nominale. Czynność powtarzamy, aż do wydania nic 
nie pozostanie. Algorytm powyższy funkcjonuje na zasadzie, że 
wykonuje się działanie, które wydaje się najlepsze w danej chwili, nie 
uwzględniając tego, jak to wpłynie na wynik(wydajność) w 
przyszłości. Algorytmy działające według tej zasady nazywamy 
algorytmami zachłannymi (greedy algorithm). 

 

metody Main, która wywołuje w pętli powyższe metody. Metoda 
Main również obsługuje wyjątek zgłoszony przez metodę obliczającą 
cenę brutto towaru. 

background image

 

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: Kasjer.  

v.  nazwa rozwiązania: Lab8 

3.  Zdefiniuj trzy zmienne współdzielone typu decimal: cenaBrutto i 

kwotaWplacona, cenaNetto. 
 
static decimal cenaBrutto,kwotaWplacona, cenaNetto; 

4.  Zdefiniuj stałą nazwaną współdzieloną StawkaPodatku typu decimal 

i nadaj jej wartość 0,22. 
 
const decimal StawkaPodatku = 0.22m; 
 
Uwaga: 
Stał nazwane współdzielone definiujemy bez słowa static!!! 

5. 

Utwórz metodę Pobierz, która będzie pobierać od użytkownika cenę netto 
towaru i obliczać cenę brutto. Następnie wypisze cenę brutto i pobierze 
kwotę wpłaconą przez klienta. Jeżeli cena towaru brutto jest większa od 
kwoty wpłaconej przez użytkownika zgłoś wyjątek. Po pobraniu obu 
wartości (ceny netto i kwoty podanej przez klienta) oraz po obliczeniu ceny 
brutto zaokrąglij wszystkie wartości do dwóch miejsc po przecinku przy 
pomocy metody Round struktury Decimal.  
cenaNetto = 

Decimal

.Round(cenaNetto, 2);

 

Pilnuj aby wartości wprowadzone były większe od zera. 
 
static void Pobierz() 

   do 
   { 
      Console.Write("\nPodaj cenę (netto) towaru  
  

 

  ¬zakupionego przez klienta: "); 

      cenaNetto =  
  

    ¬Convert.ToDecimal(Console.ReadLine()); 

   } 
   while (cenaNetto <= 0); 
   cenaNetto = Decimal.Round(cenaNetto, 2); 
   cenaBrutto = Decimal.Round( 
  

 

cenaNetto * ( 1 + StawkaPodatku),2); 

   Console.WriteLine("Cena brutto wynosi: {0:C}",  
  

 

cenaBrutto); 

   do 

background image

 

   { 
      Console.Write("\nPodaj kwotę wpłaconą przez  
  

 

¬klienta: "); 

      kwotaWplacona =  
  

 

Convert.ToDecimal(Console.ReadLine()); 

   } 
   while (kwotaWplacona <= 0); 
   kwotaWplacona = Decimal.Round(kwotaWplacona, 2); 
   if (cenaBrutto > kwotaWplacona) 
      throw new Exception("Cena towaru nie może być  
  

 

¬większa od kwoty wpłaconej przez  

  

 

¬klienta!!!"); 

 

6.  Utwórz metodę Wypisz, która wypisuje na ekranie kwotę wpłaconą przez 

klienta, cenę brutto, cenę netto, kwotę podatku.  
 
static void Wypisz() 

   Console.WriteLine("\n\n\n*******************"); 
   Console.WriteLine("\nKwota wpłacona przez  
  

 

¬klienta: {0:C}", kwotaWplacona); 

   Console.WriteLine("\nCena netto: {0:C}",  
  

 

cenaNetto); 

   Console.WriteLine("\nCena brutto: {0:C}",  
  

 

cenaBrutto); 

   Console.WriteLine("\nWartość podatku: {0:C}",  
  

 

cenaBrutto - cenaNetto); 

7.  Utwórz metodę Reszta, która wypisuje na ekranie ilość poszczególnych 

banknotów i monet, które trzeba dać klientowi, aby wydać mu resztę. 
Rozpocznij od obliczenia ilości banknotów 100 zł, następnie 20 zł, 10 zł itd. 
 
static void Reszta() 

   decimal reszta = kwotaWplacona - cenaBrutto; 
   int ilosc = 0; 
   Console.WriteLine("\nWartość reszty należnej  
  

 

¬klientowi: {0:C}", reszta); 

   while (100 <= reszta) 
   { 
      ilosc++; 
      reszta -= 100; 
   } 
   if (ilosc != 0) 
   { 
      Console.WriteLine("\tLiczba banknotów {0:C}:  
  

 

¬{1}", 100, ilosc); 

      ilosc = 0; 
   } 
   while (50 <= reszta) 
   { 
      ilosc++; 
      reszta -= 50; 

background image

 

   } 
   if (ilosc != 0) 
   { 
      Console.WriteLine("\tLiczba banknotów {0:C}:  
  

 

¬{1}", 50, ilosc); 

      ilosc = 0; 
   } 
   ... 
   ... 
   ... 

8.  W metodzie Main wywołuj, póki jest klient do obsłużenia, powyżej 

zdefiniowane metody. Obsłuż również wyjątek zgłaszany w metodzie 
Pobierz. 
 
static void Main(string[] args) 

   char c='t'; 
   do 
   { 
      try 
      { 
         Pobierz(); 
         Wypisz(); 
         Reszta(); 
         Console.WriteLine("\n\nCzy jest jeszcze  
  

 

¬jakiś klient?"); 

         c = Console.ReadKey().KeyChar; 
      } 
      catch (Exception ex) 
      { 
         Console.WriteLine(ex.Message); 
      } 
   } 
   while (c == 't' || c == 'T'); 

9.  Skompiluj i uruchom program. 

Ćwiczenie 2: 
Napisz program obliczający całkę oznaczoną z funkcji nieujemnej i całkowalnej  
na zadanym przedziale np. f(x) = x

4

 + x

3

 + 2. Użytkownik ma do 

wyboru: 

 

metodę (metoda prostokątów lub metoda trapezów) 

 

przedział całkowania 

 

liczbę podziałów (podprzedziałów) 

Polecenie powyższe jest identyczne z poleceniem do laboratorium w rozdziale 
5, gdzie jest również opisany algorytm obliczenia całki metodą trapezów i 
prostokątów. W odróżnieniu od poprzedniego laboratorium w poniższym 
zastosuj następujący podział na metody: 

 

Utwórz oddzielną klasę MetodyCalkowania zawierającą następujące 
elementy: 

background image

 

Definicję typu wyliczeniowego Metody, który ma dwa elementy 
Prostokatow=1 oraz Trapezow=2 

Zmienne współdzielone zawierające wartość początku przedziału 
całkowania, końca przedziału całkowania, liczbę podziałów oraz 
zmienną pomocniczą, dla której jest obliczana wartość funkcji 
całkowanej w kolejnych iteracjach. 

Metodę obliczającej wartość dla funkcji całkowanej: 
f(x) = x

4

 + x

3

 + 2 

i ją zwracającą do programu 

Funkcja ta korzysta z współdzielonej zmiennej pomocniczej. 

o  Metodę obliczającej wartość całki metodą trapezów i zwracającą ją do 

programu. 

Metodę obliczającej wartość całki metodą prostokątów i zwracającą ją 
do programu. 

Metodę ustawiającej koniec i początek przedziału. 

Metodę zmieniającej ilość podziałów. 

 

Do klasy Program dodaj następujące elementy: 

Zmienną współdzieloną zawierającą informacje o aktualnie wybranej 
metodzie całkowania. 

Metodę wyświetlającą menu i przekazującą pozycję menu wybraną 
przez użytkownika. 

Metodę dającą użytkownikowi możliwość wyboru metody całkowania 
i przekazującą wybór użytkownika do programu. 

Metody obliczającej całkę metodą wybraną przez użytkownika (wybór 
jest zawarty w zmiennej współdzielonej) i wypisującą jej wartość na 
ekranie. 

 

W metodzie Main w pętli wyświetl menu, a następnie w zależności od 
wyboru użytkownika wywołaj odpowiednią metodę. 

 

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: Calka 

2.  Uczyń nowo utworzony projekt projektem startowym 

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

kontekstowego wybierz Set as StartUp Project. 

albo, gdy rozpoczynasz laboratorium od tego ćwiczenia 

background image

 

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: Calka.  

v.  nazwa rozwiązania: Lab8 

3. 

Wewnątrz przestrzeni nazwa Calka, utwórz oddzielną klasę 
MetodyCalkowania zawierającą następujące elementy: 
 
namespace Calka 

   .... 
   class MetodyCalkowania 
   { 
 

   ... 

 

   //definicja poszczególnych elementów 

   } 

a.  Definicję typu wyliczeniowego Metody, który ma dwa elementy 

Prostokatow=1 oraz Trapezow=2 
 
public enum Metody{Prostokatow=1, Trapezow=2} 

b.  Zmienne współdzielone zawierające wartość początku przedziału 

całkowania - PoczatekPrzedzialu, końca przedziału  całkowania 
- KoniecPrzedzialu, liczbę podziałów - LiczbaPodzialow 
oraz zmienną pomocniczą - x, dla której jest obliczana wartość funkcji 
całkowanej w kolejnych iteracjach. Nadaj wartości: zmiennej 
reprezentującej początek przedziału wartość zero, zmiennej 
reprezentującej koniec przedziału wartość 1, zmiennej reprezentującej 
liczbę podziałów wartość 10. 
 
public static double PoczatekPrzedzialu = 0; 
public static double KoniecPrzedzialu = 1; 
public static uint LiczbaPodzialow = 10; 
static double x; 

c.  Metodę f obliczającej wartość dla funkcji całkowanej: 

f(x) = x

4

 + x

3

 + 2 

i ją zwracającą do programu 

Funkcja ta korzysta z współdzielonej zmiennej pomocniczej. 
 
static double f() 

   return x * x * x * (x + 1) + 2; 

background image

 

d.  Metodę Trapezow obliczającej wartość całki metodą trapezów i 

zwracającą ją do programu. Opis algorytmu obliczającego całkę 
metodą trapezów znajduje się w laboratorium w rozdziale 5. W celu 
obliczenia wartości funkcji w danym punkcie, wywołuj metodę 
zdefiniowaną w kroku poprzednim. Pamiętaj jednak, aby wcześniej 
ustawić odpowiednią wartość pomocniczej zmiennej współdzielonej - 
x. 
 
public static double Trapezow() 

   double suma = 0; 
   double dx = (KoniecPrzedzialu -  
      PoczatekPrzedzialu) / LiczbaPodzialow; 
   x = PoczatekPrzedzialu; 
   for (int i = 1; i < LiczbaPodzialow; i++) 
   { 
      x += dx; 
      suma += f(); 
   } 
   x = PoczatekPrzedzialu; 
   double tmp = f(); 
   x = KoniecPrzedzialu; 
   tmp += f(); 
   suma += tmp / 2; 
   suma *= dx; 
   return suma; 

e.  Metodę Prostokatow obliczającej wartość całki metodą 

prostokątów i zwracającą ją do programu. Opis algorytmu 
obliczającego całkę metodąprostokątów znajduje się w laboratorium w 
rozdziale 5. W celu obliczenia wartości funkcji w danym punkcie, 
wywołuj metodę zdefiniowaną w dwa kroki wcześniej. Pamiętaj 
jednak, aby wcześniej ustawić odpowiednią wartość pomocniczej 
zmiennej współdzielonej. 
 
public static double Prostokatow() 

   double suma = 0; 
   double dx = (KoniecPrzedzialu -  
      PoczatekPrzedzialu) / LiczbaPodzialow; 
   double x = PoczatekPrzedzialu; 
   for (int i = 0; i < LiczbaPodzialow; i++) 
   { 
      x += dx; 
      suma += f(); 
   } 
   suma *= dx; 
   return suma; 

f.  Metodę UstawPrzedzial ustawiającej koniec i początek 

przedziału. Pilnuj, aby koniec przedziału miał większą wartość niż 
początek. 
 
public static void UstawPrzedzial() 

background image

 


   do 
   { 
      if(PoczatekPrzedzialu > KoniecPrzedzialu) 
      { 
         Console.Write("\nPoczątek musi być  
 

 

 

¬mniejszy od końca: "); 

      } 
      Console.Write("\nPodaj początek  
 

 

 

¬przedziału: "); 

      PoczatekPrzedzialu =  
 

 

    Convert.ToDouble(Console.ReadLine()); 

      Console.Write("Podaj koniec przedziału:  
 

 

 

¬ "); 

      KoniecPrzedzialu =  
 

 

    Convert.ToDouble(Console.ReadLine()); 

   } 
   while(PoczatekPrzedzialu>KoniecPrzedzialu); 

g.  Metodę zmieniającej ilość podziałów. Pilnuj, aby wartość liczby 

podziałów była większa od zera. 
 
public static void UstawLiczbePodzialow() 

   Console.Write("\nPodaj liczbę podziałów: "); 
   LiczbaPodzialow =  
 

 

    Convert.ToUInt32(Console.ReadLine()); 

   if (LiczbaPodzialow == 0) 
      throw new Exception("Liczba podziałów  
 

 

 

¬musi być większa od zera"); 

4.  Do klasy Program, klasy wygenerowanej automatycznie przez Visual 

Studio, dodaj następujące elementy: 

a.  Zmienną współdzieloną zawierającą informacje o aktualnie wybranej 

metodzie całkowania. Nadaj zmiennej wartość. 
 
static MetodyCalkowania.Metody metoda =  
 

 

 

MetodyCalkowania.Metody.Prostokatow; 

b.  Metodę wyświetlającą menu i przekazującą pozycję menu wybraną 

przez użytkownika. 
 
static char Menu() 

   Console.WriteLine("\nPrzedział całkowania:  
 

 

 

¬<{0}; {1}>",  

 

 

 

MetodyCalkowania.PoczatekPrzedzialu,  

 

 

 

MetodyCalkowania.KoniecPrzedzialu); 

   Console.WriteLine("Liczba podziałów: {0}",  
 

 

 

MetodyCalkowania.LiczbaPodzialow); 

   Console.WriteLine("Metoda całkowania: {0}",  
 

 

 

metoda); 

   Console.WriteLine("\t\t\tA - Zmiana  
 

 

 

przedziału"); 

background image

 

   Console.WriteLine("\t\t\tB - Zmiana liczby  
 

 

 

podziałów"); 

   Console.WriteLine("\t\t\tC - Zmiana metody  
 

 

 

całkowania"); 

   Console.WriteLine("\t\t\tD - Policz całkę"); 
   Console.WriteLine("\t\t\tK - Koniec"); 
   return Console.ReadKey(true).KeyChar; 

c.  Metodę dającą użytkownikowi możliwość wyboru metody całkowania 

i przekazującą wybór użytkownika do programu. 
 
static MetodyCalkowania.Metody  
 

 

 

 

UstawMetodeCalkowania() 


   int m = 1; 
   do 
   { 
      if (m != 1) 
      { 
         Console.WriteLine("\nNaciśnij 1 lub 2:  
 

 

 

 

 

¬"); 

      } 
      Console.WriteLine("\nPodaj metodę  
 

 

 

 

¬liczenia całki : "); 

      Console.WriteLine("\t1 - Metoda  
 

 

 

 

 

¬prostokątów"); 

      Console.WriteLine("\t2 - Metoda trapezów:  
 

 

 

 

 

¬"); 

      m = Convert.ToInt32(Console.ReadLine()); 
   } 
   while (!(m == 1 || m == 2)); 
   return (MetodyCalkowania.Metody)m; 

d.  Metody obliczającej całkę metodą wybraną przez użytkownika (wybór 

jest zawarty w zmiennej współdzielonej) i wypisującą jej wartość na 
ekranie. W celu obliczenia wartości całki wywołaj odpowiednie 
metody z klasy MetodyCalkowania. 
 
static void ObliczCalke() 

   double calka = 0; 
   switch (metoda) 
   { 
      case MetodyCalkowania.Metody.Prostokatow: 
        calka = MetodyCalkowania.Prostokatow(); 
         break; 
      case MetodyCalkowania.Metody.Trapezow: 
         calka = MetodyCalkowania.Trapezow(); 
         break; 
   } 
   Console.Write("\nPrzybliżona wartość całki  
 

 

¬funkcji f(x) w przedziale <{0}; {1}>  

 

 

¬wynosi: {2}", 

 

 

MetodyCalkowania.PoczatekPrzedzialu,  

background image

 

 

 

MetodyCalkowania.KoniecPrzedzialu, calka); 

   Console.ReadKey(true); 

 

5.  W metodzie Main w pętli wyświetl menu, a następnie w zależności od 

wyboru użytkownika wywołaj odpowiednią metodę. 
 
static void Main(string[] args) 

   char c; 
   do 
   { 
      c = Menu(); 
      switch (c) 
      { 
         case 'a': 
         case 'A': 
            MetodyCalkowania.UstawPrzedzial(); 
            break; 
         case 'b': 
         case 'B': 
          MetodyCalkowania.UstawLiczbePodzialow(); 
            break; 
         case 'c': 
         case 'C': 
            metoda = UstawMetodeCalkowania(); 
            break; 
         case 'd': 
         case 'D': 
            ObliczCalke(); 
            break; 
      } 
   } 
   while (!(c == 'k' || c == 'K')); 

6.  Skompiluj i uruchom program.