1 Instrukcje sterujace (materia Nieznany (2)

background image

Pozostałe instrukcje sterujące

background image

Przegląd zagadnień

W module tym poznamy pozostałe instrukcje sterujące. Zostanie omówiona
instrukcja wielokrotnego wyboru switch oraz instrukcje skoku.
Zaprezentowany zostanie też pewien szablon programu.

Po skończeniu tego modułu studenci powinni umieć wykorzystywać
następujące instrukcje:

switch

goto

break

continue

background image

Instrukcja wyboru switch

Przy omawianiu instrukcji wyboru if zostało wspomniane o wyborze
wielowariantowym. Jako wybór wielowariantowy bardziej od instrukcji if,
nadaje się instrukcja switch. Ogólna postać instrukcji switch jest
następująca:

switch(wyrazenie)

//nie ma średnika

{

case wartoscA: instrA1;

...;

instrAn;

break;

...

case wartoscN: instrN1;

...;

instrNn;

break;

default : instr1;

...;

instrn;

break;

}

Wartość wyrażenia wyrazenie musi być typu całkowitego (sbyte,
byte, short, ushort, int, uint, long, ulong, char) lub
dowolnego typu wyliczeniowego lub typu string lub typu, z którego istnieje
konwersja niejawna do jednego z podanych wcześniej typów. Wartości stojące
obok słowa case (wartoscA ... wartoscN) muszą być znane w czasie
kompilacji, czyli mogą być to literały lub stałe nazwane .Wartości te nie mogą

background image

się powtarzać. Typ wartości stojących obok słowa case musi być zgodny z
typem wyrażenia wyrazenie.

Działanie instrukcji switch można przedstawić w kilku krokach:

1. Obliczana jest wartość wyrażenia wyrazenie.

2. Jeżeli któraś wartość 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 wyrazenie, 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 wyrazenie i w bloku instrukcji
switch nie ma instrukcji default, to następuje wyjście z bloku
instrukcji switch.

Blok default może wystąpić w bloku instrukcji switch najwyżej jeden
raz.

Jeżeli chcemy, aby dane instrukcje były wykonywane dla kilku wartości
wyrażenia wyrazenie, należy postąpić jak w poniższym przykładzie, który
oblicza liczbę dni w miesiącu, nie uwzględniając lat przestępnych. Zmienna
miesiac zawiera numer miesiąca w roku.

int liczbaDni = 0;
switch(miesiac)
{

case 2 : liczbaDni = 28;
break;
case 4 :
case 6 :
case 9 :
case 11 : liczbaDni = 30;
break;
default : liczbaDni = 31;
break;
}

Trzeba pamiętać, że jeśli w bloku case lub default występuje jakaś
instrukcja, to przed rozpoczęciem nowego bloku case, defaut lub nawiasem
klamrowym zamykającym blok instrukcji switch, musi wystąpić instrukcja
skoku: break, goto, throw oraz return. Instrukcja goto zostanie
omówiona w dalszej części tego rozdziału. Brak instrukcji skoku jest nazywany
błędem przejścia (no fall through rule). Wyjątkiem od tej reguły jest sytuacja,
gdy po case występuje pętla nieskończona. Reguła ta różni język C# np. od
języków C/C++. Pozwolenie na przejście między blokami case było
przyczyną licznych błędów logicznych w programach napisanych w C/C++.
Poniższy kod spowoduje więc błąd kompilatora.

switch(c)
{
case 'a': instrA1;

//brak instrukcji skoku

background image

case 'A': instrukcjaA1;
instrukcjaA2;
...
break;

case 'b': instrB1; //brak instrukcji skoku
case 'B': instrukcjaB1;
instrukcjaB2;
...
break;
default: instrukacja1;

//brak instrukcji skoku


}

Rozwiązanie problemu, gdy jest potrzeba uruchomienia kodu zawartego w inny
bloku case, po kodzie w danym bloku case, jest przedstawione przy
omawianiu instrukcji goto w tym module.

background image

goto

Instrukcja goto jest instrukcją o "złej sławie". Używanie instrukcji goto
powoduje, że program staje się nieczytelny. Powinniśmy się, więc starać jej
unikać. Instrukcja goto ma następującą formę:

goto etykieta;

Po napotkaniu takiej instrukcji wykonywanie programu przenosi się do miejsca
gdzie jest zdefiniowana dana etykieta. Definicja etykiety składa się z jej nazwy
i znaku dwukropka.

etykieta :

Etykieta może mieć następujące formy:

identyfikator

case wartosc

default

W przypadku dwóch ostatnich rodzajów etykiet, instrukcja goto musi się
znajdować w bloku instrukcji switch. W przypadku pierwszym, goto może
skoczyć do etykiety na zewnątrz bloku lub do etykiety w tym samym bloku.
Nie może skoczyć do etykiety, która jest zdefiniowana w bloku
zagnieżdżonym, wewnętrznym w stosunku do bloku instrukcji goto.
Instrukcja goto nie może występować w bloku finally.

Uwaga:
Instrukcja goto nie może przenieść wykonania kodu z jednej metody do
drugie - nie może "skakać" między metodami

background image

Etykieta w bloku
zewnętrznym - OK

Etykieta w tym samym
bloku - OK

Etykieta w bloku
wewnętrznym - źle

et:
...
{
...
goto et;
...
}

goto et;
...
et:
...

goto et;
...
{
...
et:
...
}

W przypadku, gdy etykieta nie jest dostępna, podczas kompilacji zgłaszany jest
błąd

Mimo złej sławy są dwie sytuacje, kiedy instrukcja goto jest na pewno
przydatna.

1. Natychmiastowe opuszczenie wielokrotnie zagnieżdżonych pętli.


while(...){
...
for(...){
...
while(...){
...
goto Etykieta;
}
}
}
Etykieta:
instrukcja1;

2. W celu ominięcia reguły zabraniającego przejścia między blokami

case lub blokiem default (no fall through rule).

switch(c)
{
case 'a':instrA1;
goto case 'A';
case 'A':instrukcjaA1;

instrukcjaA2;

...

break;

case 'b': instrB1;
goto default;
default: instrukacja1;
break;
}

background image

break

Poznaliśmy już wcześniej działanie instrukcji break - polegało na przerwaniu
wykonywania instrukcji switch. Oprócz tego break może również
przerywać działanie pętli. Jeśli jest kilka pętli zagnieżdżonych jedna w drugiej,
to instrukcja break powoduje przerwanie tylko tej pętli, w której bezpośrednio
się znajduje - patrz slajd.

background image

continue

Instrukcja continue może występować wewnątrz bloku instrukcji
iteracyjnych. W odróżnieniu od instrukcji break, instrukcja continue nie
kończy działania pętli, ale przerywa tylko aktualny obieg pętli i zaczyna
następny, kontynuując pracę pętli - patrz slajd. Podobnie jak break, w
przypadku pętli zagnieżdżonych, instrukcja continue przerywa aktualny
obieg tej pętli, w której bezpośrednio się znajduje.

background image

Szablon programu

Używając poznane do tej pory instrukcje, można przedstawić pewien szablon
programu. Szablon możemy przedstawić przy pomocy następującego schematu:

Przykładową implementację można obejrzeć na slajdzie. Bardziej rozbudowany
przykład jest dostępny projekcie SzablonProjektu, który jest częścią
rozwiązania Kurs\Demo\Modul5\Modul5.sln, gdzie Kurs jest
katalogiem gdzie skopiowano pliki kursu.

Wyświetlenie menu, czyli

co program robi i jak go

do tego zmusić.

Oczekiwanie na polecenie

od użytkownika i jego

pobranie.

Przetworzenie polecenia

użytkownika i

wyświetlenie wyników.

background image

Uwaga:
W programie wykorzystywane są metody i właściwości klasy Console, które
do tej pory nie były omówione:

Console.BufferHeight - liczba dostępnych wierszy w okienku..

Console.WindowHeight - liczba widocznych wierszy w oknie.
Musi być ona mniejsza od właściwości
Console.LargestWindowHeight

, która oznacza maksymalną

ilość wierszy, wyznaczoną w oparciu o bieżącą wielkość fontu i
rozdzielczość ekranu.

Console.BufferWidth - liczba dostępnych kolumn w okienku.
Musi być ona mniejsza od właściwości
Console.LargestWindowWidth

, która oznacza maksymalną

ilość kolumn, wyznaczoną w oparciu o bieżącą wielkość fontu i
rozdzielczość ekranu.

Console.WindowWidth - liczba widocznych kolumn w oknie.

Console.BackgroundColor - kolor tła.

Console.ForegroundColor - kolor czcionki.

Console.Clear() - wyczyszczenie całego okna, zamazanie
kolorem tła.

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 są numerowane od góry do dołu okna.

Console.SetCursorPosition(kolumna, wiersz) -
ustawienie pozycji kursora, czyli gdzie będzie rozpoczynać się
operacja wypisania na ekranie

Console.ReadKey(true).KeyChar - wartość typu char
naciśniętego klawisza.

Warto wspomnieć jeszcze o jednej metodzie klasy Console:

Console.Beep(czestotlowosc, czas) - wydanie dźwięku o
danej częstotliwość podanej w Hz, przez określony czas podany w ms.

background image

Pytania sprawdzające

1. Jakie błędy popełniono w poniższym kodzie:


double x;
...
switch(x){
case 4 :
case 4 : instrukcjaA1;
break;
default: instrukacj2;
}

Odp.
W powyższym kozie popełniono następujące błędy:
- wartość (zmienna ) typu double nie może być wartością przełączającą w
instrukcji switch. Dopuszczalne typy to wszystkie typy całkowite, typ
string oraz typy wyliczeniowe,
- powtórzona wartość 4. Każda wartość obok case musi być unikalna, w
danej instrukcji switch
- po etykiecie default występuje instrukcja, nie ma natomiast instrukcji
skoku break albo goto.

2. Jaka jest różnica między instrukcjami break i continue wewnątrz pętli?


Odp.
Instrukcja break powoduje przerwanie (zakończenie) pętli, natomiast
instrukcja continue kończy pojedynczy obieg pętli i zaczyna następny,
kontynuując pracę pętli.

background image

Laboratorium

Ćwiczenie

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)

Całkę oznaczaną w przedziale <a; b> z funkcji nieujemnej całkowalnej na
przedziale <a, b> można interpretować jako pole obszaru ograniczonego
wykresem tej funkcji, osią OX oraz prostymi x = a i x = b.

W przypadku metody prostokątów, pole to przybliżamy, sumą pól odpowiednio
dobranych prostokątów. Sposób postępowania jest następujący: Przedział

background image

całkowania <a; b> dzielimy na n równych podprzedziałów: <x

0

; x

1

>,

<x

1

; x

2

>, ..., <x

n-2

; x

n-1

>, <x

n-1

; x

n

>

gdzie:

Dla każdego punktu x

i

, gdzie i = 1...n, wyznaczamy wartość funkcji w tym

punkcie. Będzie to długość jednego z boków prostokąta. Długość drugiego
boku jest równa szerokości podprzedziału. Sumę pól prostokątów, a więc
przybliżoną wartość całki, możemy zapisać wzorem:

W przypadku metody trapezów, zamiast sumy pól prostokątów używamy sumę
pól trapezów:

Pole trapezu jest równe iloczynowi wysokości i połowy sumy podstaw trapezu.

Dla podprzedziału <x

i-1

; x

i

> pole trapezu można zapisać:

Wzór na przybliżoną wartość całki, jako sumę pól trapezów, można więc
zapisać:

Dzięki powyższemu przekształceniu podczas obliczania wartości sumy, f(x

i

)

będzie obliczane tylko raz zamiast dwóch razy, gdybyśmy zastosowali wzór bez
przekształceń.

n

i

n

b

a

i

a

x

b

x

a

x

i

n

,...,

0

,

,

0

n

i

i

b

a

n

i

i

x

f

n

a

b

n

a

b

x

f

dx

x

f

1

1

)

(

)

(

)

(

)

(

2

1

2

1

podst

podst

h

P

trapezu

)]

(

)

(

[

2

1

1

i

i

trapezu

x

f

x

f

n

b

a

P

1

1

1

1

1

1

)

(

2

)

(

)

(

)]

(

)

(

[

2

2

)

(

)

(

)

(

n

i

i

n

i

i

i

b

a

n

i

i

i

x

f

b

f

a

f

n

a

b

x

f

x

f

n

a

b

n

a

b

x

f

x

f

dx

x

f

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

v. nazwa rozwiązania: Lab5

3.

Przed metodą Main zdefiniuj nowy typ wyliczeniowy o nazwie
MetodyCalkowania

, który ma dwa elementy Prostokatow=1 oraz

Trapezow=2

enum MetodyCalkowania { Prostokatow=1, Trapezow=2 }

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

a. Zadeklaruj następujące zmienne i nadaj im wartości początkowe:

i. dwie zmienne rzeczywiste a i b, reprezentujące początek i koniec

przedziału całkowania. a musi być mniejsze od b.

ii. Zmienną dodatnią n reprezentującą liczbę podziałów przedziału

całkowania.

iii. Zmienną metoda typu MetodyCalkowania.


double a = 0, b = 1;
uint n = 10;
MetodyCalkowania metoda =

MetodyCalkowania.Prostokatow;

b.

Ustaw główną pętlę programu:

char c;
do
{
...
}
while(!(c =='K' || c=='k'));

c. W głównej pętli programu:

i. Wyświetl menu programu. Menu powinno zawierać informacje na

temat: aktualnego przedziału całkowania, ilości podziałów i
wybranej metody całkowania oraz jak zmienić przedział
całkowania, metodę całkowania, liczbę podziałów, jak obliczyć
całkę dla podanych parametrów i jak zakończyć program.

Console.WriteLine("Przedział całkowania: <{0}; {1}>",

a, b);

background image

Console.WriteLine("Liczba podziałów: {0}", n);
Console.WriteLine("Metoda całkowania: {0}", metoda);
Console.WriteLine("-----");
Console.WriteLine("A - Zmiana przedziału");
Console.WriteLine("B - Zmiana liczby podziałów");
Console.WriteLine("C - Zmiana metody całkowania");
Console.WriteLine("D - Policz całkę");
Console.WriteLine("K - Koniec");

ii. Pobierz od użytkownika polecenie:


c = Console.ReadKey(true).KeyChar;

iii. Ustaw blok instrukcji switch w celu przetworzenia poleceń użytkownika:


switch(c)
{
...
}

iv. W bloku switch napisz następujący kod przetwarzający polecenia

użytkownika:

1.

Obsługa zmiany przedziału całkowania:
Pobierz wartość początku przedziału i wstaw do zmiennej a. Pobierz
wartość końca przedziału i wstaw do zmiennej b. Dopilnuj, aby
wartość b była większa od a:

case 'a':
case 'A':
do
{
if (a > b)
{
Console.Write("Początek musi być

¬mniejszy od końca: ");

}
Console.Write("Podaj początek przedziału: ");
a = Convert.ToDouble(Console.ReadLine());
Console.Write("Podaj koniec przedziału: ");
b = Convert.ToDouble(Console.ReadLine());
}
while (a > b);
break;

2. Obsługa zmiany liczby podziałów:

Pobierz wartość liczby podziałów i wstaw do zmiennej n. Jeżeli
użytkownik podał zero, zgłoś wyjątek.

case 'b':
case 'B':

Console.Write("Podaj liczbę podziałów: ");

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

if (n == 0)

throw new Exception("Liczba podziałów musi

¬ być większa od zera");

break;

background image

3. Obsługa zmiany metody całkowania:

Pobierz metodę całkowania od użytkonika:

case 'c':
case 'C':
int m = 1;
do
{
if (m != 1)
{
Console.Write("Naciśnij 1 lub 2: ");
}
Console.WriteLine("Podaj 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));
metoda = (MetodyCalkowania)m;
break;

4.

Obsługa liczenia całki

a. Dodaj nowy blok case:


case 'd':
case 'D':

b. Zadeklaruj trzy pomocnicze zmienne rzeczywiste: suma i nadaj

jej wartość zero, dx (szerokość podprzedziału) i nadaj jej wartość
(b-a)/n, x i nadaj jej wartość a.

double suma = 0;
double dx = (b - a) / n;
double x = a;

c. W zależności od wartości zmiennej metoda, oblicz wartość całki i

wstaw ją do zmiennej suma. Jeżeli wartość zmiennej metoda jest
równa MetodyCalkowania.Prostokatow skorzystaj ze
wzoru:



Jeżeli wartość zmiennej metoda jest równa
MetodyCalkowania.Trapezow skorzystaj ze wzoru:




Uwaga:
W celu optymalizacji obliczania wartości funkcji w punkcie,
możemy skorzystać z następującego przekształcenia:
f(x) = x

4

+x

3

+2 = x

3

(x+1)+2


switch (metoda)

n

i

i

b

a

x

f

n

a

b

dx

x

f

1

)

(

)

(

1

1

)

(

2

)

(

)

(

)

(

n

i

i

b

a

x

f

b

f

a

f

n

a

b

dx

x

f

background image

{
case MetodyCalkowania.Prostokatow:

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

{

x += dx;

suma += x * x * x * (x + 1) + 2;

}

suma *= dx;

break;

case MetodyCalkowania.Trapezow:

for (int i = 1; i < n; i++)

{

x += dx;

suma += x * x * x * (x + 1) + 2;

}

suma += (a * a * a * (a + 1) +

b * b * b * (b + 1) + 4) / 2;

suma *= dx;

break;

}

d.

Wypisz wartość całki (sumy) na ekranie i poczekaj na reakcję
użytkownika, aby mógł obejrzeć wynik.

Console.Write("Przybliżona wartość całki

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

¬ wynosi: {2}",a, b, suma);

Console.ReadKey(true);
break;

5. Skompiluj i uruchom program.


Wyszukiwarka

Podobne podstrony:
Lab 06 Instrukcje sterujace id Nieznany
1 Instrukcje iteracyjne (materi Nieznany (2)
Lab 06 Instrukcje sterujace id Nieznany
instrukcja bhp dla materialow w Nieznany
instrukcja bhp dla materialow w Nieznany (2)
instrukcja bhp dla materialow w Nieznany
zestaw 5 dynamika punktu materi Nieznany
instrukcja przeciwpozarowa gene Nieznany
Instruktazstanowiskowy id 21769 Nieznany
kolm instrumenty 3 id 239529 Nieznany
Bezpieczenstwo zakres materialu Nieznany
cw3 i 4 instrukcja id 123316 Nieznany
CA 6 instrukcja uzytkownika id Nieznany
Edukacja integracyjna materialy Nieznany

więcej podobnych podstron