Instrukcje sterujące w C#
Opracował dr Robert Fidytek
2
Instrukcje sterujące
Do tej pory zostały omówione instrukcje warunkowe if i if-else, instrukcje
iteracyjne for, while, do-while. Na dzisiejszym wykładzie zapoznamy się z
pozostałymi instrukcjami sterującymi:
●
instrukcja (wielokrotnego) wyboru
●
switch
●
instrukcje skoku
●
goto
●
break
●
continue
3
Instrukcja wyboru switch
Składnia:
switch
(wyrażenie)
{
case
wartośćA:
instrukcjeA;
break
;
case
wartośćB:
instrukcjaB;
break
;
case
wartośćC:
instrukcjeC;
break
;
...
case
wartośćN:
instrukcjeN;
break
;
default
:
instrukcje_default;
break
;
}
Zasada działania instrukcji wyboru switch:
1. Obliczana jest wartość wyrażenia wyrażenie.
2. Jeżeli któraś wartość (wartośćA, wartośćB, ...) stojąca
obok słowa case jest równa obliczonej wartości, to
wykonywane są instrukcje danego bloku case.
Po osiągnięciu instrukcji break następuje wyjście z
bloku instrukcji switch.
3. Jeżeli żadna wartość stojąca obok słowa case, nie
odpowiada obliczonej wartości wyrażenia wyrażenie,
wykonywane są instrukcje bloku default.
Po osiągnięciu instrukcji break następuje wyjście z
bloku instrukcji switch.
4. Jeżeli żadna wartość stojąca obok słowa case, nie
odpowiada obliczonej wartości wyrażenia wyrażenie i w
bloku instrukcji switch nie ma instrukcji default, to
następuje wyjście z bloku instrukcji switch.
4
Instrukcja wyboru switch
legenda:
wyr – wyrażenie
warA – wartośćA
warB – wartośćB
warC – wartośćC
5
Instrukcja wyboru switch
Zasady, których należy przestrzegać w
czasie stosowania instrukcji wyboru switch:
Dozwolone są jedynie wartości wyrażenia
wyrażenie, które w wyniku dają wartość typu
całkowitego (sbyte, byte, short, ushort, int, uint,
long, ulong), znakowego (char), wyliczeniowego
(enum) lub łańcuchowego (string).
Wartości wyrażenia (wartośćA, wartośćB, …)
stojące obok słowa case muszą być
niepowtarzalne i zgodne z typem wyrażenia
wyrażenie.
Koniec instrukcji danego bloku case musi zawierać
słowo kluczowe break (wyjątek stanowi przypadek,
gdy kilka wartości wyrażeń (np: wartośćA,
wartośćB) wskazuje na tą samą listę instrukcji lub
mamy do czynienia z inną instrukcją skoku).
Przykład:
switch
(wyrażenie)
{
case
wartośćA
:
case
wartośćB
:
instrukcjaB;
break
;
case
wartośćC:
instrukcjeC;
break
;
...
case
wartośćN:
instrukcjeN;
break
;
default
:
instrukcje_default;
break
;
}
6
Przykład: Liczba dni
//nie rozważamy dni przestępnych
string
miesiąc =
"maj"
;
int
liczba_dni;
switch
(miesiąc)
{
case
"luty"
:
liczba_dni = 28;
break
;
case
"kwiecień"
:
case
"czerwiec"
:
case
"wrzesień"
:
case
"listopad"
:
liczba_dni = 30;
break
;
default
:
liczba_dni = 31;
break
;
}
Console
.WriteLine(
"Miesiąc {0} ma {1} dni."
, miesiąc, liczba_dni);
Po zakończeniu bloku case
musi nastąpić instrukcja
skoku np. break.
7
Przykład: Dzień tygodnia
int
dzień=7;
//wersja z if
if
(dzień == 1)
Console
.WriteLine(
"poniedziałek"
);
else
if
(dzień == 2)
Console
.WriteLine(
"wtorek"
);
else
if
(dzień == 3)
Console
.WriteLine(
"środa"
);
else
if
(dzień == 4)
Console
.WriteLine(
"czwartek"
);
else
if
(dzień == 5)
Console
.WriteLine(
"piątek"
);
else
if
(dzień == 6)
Console
.WriteLine(
"sobota"
);
else
if
(dzień == 7)
Console
.WriteLine(
"niedziela"
);
else
Console
.WriteLine(
"niewłaściwy numer dnia tygodnia"
);
//wersja z switch
switch
(dzień)
{
case
1:
Console
.WriteLine(
"poniedziałek"
);
break
;
case
2:
Console
.WriteLine(
"wtorek"
);
break
;
case
3:
Console
.WriteLine(
"środa"
);
break
;
case
4:
Console
.WriteLine(
"czwartek"
);
break
;
case
5:
Console
.WriteLine(
"piątek"
);
break
;
case
6:
Console
.WriteLine(
"sobota"
);
break
;
case
7:
Console
.WriteLine(
"niedziela"
);
break
;
default
:
Console
.WriteLine(
"niewłaściwy numer dnia tygodnia"
);
break
;
}
8
Instrukcja (bezwarunkowego)
skoku goto
Skoki ze spadochronów nie są wcale takie niebezpieczne. No chyba, że skacze się bez sprzętu, a tym bardziej nago.
9
Instrukcja skoku goto
Instrukcja skoku goto pozwala na przeniesienie wykonywania programu do innego
miejsca w programie. Używanie instrukcji goto powoduje, że program staje się mniej
czytelny, dlatego też powinniśmy się starać jej unikać.
Składnia:
goto
etykieta
;
//przeniesienie do miejsca, gdzie jest zdefiniowana etykieta
...
etykieta :
//definicja etykiety (zakończona dwukropkiem)
Etykieta może mieć następujące formy:
a) identyfikator
b) case wartość
c) default
W przypadkach rodzajów etykiet b) i c) instrukcja skoku goto musi się znajdować w
bloku instrukcji wyboru switch.
Uwagi:
➔
Instrukcja goto nie może występować w bloku finally.
➔
Instrukcja goto nie może przenieść wykonywania kodu z jednej metody do drugiej.
10
//(1) etykieta w bloku zewnętrznym - dobrze
etykieta :
...
{
...
goto
etykieta
;
...
}
Etykiety w „różnych” blokach
//(2) etykieta w tym samym bloku - dobrze
goto
etykieta
;
...
etykieta :
...
//(3) etykieta w bloku wewnętrznym - źle
goto
etykieta
;
...
{
...
etykieta :
...
}
Gdańsk, Falowiec na ul. Obrońców Wybrzeża
11
Zastosowanie 1: Opuszczenie
wielokrotnie zagnieżdżonych pętli
Przykład poglądowy:
for
(...)
{
while
(...)
{
for
(...)
{
...
goto
etykieta
;
...
}
//for
}
//while
}
//for
etykieta :
instrukcje;
//Co zostanie wyświetlone na ekranie?
for
(
int
i = 1; i <= 10; i++)
{
for
(
int
j = 1; j <= 4; j++)
{
if
(i+j>3)
goto
skok
;
Console
.WriteLine(
"i={0}, j={1}"
,i,j);
}
}
skok :
Console
.ReadKey(
true
);
12
Zastosowanie 2: Ominięcie reguły
zabraniającej przejścia pomiędzy blokami
Przykład poglądowy:
switch
(c)
{
case
'a'
:
instrukcje_a;
goto
case
'A'
;
case
'A'
:
instrukcje_A;
break
;
...
case
'b'
:
instrukcje_b;
goto
default
;
default
:
instrukcje_default;
break
;
}
//Co zostanie wyświetlone na ekranie?
char
c=
'1'
;
switch
(c)
{
case
'1'
:
Console
.WriteLine(
"Bardzo"
);
goto
case
'2'
;
case
'2'
:
Console
.WriteLine(
"lubie"
);
goto
default
;
case
'3'
:
Console
.WriteLine(
"programować"
);
goto
default
;
default
:
Console
.WriteLine(
"komputery"
);
break
;
}
13
Instrukcja skoku break
Instrukcja skoku break powoduje przerwanie wykonywania
instrukcji iteracyjnej (pętli) lub instrukcji wyboru switch.
Przykład poglądowy:
//wyjście z najbardziej zagnieżdżonej pętli
while
(...)
{
for
(...)
{
...
if
(warunek)
break
;
...
}
//for
...
instrukcje_while;
...
}
//while
Jeżeli jest kilka pętli zagnieżdżonych
jedna w drugiej, to instrukcja skoku break
powoduje przerwanie tylko tej pętli, w
której bezpośrednio się znajduje.
14
Co zostanie wyświetlone na
ekranie?
//przykład 1
for
(
int
i = 1; i <= 10; i++)
{
if
(i % 5 == 0)
break
;
Console
.WriteLine(i*i*i);
}
//przykład 2
int
j = 15;
while
(--j > 7)
{
if
(j * j < 100)
break
;
Console
.WriteLine(j*j);
}
15
Co zostanie wyświetlone na
ekranie?
//przykład 1
for
(
int
i = 1; i <= 10; i++)
{
if
(i % 5 == 0)
break
;
Console
.WriteLine(i*i*i);
}
//przykład 2
int
j = 15;
while
(--j > 7)
{
if
(j * j < 100)
break
;
Console
.WriteLine(j*j);
}
16
Instrukcja skoku continue
Instrukcja skoku continue może występować wewnątrz instrukcji
iteracyjnych. W odróżnieniu od instrukcji skoku break instrukcja
skoku continue nie kończy działania pętli, ale przerywa tylko
aktualny obieg pętli i zaczyna następny kontynuując pracę pętli.
Przykład poglądowy:
//przerwanie wykonywania obiegu pętli i rozpoczęcie nowego
while
(...)
{
...
if
(warunek)
continue
;
...
}
//while
17
Co zostanie wyświetlone na ekranie?
//przykład 1
for
(
int
i = 1; i < 10; ++i)
{
if
(i % 2 == 1)
continue
;
Console
.Write(
"{0}, "
,i);
}
//przykład 2
int
j = -2;
while
(++j < 10)
{
if
(j++ %3 != 0)
continue
;
Console
.WriteLine(
"Wykonano pętle dla j={0}"
,j);
}
18
Szablon programu
//zmiana koloru tła
char
c;
do
{
Console
.WriteLine(
"Menu: g-green, r-red, b-blue, k-koniec"
);
c =
Console
.ReadKey(
true
).KeyChar;
switch
(c)
{
case
'g'
:
case
'G'
:
Console
.BackgroundColor =
ConsoleColor
.Green;
break
;
case
'r'
:
case
'R'
:
Console
.BackgroundColor =
ConsoleColor
.Red;
break
;
case
'b'
:
case
'B'
:
Console
.BackgroundColor =
ConsoleColor
.Blue;
break
;
}
Console
.Clear();
//wyczyszczenie i zamazanie okna tłem
}
while
(c !=
'k'
&& c !=
'K'
);
19
Wybrane metody i właściwości klasy Console
●
Console.BackgroundColor – kolor tła
●
Console.ForegroundColor – kolor czcionki
●
Console.Clear() - wyczyszczenie okna, zamazanie kolorem tła
●
Console.ReadKey(true).KeyChar – wartość typu char naciśniętego klawisza
●
Console.SetCursorPosition(kolumna, wiersz) – ustawienie pozycji kursora
(liczymy od zera)
●
Console.CursorLeft – numer kolumny, gdzie znajduje się kursor.
Kolumny są numerowane od lewej do prawej strony okna.
●
Console.CursorTop – numer wiersza, gdzie znajduje się kursor.
Wiersze numerowane są od góry do dołu okna.
●
Console.BufferHeight (Console.BufferWidth) – liczba dostępnych wierszy (kolumn) w
okienku.
●
Console.WindowHeight (Console.WindowWidth) – liczba widocznych wierszy (kolumn)
w oknie.
●
Console.LargestWindowHeight (Console.LargestWindowWidth) – maksymalna ilość
wierszy (kolumn) wyznaczona w oparciu o bieżącą wielkość fontu i rozdzielczość ekranu.
●
Console.Beep(częstotliwość, czas) - wydanie dźwięku o danej częstotliwości
podanej w Hz, przez określony czas podany w ms.
20
Zadanie 1
Popraw błędy:
double
zmienna = 6;
switch
(zmienna);
{
case
1, 2:
Console
.WriteLine(
"1 lub 2"
);
break
;
case
3:
case
4:
Console
.WriteLine(
"3 lub 4"
);
case
4:
Console
.WriteLine(
"4"
);
break
;
default
:
Console
.WriteLine(
"inna liczba"
);
}
21
Zadanie 2
Jaka jest różnica w działaniu pomiędzy instrukcjami
break i continue
wewnątrz pętli while?
22
Zadanie 3
//Jakie błędy popełniono w poniższym kodzie programu?
goto
skok;
for
(
double
i = 1, i <= 10, i++)
{
Console
.Write(i);
skok:
Console
.Write(
" * "
);
}
23
Zadanie 4
//Jakie liczby zostaną wypisane na ekranie?
int
i = 0, j = 3;
while
(++i <= 10)
{
j -= i;
if
(j > 0)
continue
;
else
if
(j < -5)
break
;
else
Console
.Write(
"{0}, "
, j);
}