background image

JiPP 3

4. Instrukcje. Obsługa 

wyj

ą

tków.

Włodzimierz Kasprzak

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

2

Treść

1.

Rodzaje instrukcji. 

2.

Instrukcje wyboru.

3.

Instrukcje pętli. 

4.

Instrukcje skoku. 

5.

Podstawowe wyjątki.

6.

Zgłaszanie wyjątku.

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

3



1. Rodzaje instrukcji



Instrukcja złoŜona



Blok



Instrukcje sterujące

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

4

Instrukcja złoŜona. Blok.



Nawiasy { } 
oznaczają

instrukcję złoŜoną

lub 

blok instrukcji

.



Blok zawiera 
przynajmniej jedną
instrukcję
deklaracji.

{

// instrukcje

}

{

// instrukcje

}

{

int i;

...

{

int i;

...

}

}

{

int i;

...

{

int i;

...

}

}

{

int i;

...

}

...

{

int i;

...

}

{

int i;

...

}

...

{

int i;

...

}



W bloku
wewnętrznym 

nie 

moŜna powtórzyć

definicji tej samej 
nazwy co 
zdefiniowana w 
bloku 
zewnętrznym. 



Definicje podane 
w blokach 

rozłącznych

nie 

mają ze sobą
związku. 

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

5

Instrukcje sterujące

Instrukcje wyboru

if , switch

Instrukcje wyboru

if , switch

Instrukcje pętli 

while, do, for, foreach

Instrukcje pętli 

while, do, for, foreach

Instrukcje skoku 

goto, break, continue

Instrukcje skoku 

goto, break, continue

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

6



2. Instrukcje wyboru



Instrukcja

if



Rozwijanie instrukcji

if



Instrukcja 

switch



Test: wykryj błędy

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

7

Instrukcja 

if



Składnia:



Nie ma niejawnej konwersji z 

int

do 

bool

int x;
...
if (x) ...

// Musimy pisać if (x != 0) w C#

if (x = 0) ... // Musimy pisać if (x == 0) w C#

int x;
...
if (x) ...

// Musimy pisać

if (x != 0)

w C#

if (x = 0) ... // Musimy pisać

if (x == 0)

w C#

if ( 

wyraŜenie-logiczne

)

pierwsza-instrukcja-zagnieŜdŜona

else

druga-instrukcja-zagnieŜdŜona

if ( 

wyraŜenie-logiczne

)

pierwsza-instrukcja-zagnieŜdŜona

else

druga-instrukcja-zagnieŜdŜona

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

8

Rozwijanie instrukcji 

if

enum Suit { Clubs, Hearts, Diamonds, Spades }
Suit trumps = Suit.Hearts; 
if (trumps == Suit.Clubs)

color = "Black";

else if (trumps == Suit.Hearts)

color = "Red";

else if (trumps == Suit.Diamonds)

color = "Red"; 

else

color = "Black";

enum Suit { Clubs, Hearts, Diamonds, Spades }
Suit trumps = Suit.Hearts; 
if (trumps == Suit.Clubs)

color = "Black";

else if (trumps == Suit.Hearts)

color = "Red";

else if (trumps == Suit.Diamonds)

color = "Red"; 

else

color = "Black";



Dla wzajemnie wykluczających się opcji.



else

wiązane jest z najbliŜszym poprzedzającym 

if

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

9

ZagnieŜdŜanie instrukcji 

if



Potencjalne niebezpieczeństwo niejednoznaczności –
ale 

else

wiązane jest z najbliŜszym poprzedzającym 

if .



Np. zamiar programisty wynika ze struktury:



Ale interpretacja kompilatora jest inna:

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

10

Instrukcja

switch



switch

- stosowana dla wyboru spośród wielu alternatyw



break

jest  wymagane  dla  zakończenia  pola  pojedynczej 

alternatywy – nie  ma  „cichego” przejścia  pomiędzy 
alternatywami (przy braku 

break

wystąpi błąd kompilacji)



Typem  wyraŜenia  dla 

switch

moŜe  być: 

int,  char,  enum, 

string

switch (trumps) {
case Suit.Clubs :
case Suit.Spades :

color = "Black"; break;

case Suit.Hearts :
case Suit.Diamonds :

color = "Red"; break; 

default:

color = "ERROR"; break;

}

switch (trumps) {
case Suit.Clubs :
case Suit.Spades :

color = "Black"; break;

case Suit.Hearts :
case Suit.Diamonds :

color = "Red"; break; 

default:

color = "ERROR"; break;

}

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

11

Instrukcja

switch



Grupowanie alternatyw 

case

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

12

Instrukcja

switch



Wykorzystanie instrukcji 

goto

Wymusza  przejście  do  innych 
alternatyw,  np.  pozwala  uniknąć
błędu z powodu braku 

break

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

13

Przykład: wykryj błędy.

if number % 2 == 0   ...

if number % 2 == 0   ...

if (percent < 0) || (percent > 100) ...

if (percent < 0) || (percent > 100) ...

if (minute == 60);

minute = 0;

if (minute == 60);

minute = 0;

switch (trumps) {
case Suit.Clubs, Suit.Spades :

color = "Black";

case Suit.Hearts, Suit.Diamonds :

color = "Red";

defualt :

...

}

switch (trumps) {
case Suit.Clubs, Suit.Spades :

color = "Black";

case Suit.Hearts, Suit.Diamonds :

color = "Red";

defualt :

...

}

2

2

2

3

3

3

4

4

4

1

1

1



Błąd



Błąd



Poprawne



3 błędy

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

14



3. Instrukcje pętli



Instrukcja

while 



Instrukcja

do 



Instrukcja

for 



Instrukcja

foreach 



Test: wykryj błędy

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

15

Instrukcja 

while



Warunek pętli jest 

wyraŜeniem logicznym



WyraŜenie logiczne sprawdzane jest na początku pętli. 



Instrukcja zawarta w pętli wykonuje się wtedy, gdy 
warunekl logiczny przyjmuje wartość

True

.

int i = 0;

// Inicjalizacja zmiennej - warunku p

ę

tli

while (i < 10) {

// Warunek p

ę

tli

Console.WriteLine(i);

// Instrukcja zawarta w p

ę

tli

i++;

// Instrukcja modyfikuj

ą

ca warunek p

ę

tli

}

int i = 0;

// Inicjalizacja zmiennej - warunku p

ę

tli

while (i < 10) {

// Warunek p

ę

tli

Console.WriteLine(i);

// Instrukcja zawarta w p

ę

tli

i++;

// Instrukcja modyfikuj

ą

ca warunek p

ę

tli

}

// Pętla wykona się dla i =
//  0 , 1,  2, 3, 4, 5, 6, 7,  8, 9

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

16

Instrukcja

do



Warunek

logiczny 

dla iteracji instrukcji zawartej w pętli. 



Warunek sprawdzany jest 

na końcu pętli

- instrukcja 

zawarta w pętli zawsze wykona się

przynajmniej raz,

a jest 

powtarzana wtedy, gdy  wartość warunku wynosi 

True

.



Instrukcję naleŜy zakończyć

średnikiem 

int i = 0;
do {

Console.WriteLine(i);
i++;

} while (i < 10);

// Warunek zakończony średnikiem

int i = 0;
do {

Console.WriteLine(i);
i++;

} while (i < 10)

;

// Warunek zakończony średnikiem

// Pętla wykona się dla i =
//  0 , 1,  2, 3, 4, 5, 6, 7,  8, 9

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

17

Instrukcja

for



Instrukcje modyfikacji umieszczone są na początku pętli. 



Zmienne definiowane w bloku 

for

są widoczne jedynie w tym 

zakresie – instrukcja 

for

moŜe być blokiem instrukcji.



W pętli

for

moŜna iterować wiele zmiennych. 

for (int i = 0; i < 10; i++) {

Console.WriteLine(i);           

}

for

(int i = 0; i < 10; i++) {
Console.WriteLine(i);           

}

// dla : 0 1 2 3 4 5 6 7 8 9

for (int i = 0; i < 10; i++)

Console.WriteLine(i);

Console.WriteLine(i); 

// BŁ

Ą

D: i jest poza zakresem

for (int i = 0; i < 10; i++)

Console.WriteLine(i);

Console.WriteLine(

i

); 

// BŁ

Ą

D: i jest poza zakresem

for (int i = 0, j = 0; ... ; i++, j++ )

for (int

i = 0, j = 0

; ... ; 

i++, j++

)

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

18

Instrukcja

foreach



W  System.Collections istnieje  klasa 

ArrayList –

umoŜliwia 

tworzenie kolekcji elementów określonego typu.



Pętla 

foreach

- wykonuje  zawarte  w  niej  instrukcje  dla 

kaŜdego  elementu  klasy  kolekcyjnej.  NaleŜy  podać typ  i 
nazwę iterowanej zmiennej

using System.Collections;
...
ArrayList numbers = new ArrayList( );
for (int i = 0; i < 10; i++ ) {

numbers.Add(i);

}
foreach (int number in numbers) {

Console.WriteLine(number);

}

using System.Collections;
...
ArrayList numbers = new ArrayList( );
for (int i = 0; i < 10; i++ ) {

numbers.Add(i);

}
foreach (int number in numbers) {

Console.WriteLine(number);

}

// dla: 0 1 2 3 4 5 6 7 8 9

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

19

Test: wykryj błędy

for (int i = 0, i < 10, i++)

Console.WriteLine(i);

for (int i = 0, i < 10, i++)

Console.WriteLine(i);

int i = 0;
while (i < 10)

Console.WriteLine(i);

int i = 0;
while (i < 10)

Console.WriteLine(i);

for (int i = 0; i >= 10; i++)

Console.WriteLine(i);

for (int i = 0; i >= 10; i++)

Console.WriteLine(i);

do

...
string line = Console.ReadLine( );
guess = int.Parse(line);

while (guess != answer);

do

...
string line = Console.ReadLine( );
guess = int.Parse(line);

while (guess != answer);

2

2

2

3

3

3

4

4

4

1

1

1

Nieskończona 

pętla !



Błąd

Warunek nie do 

spełnienia !



Błąd

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

20



4. Instrukcje skoku



Instrukcja

goto



Instrukcje

break

continue

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

21

Instrukcja

goto



Przeniesienie  wykonywania  programu  do  etykietowanej 
instrukcji znajdującej się w 

tym samym zakresie

.



MoŜna  wykonać skok  na  zewnątrz  instrukcji  złoŜonej  ale 
nigdy do wewnątrz bloku.



Stosowanie  instrukcji 

goto

nie  jest  zalecane  w 

programowaniu  strukturalnym  ani  obiektowym.  Jedyne 
jej zastosowanie – w połączeniu z instrukcją

switch

.

if (number % 2 == 0) goto Even;
Console.WriteLine("odd");
goto End;
Even:
Console.WriteLine("even");
End:;

if (number % 2 == 0) goto Even;
Console.WriteLine("odd");
goto End;
Even:
Console.WriteLine("even");
End:;

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

22

Instrukcje

break

continue



Instrukcja 

break

przerywa wykonanie pętli. 



Instrukcja

continue

przerywa  wykonanie  aktualnej 

iteracji danej pętli i przechodzi do następnej iteracji. 

Ale moŜna to samo osiągnąć bez skoków:

int i = 0;
while (true) {

Console.WriteLine(i);
i++;
if (i < 10) 

continue;

else

break;

}

int i = 0;
while (true) {

Console.WriteLine(i);
i++;
if (i < 10) 

continue

;

else

break

;

}

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

23



5. Podstawowe wyjątki



Motywacja



Klasy wyjątków



Bloki 

try

catch



Wielokrotne bloki 

catch

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

24

Motywacja



Tradycyjna  obsługa  błędów  jest  nieczytelna  poprzez  wstawienie 
dodatkowych  instrukcji  sprawdzających  poprawność danych  jest 
nieczytelna    (

mieszają się fragmenty  kodu

dla  normalnej  pracy  z 

fragmentami  przeznaczonymi  do  sprawdzania  i  ewentualnej  obsługi 
błędów). Szczególne trudności sprawia 

powrót do miejsc

obsługi błędów 

oddalonych o wiele poziomów wywołań metod.  

int errorCode = 0;
FileInfo source = new FileInfo("code.cs");
if (errorCode == -1) goto Failed;
int length = (int)source.Length;
if (errorCode == -2) goto Failed;
char[] contents = new char[length];
if (errorCode == -3) goto Failed;
... // tu wykona się sytuacja poprawna
Failed: ...

int errorCode = 0;

FileInfo source = new FileInfo("code.cs");

if (errorCode == -1) goto Failed;

int length = (int)source.Length;

if (errorCode == -2) goto Failed;

char[] contents = new char[length];

if (errorCode == -3) goto Failed;

... // tu wykona się sytuacja poprawna

Failed: ...

Obsługa błędu

Obsługa błędu

Normalny kod programu

Normalny kod programu

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

25

Klasy wyjątków

Exception

Exception

SystemException

SystemException

OutOfMemoryException

OutOfMemoryException

IOException

IOException

NullReferenceException

NullReferenceException

ApplicationException

ApplicationException

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

26

Bloki 

try

catch



Obsługa wyjątków ma charakter obiektowy.



Zwykły kod programu umieszczany jest wewnątrz bloku 

try



Obsługa błędów odbywa się w oddzielnym bloku 

catch

try {

Console.WriteLine

(„Wprowad

ź

liczb

ę

"

);

int i = int.Parse(Console.ReadLine());

}
catch (OverflowException wyjatek)
{

Console.WriteLine(wyjatek);

}

try {

Console.WriteLine

(„Wprowad

ź

liczb

ę

"

);

int i = int.Parse(Console.ReadLine());

}
catch (OverflowException wyjatek)
{

Console.WriteLine(wyjatek);

}

Obsługa wyjątków

Obsługa wyjątków

Normalny program

Normalny program

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

27

Wielokrotne bloki 

catch



Blok 

catch

przejmuje obsługę wyjątków pewnej klasy. 

try
{

Console.WriteLine(„Wprowadź pierwszą liczbę");
int i = int.Parse(Console.ReadLine());
Console.WriteLine(„Wprowadź drugą liczbę");
int j = int.Parse(Console.ReadLine());
int k = i / j;

}
catch (OverflowException wyjatek) {…}
catch (DivideByZeroException wyjatek) {…}

try
{

Console.WriteLine(„Wprowadź pierwszą liczbę");
int i = int.Parse(Console.ReadLine());
Console.WriteLine(„Wprowadź drugą liczbę");
int j = int.Parse(Console.ReadLine());
int k = i / j;

}
catch (OverflowException wyjatek) {…}
catch (DivideByZeroException wyjatek) {…}

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

28

Wielokrotne bloki catch



Blok

try

moŜe posiadać

jeden

ogólny blok catch



Blok 

catch

nie moŜe przechwycić wyjątku będącego typu 

klasy pochodnej od klasy wyjątku przechwyconego

przez 

wcześniejszy blok catch.

catch {…}
...
// lub 
...
catch (System.Exception) {…}

catch {…}
...
// lub 
...
catch (System.Exception) {…}

catch (Exception wyjatek) {…}
catch (OutOfMemoryException wyjatek) {…} 

// Bł

ą

d kompilacji

catch (Exception wyjatek) {…}
catch (OutOfMemoryException wyjatek) {…} 

// Bł

ą

d kompilacji

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

29



6. Zgłaszanie wyjątków



Instrukcja

throw 



Fraza

finally



Testowanie nadmiaru arytmetycznego 



Zalecenia dla obsługi wyjątków

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

30

Instrukcja

throw



Zgłoszenie wyjątku odpowiedniego typu klasy pochodnej 
od 

System.Exception



Powinniśmy  przekazać sensowną wiadomość poprzez 
obiekt wyjątku. 

throw

wyra

Ŝ

enie

;

throw

wyra

Ŝ

enie

;

if (minute < 1 || minute >= 60) {

throw new InvalidTimeException(minute + 

" to nie jest poprawna liczba minut");

// Nigdy nie osi

ą

gniemy tego miejsca !!

}

if (minute < 1 || minute >= 60) {

throw new InvalidTimeException(minute + 

" to nie jest poprawna liczba minut");

// Nigdy nie osi

ą

gniemy tego miejsca !!

}

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

31

Instrukcja

throw



W obsłudze wyjątku moŜna 

ponowić wyjątek



W obsłudze wyjątku moŜna teŜ zgłosić

nowy wyjątek



W bloku  catch moŜna  teŜ zgłosić

pusty  wyjątek

– jest  to 

równowaŜne 

ponowieniu obsługiwanego wyjątku

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

32

Fraza 

finally



Wszystkie  instrukcje  umieszczone  w  bloku 

finally

są zawsze 

wykonywane – niezaleŜnie od tego czy wystąpił wyjątek. 



W  bloku 

finally

moŜna  zgłosić wyjątek.  Jego  obsługą zajmie  się blok 

catch

przy 

zewnętrznym  bloku  try

.  Aktualnie  propagowany  wyjątek 

zostanie zgubiony.

Monitor.Enter(x); // Zainicjowanie zarządzanego zasobu
try {

...

}
finally {

Monitor.Exit(x); // Zwolnienie zarządzanego zasobu

}

Monitor.Enter(x); // Zainicjowanie zarządzanego zasobu
try {

...

}
finally {

Monitor.Exit(x); // Zwolnienie zarządzanego zasobu

}

Bloki catch są opcjonalne

Bloki catch są opcjonalne

try {

throw new PrzykladowyWyjatek(”Zostanie zgubiony”);

}
finally { throw new PrzykladowyWyjatek(”Zostanie przekazany”);
}

try {

throw new PrzykladowyWyjatek(”Zostanie zgubiony”);

}
finally { throw new PrzykladowyWyjatek(”Zostanie przekazany”);
}

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

33

Sprawdzenie arytmetycznego nadmiaru



Domyślnie wystąpienie nadmiaru w operacji arytmetycznej  

nie 

jest sprawdzane



Instrukcja 

checked

aktywuje sprawdzanie nadmiaru. 



Instrukcja 

unchecked

deaktywuje sprawdzanie nadmiaru. 

checked {

int number = int.MaxValue;
Console.WriteLine(++number);

}

checked {

int number = int.MaxValue;
Console.WriteLine(++number);

}

unchecked {

int number = int.MaxValue;
Console.WriteLine(++number);

}

unchecked {

int number = int.MaxValue;
Console.WriteLine(++number);

}

-2147483648

OverflowException

OverflowException

Zgłoszenie wyjątku. 
Instrukcja z  WriteLine nie 
wykona się.

MaxValue + 1 jest ujemne?

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

34

Zalecenia dla obsługi wyjątków



Zgłaszanie



Unikaj 

wyjątków 

dla 

sytuacji 

normalnych 

lub 

spodziewanych problemów



Nigdy nie twórz i nie zgłaszaj obiektów klasy Exception



PrzekaŜ napis z informacją do obiektu Exception



Zgłaszaj obiekty najbardziej specjalizowanej klasy wyjątków



Obsługa



Kolejność bloków catch - od specyficznego do ogólnego 



Nie zezwalaj na wyjście wyjątków  poza Main

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

35

Przykład 4.1: Konwersja liczby na datę

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

36

Przykład 4.1 (c.d.)

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

37

Przykład 4.2: Uzupełnienie programu 4.1 o wyjątki

background image

W.Kasprzak: JiPP3

4. Instrukcje. Wyjątki.

38

Przykład 4.2 (c.d.)