1 Wstęp do informatyki- wykład 7 Operatory operator przecinkowy, operator zasięgu Pętla for Instrukcja break i continue Treści prezentowane w wykładzie zostały oparte o: S. Prata, Język C++. Szkoła programowania. Wydanie VI, Helion, 2012 www.cplusplus.com Jerzy Grębosz, Opus magnum C++11, Helion, 2017 B. Stroustrup, Język C++. Kompendium wiedzy. Wydanie IV, Helion, 2014 S. B. Lippman, J. Lajoie, Podstawy języka C++, WNT, Warszawa 2003.
Instrukcje iteracyjne - pętla while 2
Pętla do...while... 3
Pętla while - przykład Napisz program, który wyznaczy pierwszą liczbę naturalną postaci 2 n, która jest większa od losowo wybranej liczby lim: int main() int lim = rand(); //liczba losowa z [0, RAND_MAX] cout<<"wylosowana granica to: "<<lim<<endl; int liczba = 1; while ( liczba <= lim )//dopóki nie przekroczymy lim liczba *= 2;//liczymy kolejną potegę liczby 2 cout << "Szukana liczba to:" << liczba << endl; return 0; 4
Pętla do...while -przykład petla zaporowa Napisz program, który będzie wczytywał dane od użytkownika aż do chwili, gdy poda on liczbę z przedziału [5, 100] #include <iostream> using namespace std; int main() int n; do cout << "Podaj liczbe z przedziału [5, 100]"; cin >> n; while (n < 5 n > 100); cout << "Liczba z przedziału wynosi:" << n << endl; return 0; 5
Pętle przykład liczba cyfr liczby - pętla do-while #include <iostream> #include <cmath> //bo używamy funkcji abs using namespace std; int main() int n; cout << "Podaj liczbe calkowita "; cin >> n; int rob = abs(n);//można rob=n; bo tylko liczymy cyfry int il = 0; //zmienna - licznik ilości cyfr do il++; //il = il+1; il += 1; zwiększamy licznik //bo mamy pierwszą lub kolejna cyfrę liczby rob /= 10; //n = n/10; while (rob!= 0); cout << "Liczba cyfr liczby " << n << " to " << il ; return 0; 6
Operator przecinkowy 7 Operator przecinkowy jest dwuargumentowy: po dwóch stronach przecinka dwa wyrażenia wyr1, wyr2 Działanie jego polega na: obliczeniu wyrażenia wyr1 i zignorowaniu rezultatu; obliczeniu wyrażenia wyr2; jego wartość staje się wartością całego wyrażenia. Często operator przecinkowy stosuje się w części inicjalizacyjnej lub inkrementującej nagłówka pętli for
Operator przecinkowy 8 #include <iostream> using namespace std; int main(). int r = 0, k;. while (cin >> k, k) // dopóki k!=0 r += k > 0? (cout << "Dodatnia\n", +1) : (cout << "Ujemna\n", -1); cout << "Roznica ilosci dodatnich i ujemnych : " << r << endl;
Operator przecinkowy 9 while (cin >> k, k) - operator przecinkowy jest użyty w warunku pętli while: pierwsze wyrażenie, ' cin» k', wczytuje kolejną daną z klawiatury, i drugie, po prostu k, dzięki któremu pętla skończy się, gdy wczytana zostanie liczba 0 (gdyż wartością całego wyrażenia przecinkowego jest wartość prawego argumentu). r += k > 0? (cout << "Dodatnia\n", +1) : (cout << "Ujemna\n", -1); W pętli do r dodawana jest wartość wyrażenia: jest to operator selekcji sprawdzający znak k; w każdym przypadku rezultat będzie wartością wyrażenia przecinkowego. Dla k dodatnich będzie to wartość ' cout «"Dodatnia\n", +1', czyli +1 z efektem ubocznym polegającym na wypisaniu słowa "Dodatnia". Analogicznie, dla k ujemnych od r odjęte zostanie 1, a jako efekt uboczny wypisane będzie słowo "Ujemna".
10 Pętla for Pętla for (ang. for dla) oznacza: dla takich warunków wykonuj...: for(instr_inicjalizująca; wyr_warunkowe; instr_kroku) treść_pętli ; instr_inicjalizująca jest to instrukcja inicjalizująca zmienne używane w pętli. Wykonana jest jednokrotnie, na początku zanim zostanie wykonana właściwa praca pętli. wyr_warunkowe jest to wyrażenie, które obliczane jest przed każdym obiegiem pętli. Jeśli jest prawdziwe, to wykonywane zostają instrukcje będące treścią pętli, jeżeli nie, przerywana jest dalsza praca pętli. instr_kroku to instrukcja kroku pętli, wykonywana na zakończenie każdego obiegu (kroku) pętli. Jest to jakby ostatnia instrukcja, wykonywana bezpośrednio przed obliczeniem wartości wyr_warunkowe.
Pętla for for(instr_inicjaliz; wyr_warunkowe; instr_kroku) treść_pętli ; Praca pętli for: (1) Najpierw wykonuje się instrukcje instr_inicjaliz inicjalizujące pracę pętli. (2) Obliczana jest wartość wyrażenia warunkowego wyr_warunkowe: Jeżeli ma wartość false praca pętli jest przerywana. Jeżeli zaś ma wartość true, wówczas wykonywane zostają instrukcje będące treścią pętli. (3) Po wykonaniu treści pętli wykonana zostaje instrukcja kroku pętli (instr_kroku), a następnie wracamy do (2). 11
Pętla for 12
Pętla for -przykład for(instr_inicjaliz; wyr_warunkowe; instr_kroku) treść_pętli ; int main() cout << "Stewardzie, ilu leci pasazerów? "; int ile; // liczba pasażerów cin >> ile; for(int i = 1 ; i <= ile ; i++ ) cout << "Pasazer nr " << i << " prosze zapiac pasy! \n"; cout << "Wszyscy zapieli pasy, to ladujemy. "; 13
14 Pętla for -przykład Jeśli stewart odpowie 3, to na ekranie pojawi się: Stewardzie, ilu leci pasazerów? 3 Pasazer nr 1 prosze zapiac pasy! Pasazer nr 2 prosze zapiac pasy! Pasazer nr 3 prosze zapiac pasy! Wszyscy zapieli pasy, to ladujemy. instr_inicjaliz: int i = 1 definicja zmiennej z przypisaniem, tworzymy i ustawiamy licznik obiegów pętli i na 1 wyr_warunkowe: i <= ile - Jeżeli i jest mniejsze lub równe ile, wówczas wykonywana zostaje instrukcja będąca treścią pętli (czyli wypisanie tekstu z prośbą do i-tego pasażera o zapięcie pasów ) instr_kroku:i++ - zwiększenie wartości licznika zmiennej i o 1, przed kolejnym obrotem pętli
Pętla for -zakres istnienia zmiennych for(int i = 1 ; i <= ile ; i++ ) i- licznik obiegów pętli W wyrażeniu inicjalizacyjnym zmiennej o nazwie i nadajemy wartość 1, po czym przy każdym obiegu pętli wartość tego licznika rośnie. Licznik i jest zmienną, której potrzebujemy tylko na użytek tej pętli, dlatego tworzymy go w instrukcji inicjalizacyjnej. Obiekt zdefiniowany w instrukcji inicjalizacyjnej pętli for istnieje (jest do dyspozycji) tylko w ramach tej instrukcji for. To znaczy w tej linii, w której go napisaliśmy, a także w instrukcjach stanowiących treść pętli. Po zakończeniu pracy pętli tak zdefiniowany obiekt staje się niedostępny (przestaje istnieć). 15
Pętla for for(instr_inicjaliz; wyr_warunkowe; instr_kroku) treść_pętli ; Pętla for jest najczęściej stosowaną formą instrukcji iteracyjnej. Jest szczególnie wygodna, jeśli z góry wiadomo, ile będzie powtórzeń instrukcji stanowiącej ciało pętli (instrukcja treść_pętli). Zwykle w części inicjalizacyjnej instr_inicjaliz nadajemy odpowiednie wartości zmiennym używanym w ciele pętli, a w części instr_kroku dokonujemy ich zmiany po każdym przebiegu pętli. 16
Pętle przykład pętla z licznikiem Napisz program, który oblicza sumę 1/1+1/2 +1/3+...+1/n, gdzie n jest liczbą >0 podaną przez użytkownika (pętla zaporowa). #include <iostream> using namespace std; int main() int n; //n ma być liczbą >0 do cout << "Podaj liczbe calkowita"; cin >> n; while (n<=0);//(!(n>0)) 17
18 Pętle przykład while i for pętla z licznikiem // 1/1 + 1/2 +1/3 + + 1/n double s = 0.0; //suma odwrotności l.rzeczywista int k = 1; //licznik przechodzący //po kolejnych mianownikach od 1 do n while(k <= n) //dopóki są jeszcze odwrotnosci s += 1.0/k;//do sumy dodajemy kolejne składnik k++; //przechodzimy do kolejnej odwrotnosci s = 0.0; //zmienna na sume wyzerowana na poczatku for (int k=1; k <= n; k++) s += 1.0/k; cout << "Suma odwrotnosci wynosi" << s << endl;
19 Pętle przykład - for pętla z licznikiem Wyświetlić 10 początkowych liczb parzystych >0. /*1 sposób: wyswietlamy liczby 2,4,...,20, idziemy w pętli poczynając od 2 i przesuwamy się o 2*/ for(int i=2; i<=20; i+=2) cout<<i<<endl; //2-gi sposób- kolejne liczby parzyste są równe // 2i, i=1,..,10 for(int i=1; i<=10; i++ ) cout<<2*i<<endl;
20 Pętle przykład - for pętla z licznikiem //odliczanie od 10 w dół do 0 int main() for (int i = 10; i>=0; i--) //petla od 10 do 0 cout << "i = " << i << "\n"; cout << "Start\n";
21 Pętla - for uwagi instr_inicjaliz nie musi być tylko jedną instrukcją. Może być ich kilka oddzielonych przecinkami (operator przecinkowy). Podobnie w przypadku instrukcji kroku pętli (instr_kroku). Zauważmy, że nie jest możliwe zadeklarowanie w instr_inicjaliz zmiennych różnych typów (gdyż wymagałoby to więcej niż jednej instrukcji deklaracyjnej i ;) Można natomiast zadeklarować więcej niż jedną zmienną tego samego typu; na przykład prawidłowa jest konstrukcja for (int i = 0, k = size-1; i < k; i++, k--) // OK
22 Pętla - for przykład wykorzystania operatora, Napisz program, który oblicza sumę n początkowych liczb naturalnych kończących się jedną z cyfr: 2, 3 lub 9, np. dla n=7 s=2+3+9+12+13+19+21 Wartość liczby n>0 pobieramy od użytkownika(pętla zaporowa). #include <iostream> using namespace std; int main() int n; do cout << "podaj liczba>0" << endl; cin>>n; while(n<=0);
23 Pętla - for uwagi //i - kolejne liczby 1,2,... //k-ile mamy konczacych sie cyframi 2, 3 lub 9 int s=0; for(int i=1,k=1 ;k <=n ;i++) if(i%10==2 i%10==3 i%10==9)//i jest ok //to mamy odpowiednia liczba to dodajemy ją do sumy s += i; k++;//zwiekszamy licznik użytych liczb cout<<s<<endl; return 0;
24 Pętla - for uwagi Poszczególne elementy: instr_inicjaliz, wyr_warunkowe, instr_kroku nie muszą wystąpić. Dowolny z nich można opuścić, zachowując jednak średnik oddzielający go od sąsiada. Opuszczenie wyrażenia warunkowego traktowane jest tak, jakby stało tam wyrażenie zawsze prawdziwe (warunek spełniony true). Tak więc pętla for( ; ; ) // treść pętli jest pętlą nieskończoną.
25 Pętla - for uwagi Poszczególne elementy: instr_inicjaliz, wyr_warunkowe, instr_kroku nie muszą wystąpić. Dowolny z nich można opuścić, zachowując jednak średnik oddzielający go od sąsiada. Opuszczenie wyrażenia warunkowego traktowane jest tak, jakby stało tam wyrażenie zawsze prawdziwe (warunek spełniony true). Tak więc pętla for( ; ; ) // treść pętli jest pętlą nieskończoną.
26 Pętle break Zapoznaliśmy się już z działaniem instrukcji break, polegającym na przerwaniu wykonywania instrukcji switch. Podobne działanie ma break w stosunku do instrukcji pętli: for, while, do...while. Instrukcja break powoduje natychmiastowe przerwanie wykonywania tych pętli. Jeśli mamy do czynienia z kilkoma pętlami, zagnieżdżonymi jedna wewnątrz drugiej, to instrukcja break powoduje przerwanie tylko tej pętli, w której bezpośrednio tkwi. Jest to więc jakby przerwanie z wyjściem tylko o jeden poziom wyżej.
Pętla break - przykład for (int i = 1; i < 10; i++) cout << i << '\n'; if (i == 4) break; W rezultacie wykonania tego fragmentu programu na ekranie pojawi się: 1 2 3 27
28 Pętle continue Instrukcja continue przydaje się wewnątrz pętli for, while, do...while. Powoduje ona zaniechanie wykonywania instrukcji będących dalszą treścią danego obiegu pętli, jednak (w przeciwieństwie do instrukcji break) sama pętla nie zostaje przerwana. continue przerywa tylko ten obieg pętli i przygotowuje do rozpoczęcia następnego, kontynuując pracę pętli.
Pętle continue -przykład for(int k = 0 ; k < 12 ; k = k + 1) cout << "A"; if(k > 1) continue; cout << "b\n";//ta instrukcja będzie zaniechana //jeśli wykona się continue W rezultacie wykonania tego fragmentu programu na ekranie pojawi się: Ab Ab AAAAAAAAAA 29
30 Zasięg i widoczność zmiennych Zasięg (ang. scope) deklaracji to ta część programu, gdzie deklaracja jest aktywna, czyli nazwa deklarowana może być użyta i odnosi się do tej właśnie deklaracji. Zakres widoczności (ang. visibility) natomiast to ten fragment (fragmenty), w których nazwa (identyfikator) może być użyta bez żadnej kwalifikacji (nazwą klasy, przestrzeni nazw itd.). Zakres widoczności zadeklarowanej zmiennej może być węższy niż zasięg deklaracji na skutek przesłonięcia.
31 Zasięg i widoczność zmiennych Zmienne zadeklarowane poza wszystkimi funkcjami mają zasięg od miejsca deklaracji do końca pliku. W szczególności obejmuje on wszystkie funkcje zdefiniowane w tym module po wystąpieniu deklaracji. Zmienne (ogólnie: nazwy) zadeklarowane poza wszystkimi funkcjami nazywamy zmiennymi globalnymi. W odróżnieniu od zmiennych lokalnych, definiowanych wewnątrz funkcji, są one automatycznie inicjowane zerami odpowiedniego typu (dotyczy to również wskaźników). Ich czas życia to okres od początku do końca działania programu.
32 Zasięg i widoczność zmiennych Zmienne lokalne są deklarowane wewnątrz funkcji, a ogólniej bloku ograniczonego nawiasami klamrowymi. Ich zasięg obejmuje część programu od miejsca deklaracji do końca tego bloku. Zasięgiem zmiennych deklarowanych w części inicjalizacyjnej pętli for (część w nawiasie okrągłym przed pierwszym średnikiem) jak i zmiennych deklarowanych w części warunkowej instrukcji if, while, for, switch jest ciało danej instrukcji.
Zasięg i widoczność zmiennych 33 Zmienne globalne mogą być przesłonięte, jeśli wewnątrz funkcji (lub bloku) zadeklarujemy inną zmienną o tej samej nazwie (choć niekoniecznie tym samym typie). Wówczas nazwa tej zmiennej w ciele funkcji odnosi się do zmiennej lokalnej. Zmienna globalna istnieje, ale jest w zakresie funkcji (bloku) niewidoczna. Nie znaczy to, że nie mamy do niej dostępu. Do przesłoniętej zmiennej globalnej możemy odwołać się poprzez operator zasięgu ' ::' ( czterokropek ). Jeśli na przykład przesłonięta została zmienna o nazwie k, to do globalnej zmiennej o tej nazwie odwołać się można poprzez nazwę kwalifikowaną ::k. Jeśli nazwa lokalna zasłania inną nazwę lokalną, wówczas nie da się do niej dotrzeć takim operatorem zasięgu(zakresu).
Operatory zasięgu :: 34 Priorytet 1 1 zasięg klasy klasa::sklad 2 zasięg przestrzeni nazw pnazw::sklad 3 zasięg globalny ::nazw #include <iostream> using namespace std; int k=0; //zmienna globalna - jest //zatem widoczna w funkcji main. int main() //na razie k i ::k odnoszą się //do tej samej zmiennej globalnej. cout << " k: " << k << endl; //0 //odwołanie do zmiennej globalnej cout << "::k: " << ::k << endl; //0 //odwołanie do zmiennej globalnej
Operator zasięgu globalnego :: 35 int k = 10;//zm. lokalna przesłania w f-cji zm. globalna cout << " k: " << k << endl;//10 odniesienie do zm. lok. cout << "::k: " << ::k << endl;//0 odniesienie do // zm.globalnej ::k = 1; //możemy zmieniać wartość zmiennej globalnej cout << " k: " << k << endl; //10 cout << "::k: " << ::k << endl; //1 //blok wewnętrzny int k = 77;//zm.k przesłania w bloku //lokalną dla main zm. k cout << "W bloku:" << endl; cout << " k: " << k << endl;//77 mamy dostęp //do k z bloku cout << "::k: " << ::k << endl;//1 oraz k globalnego
36 Specyfikator (modyfikator) const Czasem chcielibyśmy w programie posłużyć się obiektem (np. typu int), którego zawartości nawet przez nieuwagę nie chcielibyśmy zmieniać. Obiekt tego typu to tak zwany obiekt stały (inaczej stała). Taki obiekt tworzymy poprzez dodanie w jego definicji słowa kluczowego const. Kompilator widząc je rozumie, że ma strzec zawartości tego obiektu i w dalszej pracy programu nie pozwolić już jej zmienić. Jedynym sposobem na nadanie stałej jej wartości jest inicjalizacja podczas jej definiowania, bezpośrednio w instrukcji deklaracyjnej: const double PI = 3.1415926536; Po utworzeniu i inicjalizacji wartości stałej nie można zmienić.
Pętle przykład pętla w pętli //rozkład liczby naturalnej na czynniki pierwsze int main() unsigned int n; cout << "podaj liczbe"; cin >> n; int k=2; //kolejne cyfry rozkładu while (n>1)//dopóki liczba ma jeszcze jakieś dzielniki while (n%k==0)//dopóki n się dzieli przez k cout << k << " "; n /= k; k++;//nastepny dzielnik 37