Wykład 2

Transkrypt

Wykład 2
Podstawy
programowania
Doskonalimy umiejętności
Idzie lato, czas na siłownię.
Współczynnik BMI
(nieaktualny ;) )
 𝐵𝑀𝐼
<
=
𝑚𝑎𝑠𝑎 [𝑘𝑔]
𝑤𝑧𝑟𝑜𝑠𝑡 2 [𝑚]
16,0 – wygłodzenie
 16,0–16,99 – wychudzenie
 17,0–18,49 – niedowagę
 18,5–24,99 – wartość prawidłową
 25,0–29,99 – nadwagę
 30,0–34,99 – I stopień otyłości
 35,0–39,99 – II stopień otyłości
 ≥ 40,0 – III stopień otyłości
No to piszemy program
Gdyby babcia miała wąsy…
 Instrukcja
if – sposób na sprawdzanie warunków
 Konstrukcja:
if(warunek)
{ instrukcje gdy warunek spełniony}
else
{instrukcje gdy warunek NIE spełniony}
Gdyby babcia miała wąsy…
 Część
z else jest opcjonalna:
if(warunek)
{ instrukcje gdy warunek spełniony}
Podobnie jak nawiasy klamrowe {}. Bez nich
wewnątrz if-a wykonana zostanie jedna instrukcja!
Gdyby babcia miała wąsy…
…
if(liczba > 0)
cout << „Liczba dodatnia”;
cout << „Liczba większa od zera”;
Wynik
Część „Liczba większa od zera” wykona się zawsze!
Niezależnie od wartości zmiennej liczba.
Jak to naprawić?
Gdyby babcia miała wąsy…
…
if(liczba > 0)
{
cout << „Liczba dodatnia”;
cout << „Liczba większa od zera”;
}
Poprawna wersja.
Gdyby babcia miała wąsy…
 Instrukcje
if można zagnieżdżać:
if(liczba > 5)
if(liczba < 10)
cout << „Liczba z przedziału (5;10);
Gdyby babcia miała wąsy…
 Ale
każdy szanujący się programista zrobi to w ten
sposób:
if (liczba > 5 && liczba < 10)
cout << „Liczba z przedziału (5;10);

Dzięki temu maleje ryzyko błędu.
Gdyby babcia miała wąsy…
 To
nie zadziała tak, jak nam się wydaje:
if(liczba > 5)
if(liczba < 10)
cout << „Liczba z przedziału (5;10);
else cout << „Liczba spoza przedziału”;
Gdyby babcia miała wąsy…
 To
nie zadziała tak, jak nam się wydaje:
if(liczba > 5)
if(liczba < 10)
cout << „Liczba z przedziału (5;10);
else cout << „Liczba spoza przedziału”;
else tyczy się wewnętrznej instrukcji.
Gdyby babcia miała wąsy…
Jaka jest różnica pomiędzy tymi dwoma podejściami?
1)
if (liczba > 0)
cout << „Liczba > 0”;
if (liczba > 1)
cout << „Liczba > 1”;

2)
if (liczba > 0)
cout << „Liczba > 0”;
else if (liczba > 1)
cout << „Liczba > 1”;
Gdyby babcia miała wąsy…
Jaka jest różnica pomiędzy tymi dwoma podejściami?
1)
Dla liczba=5:
if (liczba > 0)
cout << „Liczba > 0”;
1): Wyświetli oba
if (liczba > 1)
komunikaty
cout << „Liczba > 1”;

2)
if (liczba > 0)
cout << „Liczba > 0”;
else if (liczba > 1)
cout << „Liczba > 1”;
2): Wyświetli tylko
pierwszy komunikat.
I będzie szybsze.
Instrukcja if – sposób na sprawdzanie warunków
 Konstrukcja:
if(warunek)
{ instrukcje gdy warunek spełniony}
else
{instrukcje gdy warunek NIE spełniony}

Gdyby babcia miała wąsy…
Operator warunkowy
Operator warunkowy jest postaci:
warunek ? wartość1 : wartość2;
Co należy rozmieć jako: jeśli warunek jest prawdziwy to
podstaw za wartość wyrażenia wartość1, w przeciwnym
wypadku podstaw za wartość wyrażenia wartość2.
Można go traktować jako skróconą wersję instrukcji
warunkowej if. Przykład:
O czytaniu z klawiatury
No to piszemy program lepiej
Ale i tak do kitu
Ma być mniej więcej tak
Pętla while
 Pętla
while wykonuje daną instrukcję lub blok
instrukcji tak długo jak długo warunek jest spełniony
(ma wartość true). Ogólna postać pętli while jest
następująca:
while (warunek)
instrukcja;
 Pętla while bada prawdziwość warunku jeszcze
przed wykonaniem dalszego kodu (na samym jej
początku), dlatego też, jeśli warunek ma wartość
false to instrukcje zawarte w tej pętli nigdy nie
zostaną wykonane.
Pętla while - przykład
Pętla do while
 Pętla
do while jest odmianą pętli while, a jej ogólna
postać jest następująca:
do
instrukcja;
while(warunek);
Co należy rozumieć jako: Wykonuj instrukcję dopóki
warunek jest prawdziwy. Jako, iż warunek pętli
sprawdzany jest na końcu, wykona się ona zawsze
przynajmniej raz!
Fragment kodu
Fragment kodu
Wykonuj dopóki warunek jest prawdziwy.
A nie przerwij, kiedy warunek!
Stąd: dopóki wzrost > 2.4 m LUB wzrost < 0
Pętla for
 Ogólna
postać pętli for jest następująca:
for (wyrażenie początkowe; wyrażenie warunkowe; wyrażenie modyfikujące)
instrukcja_do_wykonania;
W miejsce wyrażenia początkowego wstawiane jest
wyrażenie stosowane do zainicjalizowania zmiennej
służącej jako licznik wykonań pętli. Wyrażenie
warunkowe określa jaki warunek musi być spełniony by
przejść do kolejnego przebiegu pętli. Wyrażenie
modyfikujące natomiast używane jest do modyfikacji
wartości zmiennej będącej licznikiem pętli.
Zainicjowanie licznika warunkuje jak daleko jest on
widoczny!
Instrukcja break
 Instrukcja
break powoduje przerwanie
wykonywania pętli i opuszczenie jej bloku.
Instrukcja continue
 Instrukcja
continue powoduje przejście do kolejnej
iteracji danej pętli (chyba, że była to jej ostatnia
iteracja).
Doskonalimy nasz żart
Zgadnij moją liczbę
 Program
losuje liczbę z przedziału od 1 do 100.
 Zadaniem
użytkownika jest odgadnięcie
wylosowanej liczby — wpisuje swoją propozycję a
program stwierdza, czy proponowana liczba jest
równa, mniejsza lub większa od wylosowanej.
Zgadnij moją liczbę
Zgadnij moją liczbę
 Będzie
1.
2.
3.
4.
nam potrzeba:
Wylosować liczbę.
Odczytać liczbę od użytkownika
Porównać liczby.
I wykonywać to, aż zgadnie 
Piszemy program
Pamiętaj o
zerowaniu
zmiennych.
Zmienne
nazywamy tak,
aby wiedzieć
jakie wartości
przechowują.
Piszemy program
Pamiętasz \”Hansa Klosa\” ?
Losujemy liczbę
Losujemy liczbę
Komputery nie są dobre w
losowaniu i wymyślaniu
losowych numerów.
Stąd liczby losowe i tak
muszą zostać „wyliczane”.
Ale tak, że zwykły człowiek
nie jest w stanie przewidzieć
kolejnej liczby.
Przed erą komputerów za
liczby losowe brano
końcówki numerów
telefonów w książce
telefonicznej.
Piszemy program
Inicjalizacja
Losowanie
Losujemy liczby
 srand(666);

To inicjalizacja generatora liczb
pseudolosowych (tzw. zalążek).

Dla testowania programów – ustawiamy na
stałą wartość (np. 666). Dzięki temu co
uruchomienie programu otrzymamy ten sam
zestaw liczb pseudolosowych.

Ale w programach produkcyjnych zwykle
chcemy mieć pełną losowość.
Losujemy liczby
 srand(
 int
(unsigned) time( NULL ));
wylosowana = rand() % 100 + 1
Ograniczamy do 100 liczb
(reszta z dzielenia przez 100 to
liczby 0, 1, 2,…,99)
Dodajemy 1, aby
przesunąć przedział
losowania.
Losujemy liczby
 srand(
(unsigned) time( NULL ));

Takie coś za każdym razem ustali nam zalążek
na aktualną wartość zegara systemowego
(ściślej: liczbę sekund, jaka upłynęła od
1 stycznia 1970 r.)

Ale dalej nie działa, jak chcemy, bo rand()
losuje liczby z przedziału 0…32767 (co
najmniej)

Jak to ograniczyć?
Ulepszamy program
Nowe
nagłówki
Lepsze losowanie
Lepsze losowanie
Poznaj swój kompilator
CodeBlocks martwi się, że mamy zmienne, których nie
wykorzystujemy.
Te informacje tutaj pozawalają na zmniejszenie liczby
wyrwanych włosów przy naprawianiu programu!
Poznaj swój kompilator
Dodajemy pętlę
Dopóki liczba
jest
nieodgadnięta
…
Dodajemy pętlę
Wczytuj nową
liczbę od
użytkownika
Dodajemy pętlę
Porównuj
wczytywaną z
wylosowaną
No to kolejne wyzwanie
 Napisać
program symulujący działanie
kalkulatora.
 Możliwe operacje (dwuargumentowe):




Dodawanie
Dzielenie (ze sprawdzeniem, czy nie
dzielimy przez 0)
Mnożenie
Odejmowanie
No to kolejne wyzwanie
No to kolejne wyzwanie
1.
2.
Zapytaj użytkownika o pierwszą liczbę i ją
zapamiętaj.
Zapytaj użytkownika o działanie
1.
3.
Zapytaj użytkownika o drugą liczbę i ją
zapamiętaj.
1.
4.
5.
Jeśli działanie będzie niedozwolone, wyświetl
błąd i powtórz.
Jeśli ta liczba to 0 ORAZ działanie to dzielenie,
wyświetl błąd i zakończ program.
Wyświetl wynik.
Zapytaj użytkownika, czy chce liczyć raz
jeszcze.
Które zmienne są lepsze?
 int
a
 int b
 int c
 double
pierwsza
 double druga
 double wynik
 float
pierwsza
 float druga
 float wynik
Które zmienne są lepsze?
 int
a
 int b
 int c
 float
pierwsza
 float druga
 float wynik
 double
pierwsza
 double druga
 double wynik
1. Nazwy zmiennych „mówią”,
czym one są (kod
samokomentujący się)
2. Skoro dzielimy, to musimy użyć
typu zmiennoprzecinkowego.
Pierwsza przymiarka
Pierwsza przymiarka
Apostrofy, bo to znak!
Pierwsza przymiarka
Sposób na zatrzymanie
programu.
Pierwsza przymiarka
Ale ten kod jest
brzydki!
Instrukcja wyboru switch
Instrukcja switch pozwala w wygodny sposób sprawdzić ciąg
warunków i wykonać różny kod w zależności od tego czy są
one fałszywe czy prawdziwe. Jej postać jest następująca:
Druga przymiarka
Jaka zmienna
„rozdziela” program
break
jest
cholernie
istotny!
Gdyby nie było breaków
Wykonały się wszystkie instrukcje 
Coś i tak popsuliśmy
Brakuje komunikatu o błędzie
Trzecie i ostatnie podejście
default zwykle umieszczamy na końcu.
A jak wykonywać obliczenia
wiele razy?
do {
…
}
while(wybor == ’p’ || wybor == ’P’)
Zabezpieczenie przed małymi/wielkimi
literami.
Kto chce być milionerem?
Gramy w Lotto
1.
2.
3.
4.
Przywitajmy użytkownika.
Spytajmy ile liczb obstawia
Wylosuj tyle liczb ile trzeba (i z
odpowiedniego zakresu).
Zapytaj użytkownika, czy chce losować
dalej.
Ogólny sposób losowania liczb
rand() % DŁUGOŚĆ_PRZEDZIAŁU
+ POCZĄTEK
 DŁUGOŚĆ_PRZEDZIAŁU
= ile liczb jest
możliwych do wylosowania
 POCZĄTEK
 Mały
= gdzie zaczynamy
haczyk – co jest, jeśli przedział
przechodzi przez 0?
const – oznacza stałą. To taka zmienne, tylko
jej nie da się zmienić w programie.
Nie zapomnijmy o inicjowaniu generatora
liczb pseudolosowych!
Jak być milionerem na serio 
W pętli for możemy
korzystać ze
zmiennych. Dzięki
temu nie musimy
znać liczby
przebiegów przy
projektowaniu
programu
Czemu użyłem
stałych?
Jak być milionerem na serio 
W pętli for możemy
korzystać ze
zmiennych. Dzięki
temu nie musimy
znać liczby
przebiegów przy
projektowaniu
programu
Czemu użyłem
stałych?
Żeby program
móc łatwo
przerobić np. na
Multi Lotka.
Jak być milionerem na serio 
Jak być milionerem na serio 
Jak być milionerem na serio 
Na co warto iść do kina?
 Lubię
kino. Ale nie wiem, na co iść do kina.
 Jest
sporo serwisów z ocenami, ale który tak
naprawdę daje radę?
 Poza
tym – zmieniają się często, więc nie wiem
ile ich jest.
 Jak
tutaj sobie poradzić i policzyć średnią? A
przy okazji mieć informację o maksymalnej i
minimalnej ocenie?
Liczymy średnią ocen
Zaczynamy standardowo.
Witamy użytkownika i deklarujemy
zmienne.
Liczymy średnią ocen
W pętli dopóki nie 0:
pytamy, czytamy, dodajemy i liczymy 
Liczymy średnią ocen
Na końcu liczymy średnią i ją
wyświetlamy.
Fajne?
 Tyle,
że nie działa:
Fajne?
 Tyle,
że nie działa:
1. Liczenie średniej do chrzanu.
2. Numer oceny do kitu.
Liczymy średnią ocen
Do nieokreślonej wartości dodajemy coś.
Więc wynik jest też nieokreślony!
Liczymy średnią ocen
Tak lepiej.
Liczymy średnią ocen
Tak lepiej. Ale dalej źle.
Liczymy średnią ocen
A tak najlepiej:
Korzystamy z operatora ++
I dzielimy przez (ileOcen-1) aby nie
liczyć ostatniego zera.
Liczymy średnią ocen
nan = Not A Number.
A po polsku – symbol nieoznaczony.
Pozostał tylko jeden problem, ale jego
już możecie rozwiązać sami.
A może przy okazji policzymy
min oraz max?
 Aby
to zrobić najpierw trzeba by
pamiętać, jakie są maksymalne i
minimalne wartości możliwe do zapisania
w odpowiednich typach danych.
 Pamiętacie?
A może przy okazji policzymy
min oraz max?
 Aby
to zrobić najpierw trzeba by
pamiętać, jakie są maksymalne i
minimalne wartości możliwe do zapisania
w odpowiednich typach danych.
 Pamiętacie?
 Ja
też nie. Bo i po co?
A może przy okazji policzymy
min oraz max?
Dodajemy nagłówek:
#include <limits>
A następnie korzystamy z konstrukcji:
numeric_limits < double >::max();
numeric_limits < double >::min();
A może przy okazji policzymy
min oraz max?
Dodajemy nagłówek:
#include <limits>
A następnie korzystamy z konstrukcji:
numeric_limits < double >::max();
numeric_limits < double >::min();
Zamiast double może być float, int, cokolwiek.
A może przy okazji policzymy
min oraz max?
Algorytm wyznaczania max jest
następujący:
1.
2.
3.
Za aktualne maksimum przypisz
jakąś małą liczbę.
Porównuj kolejne liczby z
aktualnym maksimum.
Jeśli liczba jest większa, to zamień
aktualne maksimum.
Algorytm max
1
-3
5
15
0
Algorytm max
1
-3
5
MAX: -100
15
0
Algorytm max
1
-3
5
1 >? MAX
MAX: -100
15
0
Algorytm max
1
-3
5
1 > MAX
MAX: 1
15
0
Algorytm max
1
-3
5
-3 >? 1
MAX: 1
15
0
Algorytm max
1
-3
5
15
5 >? 1
MAX: 1
0
Algorytm max
1
-3
5
15
5>1
MAX: 5
0
Algorytm max
1
-3
5
15 >? 5
MAX: 5
15
0
Algorytm max
1
-3
5
15 > 5
MAX: 15
15
0
Algorytm max
1
-3
5
15
0
0 >? 5
MAX: 15
Algorytm max
1
-3
5
MAX: 15
15
0
Uzupełniamy kod o min i max
Niejako przy okazji – widzimy
łańcuchowanie operatora strumieniowego
<<
Pobawimy się we wróżkę
 Pamiętacie
program „zgadnij moją liczbę”?
Gdzie komputer losował liczbę i podawał „za
dużo” lub „za mało”, a my zgadywaliśmy liczbę?
A
może by tak zrobić mu psikus? I odwrócić rolę?
 Napiszmy
program, gdzie to człowiek wymyśla
liczbę, a komputer ją odgaduje*.
* Zakładając, że użytkownik nie oszukuje 
Pobawimy się we wróżkę
 Czyżbyśmy
 Algorytm
1.
2.
3.
4.
5.
znowu zaprzęgli randoma do roboty?
może wyglądać tak:
Każ użytkownikowi wymyślić sobie liczbę.
Wylosuj liczbę z przedziału.
Spytaj użytkownika, czy to ta
Jeśli tak – otwórz szampana.
Jeśli nie – zgaduj do skutku.
Pobawimy się we wróżkę
Pobawimy się we wróżkę
Pętla nieskończona while(true)
może być zakończona przez instrukcję
break.
Pobawimy się we wróżkę
Pobawimy się we wróżkę
To się może nigdy nie
skończyć!
Pobawimy się we wróżkę
A
jak to zrobić lepiej?
 Odpowiedzią
(BST).
jest drzewo poszukiwań binarnych
Pobawimy się we wróżkę
42
Czy Twoja liczba to 50?
Pobawimy się we wróżkę
42
Czy Twoja liczba to 50?
Nie, za dużo!
Pobawimy się we wróżkę
Czy Twoja liczba to
(0+50)/2
=
25?
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(0+50)/2
=
25?
Nie, za mało!
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(25+50)/2
=
37?
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(25+50)/2
=
37?
Nie, za mało!
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(37+50)/2
=
43?
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(37+50)/2
=
43?
Nie, za dużo!
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(37+43)/2
=
40?
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(37+43)/2
=
40?
Nie, za mało!
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(40+43)/2
=
41?
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(40+43)/2
=
41?
Nie, za mało!
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(41+43)/2
=
42?
42
Pobawimy się we wróżkę
Czy Twoja liczba to
(41+43)/2
=
42?
Tak, zgadza się!
42
Pobawimy się we wróżkę
Zawsze
pytamy o połowę
dostępnego przedziału.
Ale
jak to zrealizować w C++?
42
Pobawimy się we wróżkę

Podobne dokumenty