Laboratorium 2. Instrukcje warunkowe
Przed zajęciami laboratoryjnymi zapoznaj się z następującymi pozycjami literatury:
1. Wykład z przedmiotu „Podstawy programowania”
2. J. Grębosz „Symfonia C++” tom 1. ,Oficyna Kallimach, Kraków, 1999
Rozdziały: 1, 2.1, 2.2, 2.6, 2.7, 2.8, 3.1 - 3.4, 4.1, 4.2, 4.5, 4.6, 4.10, 4.11
Przygotowując się do laboratorium przeanalizuj podane poniżej przykłady, odpowiedz na pytania, rozwiąż testy i napisz odpowiednie programy. Po zajęciach zrób zadania podane w ostatnim punkcie tego
opracowania.
Przykłady i pytania
1. Instrukcje if (…) oraz if (…) else. Wyrażenia logiczne
Przykład L2_F0_P1 Przeanalizuj program i odpowiedz na pytania
// L2_F0_P1.cpp Instrukcje warunkowe if-else, if
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
float a, b;
bool war;
cout << setiosflags(ios::fixed); // ustawienie formatu wyjściowego liczb zmiennoprzecinkowych
// zamiast fixed może być np. scientific
cout.precision(5); // 5 cyfr po przecinku
cout << "Podaj pierwsza liczbe: "; cin >> a;
cout << "Podaj druga liczbe: "; cin >> b;
//---Instrukcja (A)
if (a != b)
cout << a << " jest rozne od " << b << endl;
else
cout << a << " jest rowne " << b << endl;
//--- Instrukcja (B)
if ( !(b+2)) cout << b << " jest rowne " << -2 << endl;
//--- Instrukcja (C)
if ( !( a && b) ) cout << "Co najmniej jedna z liczb jest rowna " << 0 << endl;
//--- Instrukcja (D)
war = ( a > -10 and a < 10 ) and ( b > -10 and b < 10 );
if ( not war ) cout << "Co najmniej jedna z liczb jest spoza przedzialu [-10, 10]" << endl;
//--- Instrukcja (E)
if ( (a <-1 || a >1) || a == 0)
cout << "Dla a = " << a << " funkcja y jest nieokreslona" << endl;
else
cout << "Dla a = " << a << " wartosc funkcji y(a) = " << asin(a) + 1/a + sin(a) << endl;
//----------------------------
system("PAUSE");
return 0;
}
S t r o n a | 1 WETI Politechnika Gdańska, POP v.1.4.1
Sprawdź czy dla podanych poniżej danych program działa z zgodnie z twoimi przewidywaniami:
1) a = 0, b = -2 2) a = 0.5, b = -11.1
a) Co wypiszą na ekranie instrukcje (B), (C) oraz (D) dla a = 1 i b = 1 ?
b) Co wypisze instrukcja (E), gdy na wejście podamy a = 0 albo a = 3.14 i pominiemy dwie pierwsze linie tej instrukcji? Czy instrukcje warunkowe są konieczne podczas stosowania niektórych funkcji
z biblioteki cmath ? Jeżeli tak, to do czego?
c) Jak zmienić warunki w instrukcjach (A), (B) i (C), aby otrzymać warunki równoważne bez użycia operatorów negacji ( ! , not) ?
d) Jak zmienić warunek w instrukcji (D), aby otrzymać warunek równoważny bez użycia operatorów
koniunkcji ( && , and) ?
e) Jak zmienić warunek w instrukcji (D), aby otrzymać warunek równoważny bez użycia operatorów
alternatywy ( || , or) ?
Odpowiedzi
a) Nic.
b) Błędne wyniki typu 1.#INF , wskazujące na przekroczeniu w dostępnych zakresów liczb. Tak. Przed
użyciem funkcji trzeba mieć pewność, że podane na wejściu funkcji argumenty są poprawne (należą
do dopuszczalnego zakresu i mają odpowiedni typ).
c) Instrukcja (A): if ( a < b || a > b ) ...
Instrukcja (B): if ( ( b + 2 ) == 0 ) ...
Instrukcja (C): if ( a == 0 || b == 0 ) ...
d) Instrukcja (D): war = (( a <= -10 or a >= 10) or ( b <= -10 or b >= 10)); if (war)...
e) Instrukcja (E): if ( !(a >= -1 && a <= 1 && a != 0 ) )...
2. Zagnieżdżone instrukcje if (…) oraz if (…) else
Przykład L2_F0_P2 Przeanalizuj program i odpowiedz na pytania
// L2_F0_P2.cpp Zagniezdzone instrukcje warunkowe if-else, if
#include <iostream>
using namespace std;
int main()
{
int x, y, z;
//-------------------------------------------------------------------------------------
cout << "Podaj liczbe calkowita x: "; cin >> x; // Linia 1
cout << "Podaj liczbe calkowita y: "; cin >> y; // Linia 2
cout << "Podaj liczbe calkowita z: "; cin >> z; // Linia 3
if ( x > y) // Linia 4
if (y <= z); // Linia 5
else cout << "Wniosek : " << " # " <<endl; // Linia 6
//---------------------------------------------------------------------------------------
system("PAUSE");
return 0;
}
S t r o n a | 2 WETI Politechnika Gdańska, POP v.1.4.1
a) Do której instrukcji if odnosi się else ? Co oznacza średnik w Linii 5 ?
b) Które z poniższych zdań można wstawić w miejsce znaku #, aby wypisany wniosek był prawdziwy?
1) x jest mniejsze lub równe y
2) y jest większe niż z
3) z to liczba najmniejsza spośród 3 liczb x, y, z
c) Zapisz instrukcje ( Linie 4-6 ) używając dwóch zagnieżdżonych instrukcji if (bez słowa else).
d) Zapisz instrukcje ( Linie 4-6 ) za pomocą jednej instrukcji if ( bez słowa else).
e) Zmień Linię 5, aby zdanie: Nieprawda, że x jest większe od y, zastępujące znak # było prawdziwe?
Odpowiedzi
a) Do instrukcji w Linii 5. Średnik oznacza instrukcję pustą, która nic nie robi.
b) Zdanie 2) albo 3).
c) if ( x > y ) if ( y > z ) cout << "Wniosek : " << " # " << endl; d) if ( x > y and y > z ) cout << "Wniosek : " << " # " << endl;
e) Ujmij Linię 5 w nawiasy klamrowe { if (y <= z); }, wówczas else odnosi się do if w Linii 4.
3. Instrukcja switch
Przykład L2_F0_P3 Przeanalizuj program i odpowiedz na pytania
// L2_F0_P3.cpp Instrukcja warunkowa switch() i instrukcja break
/* Program określa stan gleby na podstawie pomiaru wilgotności [%] */
/* Kryteria: 0.. 9 % - pustynia */
/* 10.. 19 % - gleba bardzo sucha */
/* 20.. 39 % - gleba sucha */
/* 40.. 69 % - gleba właściwa */
/* 70.. 89 % - gleba mokra */
/* 90.. 99 % - bagno */
#include <iostream>
using namespace std;
int main ()
{
int wg;
cout << "Podaj wilgotnosc gleby (0 <= wg <= 99): ";
cin >> wg;
if (wg >= 0)wg = wg/10;
cout << "Stan gruntu : ";
switch (wg){
case 0 : { cout << "pustynia " << endl; break;}
case 1 : { cout << "gleba bardzo sucha " << endl; break;}
case 2 :
case 3 : { cout << "gleba sucha " << endl; break;}
case 4 :
case 5 :
case 6 : { cout << "gleba wlasciwa " << endl; break;}
case 7 :
case 8 : { cout << "gleba mokra " << endl; break;}
case 9 : { cout << "bagno " << endl; break;}
default: { cout << "niepoprawne dane " << endl; break;}
}
system("PAUSE");
return 0;
}
S t r o n a | 3 WETI Politechnika Gdańska, POP v.1.4.1
a) Co wypisze na ekranie program dla wg = 77 ?, a gdy usuniemy linię case 7: ?
b) A gdy dodatkowo usuniemy linię z etykietą default ?
c) Co wypisze na ekranie program dla wg = 7, gdy usuniemy pierwszą instrukcję break ?
d) Podaj przykłady typów, które są dopuszczalne oraz takich, które są niedopuszczalne dla wyrażenie w instrukcji switch( wyrażenie).
e) Napisz równoważny program bez użycia instrukcji switch.
Odpowiedzi
a) Stan gruntu: gleba mokra ( z linią case 7:)
Stan gruntu: niepoprawne dane ( bez case 7:)
b) Stan gruntu:
c) Stan gruntu: pustynia
gleba bardzo sucha
d) Dopuszczalne typy całkowitoliczbowe ( np. int, long int, char, bool), niedopuszczalne typy zmiennoprzecinkowe (np. float, double)
e) Możesz zastosować konstrukcję else-if, na przykład:
int main ()
{
int wg;
cout << "Podaj wilgotnosc gleby (0 <= wg <= 99): ";
cin >> wg;
cout << "Stan gruntu: " ;
if (wg < 0) cout << "niepoprawne dane " << endl;
else if (wg < 10) cout << "pustynia " << endl;
else if (wg < 20) cout << "gleba bardzo sucha " << endl;
else if (wg < 40) cout << "gleba sucha " << endl;
else if (wg < 70) cout << "gleba wlasciwa " << endl;
else if (wg < 90) cout << "gleba mokra " << endl;
else if (wg <100) cout << "bagno " << endl;
else cout << "niepoprawne dane " << endl;
system("PAUSE");
return 0;
}
Testy
1. Które instrukcje, bez względu na wartość k oraz a, nigdy nie zostaną wykonane ?
a) if ( k < a and k > a ) instrukcja_1;
else instrukcja_2;
b) if ( k < a ) {
instrukcja_1;
if ( k > b && b > a ) instrukcja_2;
else instrukcja_3;
}
else instrukcja_3;
c) if ( k < a or k > a ) {
instrukcja_1;
if ( a != k ) instrukcja_2;
else instrukcja_3;
}
else if ( k == a ) instrukcja_4;
S t r o n a | 4 WETI Politechnika Gdańska, POP v.1.4.1
2. Przy jakich wartościach k wykona się wykona sie jedna z instrukcji oznaczonych jako instrukcja_1 ?
int main()
{
int k;
cin >> k;
switch ( k + 2 ) {
case 1:
case 2: if ( k == -1 ) instrukcja2;
else instrukcja_1;
break;
case 3: if (k > 2) instrukcja_1;
else instrukcja_3;
break;
default: instrukcja_1;
break;
system("PAUSE");
return 0;
}
3. Wskaż fragmenty, które kompilator programu uzna za błędne:
a) if(k)
if(k)
if(k);
else k = k - 1;
b) if(k);
else k = k - 1;
else k = k - 1;
c) if(k);
else if(!k) k = k - 1;
d) if(k) k = k - 1;
else;
e) if(1)
else k = k - 1;
4. Zapisz instrukcje if-else w postaci wyrażenia warunkowego:
(warunek) ? wartosc_1 : wartosc_2
a) float liczba;
if( liczba < 0 ) liczba = - liczba;
else liczba = liczba;
b) float x, y;
if( x > 1 ) y = x-1;
else y = x*x -1;
Odpowiedzi
Test 1: a) instrukcja_1, b) instrukcja_2, c) instrukcja_3
Test 2: k ≠ -1 i k ≠ 1
Test 3: b) oraz e)
Test 4: a) liczba = (liczba < 0) ? ( –liczba ) : ( liczba );
b) y = ( x > 1 ) ? ( x – 1 ) : ( x * x – 1 );
S t r o n a | 5 WETI Politechnika Gdańska, POP v.1.4.1
Zadania przygotowujące do laboratorium
Zapoznaj się z treścią zadania, przemyśl rozwiązanie a następnie napisz, uruchom i przetestuj programy.
Zadanie L2_F0_Z1
Napisz program, który dla podanej liczby całkowitej wypisuje na ekranie komunikat:
• „Fizz”, jeżeli liczba jest podzielna przez 3, ale nie przez 5;
• „Buzz”, jeżeli liczba jest podzielna przez 5, ale nie przez 3;
• „FizzBuzz”, jeżeli liczba jest podzielna przez 15;
• Wartość podanej liczby, jeżeli nie jest ona podzielna ani przez 3, ani przez 5.
Zastosuj konstukcję else-if. Zastanów się nad kolejnością sprawdzania warunków.
// L2_F0_Z1.cpp Podzielnosc przez 3, 5 i 15
#include <iostream>
using namespace std;
int main()
{
int i;
cout << "Podaj liczbe calkowita: "; cin >> i;
cout << "Wynik analizy: " << endl;
if( i % 15 == 0 ) cout << "FizzBuzz" << endl; // Ten warunek musi być pierwszy. Dlaczego?
else if ( i % 3 == 0 ) cout << "Fizz" << endl; // i%3 = reszta z dzielenia zmiennej i przez 3
else if ( i % 5 == 0 ) cout << "Buzz" << endl;
else cout << i << endl;
system("PAUSE");
return 0;
}
Zadanie L2_F0_Z2
Napisz program, który wczytuje 3 różne liczby rzeczywiste: a, b oraz c i sprawdza, czy c zawiera się w przedziale ( a, b), gdy a < b, albo w przedziale ( b, a), gdy a > b.
a) Uzupełnij poniższy szkielet L2_F0_S2, aby program działał poprawnie.
b) Napisz program krócej, zachowując ten sam układ instrukcji if-else oraz nie stosując w warunkach operatorów logicznych: not, or, and ( ! , || , && ).
// L2_F0_S2.cpp
#include <iostream>
using namespace std;
int main()
{
double a, b, c;
cout << "Podaj 3 rozne liczby rzeczywiste: a b c : "; cin >> a >> b >> c;
cout << endl << "Czy liczba c zawiera sie w przedziale (a,b) lub (b,a)\? ";
//----------------------------------------------------------- UZUPELNIJ
if( a < b )
if ( ) cout << "TAK " << endl;
else cout << "NIE " << endl;
else
if ( ) cout << << endl;
else cout << << endl;
//------------------------------------------------------------
system ("PAUSE");
return 0;
}
S t r o n a | 6 WETI Politechnika Gdańska, POP v.1.4.1
// L2_F0_Z2a.cpp
#include <iostream>
using namespace std;
int main()
{ double a, b, c;
cout << "Podaj 3 rozne liczby rzeczywiste: a b c "; cin >> a >> b >> c;
cout << endl << "Czy liczba c zawiera sie w przedziale (a,b) lub (b,a)\? ";
//---------------------------------------------------------------
if( a < b )
if ( c > a && c < b) cout << "TAK " << endl;
else cout << "NIE " << endl;
else
if ( c > b && c < a) cout << "TAK " << endl;
else cout << "NIE " << endl;
//---------------------------------------------------------------
system ("PAUSE");
return 0;
}
Rozwiązanie b)
// L2_F0_Z2b.cpp
#include <iostream>
using namespace std;
int main()
{ double a, b, c;
cout << "Podaj 3 rozne liczby rzeczywiste: a b c "; cin >> a >> b >> c;
cout << endl << "Czy liczba c zawiera sie w przedziale (a,b) lub (b,a)\? ";
//---------------------------------------------------------------
if( c > a )
if ( c < b) cout << "TAK " << endl;
else cout << "NIE " << endl;
else
if ( c > b) cout << "TAK " << endl;
else cout << "NIE " << endl;
//---------------------------------------------------------------
system ("PAUSE");
return 0;
}
Zadanie L2_F0_Z3
Program wczytuje współczynniki a, b, c równania kwadratowego ax 2 + bx + c = 0. Jeżeli a ≠ 0, to oblicza ile rozwiązań rzeczywistych ma równanie kwadratowe, w przeciwnym przypadku wpisuje komunikat: „To nie
jest równanie kwadratowe”.
// L2_F0_Z3.cpp Sprawdzenie ile rozwiazan ma rownanie kwadratowe
#include <iostream>
using namespace std;
int main()
{
double a, b, c;
cout << "Podaj 3 liczby rzeczywiste: a b c : "; cin >> a >> b >> c;
if( a != 0 ) {
cout << endl << "Rownanie kwadratowe a*x*x + b*x + c = 0";
if ( b*b - 4*a*c > 0 ) cout << " ma 2 rozwiazania rzeczywiste" << endl;
else if ( b*b - 4*a*c < 0 ) cout << " nie ma rozwiazan rzeczywistych" << endl;
else cout << " ma 1 rozwiazanie rzeczywiste" << endl;
}
else
cout << "To nie jest rownanie kwadratowe" << endl;
system ("PAUSE");
return 0;
}
S t r o n a | 7 WETI Politechnika Gdańska, POP v.1.4.1
Program wczytuje trzy liczby rzeczywiste a, b, c i sprawdza czy mogą być bokami trójkąta. Jeżeli tak, to wypisuje na ekranie słowo TAK, jeżeli nie – słowo NIE. Sprawdź działanie swojego programu dla różnych danych wejściowych. W szczególności uwzględnij dane, dla których długość jednego z boków „znacząco”
różni się od pozostałych, np. a = b = 1e10, c = 1e-10. Czy zawsze otrzymujemy poprawny wynik? Jeżeli nie, to zastanów się dlaczego.
Wskazówka: suma długości dowolnych dwóch boków trójkąta jest większa niż długość trzeciego boku.
// L2_F0_Z4.cpp Czy a b c moga tworzyc trojkat?
#include <iostream>
using namespace std;
int main()
{
double a, b, c;
cout << "Podaj 3 liczby rzeczywiste: a b c : "; cin >> a >> b >> c;
cout << endl << "Czy liczby moga byc bokami trojkata\? ";
if ( b+c > a && a+c > b && a+b > c ) cout << "TAK " << endl;
else cout << "NIE " << endl;
system ("PAUSE");
return 0;
}
Zadania do samodzielnego rozwiązania po laboratorium
L2_F3_Z1
Napisz program, który wczytuje trzy różne liczby rzeczywiste a, b, c i sprawdza, która z nich jest najmniejsza, a która największa. Dwie liczby będziemy uważali za równe, gdy ich różnica jest większa niż 1e-9. Napisz program tak aby w najgorszym przypadku wykonał trzy porównania. Wynik przedstaw w postaci
wykładniczej dokładnością do 4 cyfr po przecinku.
Przykład:
Dla liczb (2.53e-1, -35.7, -1) program wypisze na ekranie:
Liczba najwieksza = 2.530e-1
Liczba najmniejsza = -3.570e1
L2_F3_Z2
Napisz program, który wczytuje dwie współrzędne punktu P( x, y) i sprawdza czy punkt należy do koła o promieniu r=2 i środku (0, 0) i jednocześnie zawiera się w I albo II ćwiartce układu współrzędnych (przyjmij, że nieujemne części osi OX oraz OY należą do I ćwiartki, a ujemna część osi OX do II).
S t r o n a | 8 WETI Politechnika Gdańska, POP v.1.4.1
Napisz program, który wyznacza rozwiązania rzeczywiste równania
2
ax + bx + c = 0
na podstawie wczytanych 3 liczb rzeczywistych a, b, c.
Jeżeli a = 0, to program powinien rozwiązać równanie liniowe a w przeciwnym razie, równanie kwadratowe.
Wyniki wyprowadzić w formacie wykładniczym z dokładnością 5 cyfr po przecinku. W szczególnych
przypadkach program powinien wypisywać komunikaty informujące, że :
1. Równanie nie ma rozwiązań w zbiorze liczb rzeczywistych
2. Równanie ma nieskończoną liczbę rozwiązań
L2_F3_Z4
Dany jest rosnący ciąg liczb rzeczywistych: p 1, p 2,..., p 7 ( p 1 < p 2 < ... < p 7). Elementy ciągu, nazwane dalej progami, definiują 8 przedziałów:
( −∞, p 1 ) [ p 1, p 2 ) [ p 2, p 3 ) [ p 3, p 4 ) [ p 4, p 5 ) [ p 5, p 6 ) [ p 6, p 7 ) [ p 7, +∞ ) Napisz program kwalifikujący wczytaną liczbę x do jednego z ośmiu przedziałów i wykonujący co najwyżej trzy proste porównania typu if ( x > p i ). Przyjmij, że progi są stałymi liczbowymi (ich wartości ustal samodzielnie). Program powinien wypisywać na standardowym wyjściu przedział (w postaci odpowiednich
nierówności), do którego należy x.
Wskazówka: zauważ, że jeżeli x należy do przedziału ( −∞, p 4 ), to nie należy do żadnego z czterech przedziałów o końcach w [ p 4, +∞ ). Po rozstrzygnięciu przynależności do ( −∞, p 4 ), tą samą obserwację i test względem „środkowego” przedziału możesz teraz zastosować do dwóch części przedziału ( −∞, p 4 ), itd.
Uwaga: poprzednie wersje programu, podane w przykładzie L2_F0_P3 nie były optymalne pod względem ilości wykonywanych porównań (w najgorszym przypadku wymagały siedmiu porównań, aby określić
przynależność do właściwego przedziału). Ich zaletą jest jednak duża czytelność i powinny być stosowane, gdy szybkość działania programu nie jest kryterium nadrzędnym.
S t r o n a | 9 WETI Politechnika Gdańska, POP v.1.4.1