710 likes | 852 Views
Podstawy informatyki 2013/2014. Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka. wyr. w1 == wyr. Tak. Nie. w2 == wyr. Tak. Nie. instr1. instr2. w_n == wyr. Tak. Nie. instr_n.
E N D
Podstawy informatyki2013/2014 Łukasz SztangretKatedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiałyDanuty Szeligi i Pawła Jerzego Matuszyka
wyr w1== wyr Tak Nie w2== wyr Tak Nie instr1 instr2 ... w_n== wyr Tak Nie instr_n instr_d Instrukcja wyboru switch switch(wyr) { casew1: instr1; break; casew2: instr2; break; ... casew_n: instr_n; break; default: instr_d; break; } • Instrukcja wyboru służy do podejmowania wielowarian-towych decyzji. • Najpierw obliczane jest wy-rażenie wyr. • Jeśli jego wartość odpowiada którejś z wartości podanej w jednej z etykiet case, to wykonywane są instrukcje po tej etykiecie, aż do napotkania instrukcji break. • Jeśli wartość wyrażenia nie zgadza się z żadną z wartości przy etykietach case, wówczas wykonywane są instrukcje po etykiecie default.
Instrukcja wyboru switch • Instrukcja break: • powoduje wyjście z instrukcji switch. • Etykieta default: • może znajdować się w dowolnym miejscu, • może w ogóle nie występować w instrukcji switch – wtedy, jeśli wartość wyrażenia nie zgadza się z żadną z wartości przy etykietach case, instrukcja switch nie wykonuje niczego. • Instrukcji występujących po etykiecie case nie musi kończyć instrukcja break. Jeśli jej nie umieścimy, to zaczną wykonywać się instrukcje umieszczone pod następną etykietą case.
Instrukcja wyboru switch #include<iostream> using namespace std; int main() { int a; cout << "Podajliczbe" << endl; cin >> a; switch (a) { case 1: cout << "Podalesliczbe jeden" << endl; break; case 2: cout << "Podalesliczbedwa" << endl; break; default: cout << "Nie podales ani liczby jeden ani dwa" << endl; } } Wyrażenie Wartość Polecenia nie są w nawiasie {}
Instrukcja wyboru switch #include<iostream> usingnamespacestd; intmain() { int a; cout << "Podaj liczbe" << endl; cin >> a; switch (a) { case 1: cout << "Podales liczbe jeden" << endl; case 2: cout << "Podalesliczbe dwa" << endl; default: cout << "Nie podales ani liczby jeden ani dwa" << endl; } }
switchvsif…else • W przypadku instrukcji switch obiekt powinien być typu całkowitego • W przypadku instrukcji if…else typ obiektu nie ma znaczenia • W przypadku instrukcji switch obiekt porównywany jest ze stałą (znaną na etapie kompilacji) • W przypadku instrukcji if…else obiekt może być porównywany z wyrażeniem zmiennym
switchvsif…else • W przypadku instrukcji switchzwasze sprawdzana jest równość • W przypadku instrukcji if…else porównanie może być dowolnym operatorem logicznym
Nie Tak wyr instr1 Nie Tak wyr_b instr2 Instrukcja sterująca break while(wyr) { instr1; if(wyr_b) break; instr2; } • Instrukcja sterująca break przerywa natychmiast dzia-łanie innych instrukcji steru-jących: • switch, • for, • while, • do...while. • Jeśli instrukcja breakwys-tępuje wewnątrz kilku zag-nieżdżonych pętli, to przery-wa działanie tylko tej pętli, w której bezpośrednio tkwi (jest to tak jakby wyjście „o jeden poziom wyżej”).
Instrukcja sterująca break 1 2 3 4 5 6 7 8 9 10 #include<iostream> usingnamespacestd; intmain() { for (int i=1; ;i=i+1) { cout << i << endl; if (i==10) { break; } } } Pętla nieskończona Wyjście z pętli
i_init Nie Tak wyr i_krok instr1 Tak Nie wyr_c instr2 Instrukcja sterująca continue for(i_init; wyr; i_krok){ instr1; if(wyr_c) continue; instr2; } • Instrukcja sterująca continue stosowana jest w pętlach. • Powoduje ona zaniechanie reali-zacji instrukcji będących treścią pętli, jednak (w przeciwieństwie do instrukcji break) sama pętla nie zostaje przerwana. • Instrukcja continue przerywa tylko aktualny obieg pętli i zaczyna następny, kontynuując pracę pętli. • Po wykonaniu instrukcji continue w pętli forwykony-wana jest i_krok.
Instrukcja sterująca continue #include<iostream> usingnamespacestd; intmain() { int n=5; for (int i=1; i<=10; i=i+1) { if (i==n) continue; cout << i << endl; } } 1 2 3 4 6 7 8 9 10 Przeskok na koniec pętli
Instrukcja skoku goto ... if(war) gotoet1; instr1; instr2; et1: instr3; • Po napotkaniu instrukcji skoku goto wykonywanie programu przenosi się do miejsca oznaczonego etykietą. • Z instrukcją goto wiąże się zawsze etykieta, do której należy przeskoczyć. • Etykieta musi znajdować się w aktualnym zakresie ważności. • Etykieta to nazwa, po której następuje dwukropek. • Używanie instrukcji goto zdradza (zazwyczaj), że jest się złym programistą. • Instrukcji goto zawsze da się uniknąć (choć nie zawsze jest to efektywne).
Instrukcja goto 0 00 0 0 1 0 0 2 0 1 0 0 1 1 0 1 2 0 2 0 0 2 1 0 2 2 1 0 0 1 0 1 1 0 2 1 1 0 1 11 #include<iostream> usingnamespacestd; intmain() { for (int i=0; i<3; i=i+1) for (int j=0; j<3; j=j+1) for (int k=0; k<3; k=k+1) { cout<<i<<""<<j<<""<<k<<endl; if (i==1 && j==1 && k==1) goto koniec; } koniec: cout<<"KONIEC\n"; } Przeskok do koniec
Typy • Każda nazwa zanim zostanie użyta musi zostać zdefiniowana (w dowolnym momencie, ale przed jej użyciem). • Obiekty różnych typów zajmują w pamięci komputera w różną objętość, różnie też można z nimi postępować. Stąd konieczność podania typu obiektu. • Składnia definicji: typnazwa_zmiennej; typ nazwa1, nazwa2, nazwa3;
Typy w C++ TYPY: • fundamentalne (jakby najbardziej podstawowe) • złożone (wykorzystujące typ fundamentalny) TYPY: • wbudowane (standardowe wyposażenie języka C++) • definiowane przez użytkownika (wymyślane przez programistę)
Typy złożone Operatory umożliwiające tworzenie typów złożonych to: • [] tablica obiektów danego typu • * wskaźnik do pokazywania na obiekty danego typu • () funkcja zwracająca wartość danego typu • & referencja obiektu danego typu
Referencja int a;
Referencja int a; int &b=a; Referencja musi być zainicjalizowana!!! Zapis: int &b; spowoduje błąd kompilacji.
Typ void • Typ voidjest również typem fundamentalnym. • Nie można zdefiniować obiektu typu void. • Typ void może występować tylko w deklaracjach typów złożonych: void funkcja(); void *wskaźnik; void tablica[5]; void &referencja=obiekt;
Zakres ważności nazwy obiektu i czas życia obiektu. • Czas życia obiektu to okres od momentu, gdy zostaje od zdefiniowany do momentu, gdy przestaje istnieć. • Zakres ważności nazwy obiektu to fragment programu, w którym nazwa obiektu jest znana, czyli obiekt jest dostępny. • Obiekt może istnieć (żyje) ale nie jest dostępny (jesteśmy poza zakresem ważności jego nazwy)
Zakres ważności nazwy • lokalny • blok funkcji • obszar pliku • obszar klasy (struktury) • zakres zdefiniowany przez przestrzeń nazw
Zakres lokalny intmain() { ... { int a; ... //tu obiekt jest dostępny } ... //tu już nie }
Zakres bloku funkcji void funkcja() { ... goto etykieta; ... etykieta: ... }
Zakres obszaru pliku int a; intmain() { ... } void funkcja() { ... }
Zakres zdefiniowany przez przestrzeń nazw #include<iostream> usingnamespacestd; namespace moja { int a; } intmain() { moja::a=1; a=1; cout<<moja::a<<endl; } BŁĄD zmienna a nie istnieje 1
Zakres zdefiniowany przez przestrzeń nazw #include<iostream> usingnamespacestd; namespace moja { int a; } usingnamespace moja; intmain() { a=1; cout<<a<<endl; } 1
Zakres zdefiniowany przez przestrzeń nazw #include<iostream> usingnamespacestd; namespace moja{int a;} usingnamespace moja; intmain() { a=1; cout<<a<<endl; int a; a=2; cout<<a<<endl; cout<<moja::a<<endl; } 1 2 1
Zakres zdefiniowany przez przestrzeń nazw #include<iostream> usingnamespacestd; namespace moja1{int a;} namespace moja2{double a;} usingnamespace moja1; usingnamespace moja2; intmain() { a=1; moja1::a=1; cout<<moja1::a<<endl; } BŁĄD kompilator nie wie do której zmiennej się odwołujemy Tu jest OK 1
Zakres zdefiniowany przez przestrzeń nazw #include<iostream> usingnamespacestd; namespace moja { int a; double b; } usingmoja::a; intmain() { a=1; moja::b=1.5; cout<<a<<endl<<moja::b<<endl; }
Zakres zdefiniowany przez przestrzeń nazw #include<iostream> usingnamespacestd; intmain() { cout<<"Hello\n"; } #include<iostream> intmain() { std::cout<<"Hello\n"; }
Zakres zdefiniowany przez przestrzeń nazw #include<iostream> intmain() { int cout=2; std::cout<<cout; } #include<iostream> usingnamespacestd; intmain() { int cout=2; cout<<cout; }
Zasłanianie nazw 1 #include<iostream> using namespace std; int i=1; int main() { cout << i << endl; int i=2; cout << i << endl; cout << ::i << endl;{ cout << i << endl; int i=3; cout << i << endl; cout << ::i << endl;} cout << i << endl; cout << ::i << endl; int i=4; } 2 1 2 3 1 2 BŁĄD REDEFINICJA 1
Zasłanianie nazw #include<iostream> using namespace std; int i=1; int main() { cout << i << endl; int i=2; cout << i << endl; cout << ::i << endl;{ cout << i << endl; int i=3; cout << i << endl; cout << ::i << endl;} cout << i << endl; cout << ::i << endl; int i=4; }
Zmienne lokalne #include<iostream> usingnamespacestd; intmain() { for (int i=0; i<5; i=i+1) { cout<<i<<endl; } cout<<i<<endl; } 0 1 2 3 4 BŁĄD
Zmienne lokalne #include<iostream> usingnamespacestd; intmain() { int i; for (i=0; i<5; i=i+1) { cout<<i<<endl; } cout<<i<<endl; } 0 1 2 3 4 5
Specyfikator const • Specyfikator const zmienia zwykłą definicję tak, że jest to teraz definicja obiektu stałego, np.: const double pi = 3.14; • Obiekty stałe można tylko inicjalizować, nie można wykonać przypisania! constint a; a=5; BŁĄD
Specyfikator register • Specyfikator register używany jest do definiowania obiektów, do których chcemy mieć bardzo szybki dostęp. • register jest sugestią dla kompilatora aby zmienną umieścił w rejestrze procesora. register int i; • Zmienna umieszczona w rejestrze nie ma adresu! • Odwołanie się do adresu takiej zmiennej spowoduje przeniesienie jej do pamięci i zwrócenie jej adresu.
Specyfikator volatile • Specyfikator volatile zmienia zwykłą definicję tak, że jest to teraz definicja obiektu, którego wartość może się zmienić bez wiedzy kompilatora, np.: volatile double a;
Instrukcja typedef • Instrukcja typedef pozwala na nadanie dodatkowej nazwy już istniejącemu typowi, np.: typedefodlegloscint; Definicja odleglosc a; odpowiada definicji int a;
Typ wyliczeniowy enum • Jest typem całkowitoliczbowym. • Do obiektu takiego typu można podstawić jedynie wartość określoną na liście wyliczeniowej. • Definicja enumnazwa_typu {lista wyliczeniowa};
Typ wyliczeniowy enum #include<iostream> usingnamespacestd; intmain() { enummiesiace{sty=1,lut,mar,kwi,maj,cze,lip,sie,wrz,paz,lis,gru}; miesiace M; M=lut; //M=3; //M=ala; cout<<M<<endl; } Definicja typuenum Definicja obiektu Przypisanie wartości 2 Oba przypisania generują błąd
Typ wyliczeniowy enum #include<iostream> usingnamespacestd; intmain() { enum {a=10,b,c,d,e,f,g,h,i,j,pod}; cout<<a*pod+c<<endl; } Definicja typuenum bez nazwy 212
Jednoargumentowe operatory arytmetyczne • Operatory znaku: + - a=+3; b=-5; • Operatory inkrementacji i dekrementacji:++ -- • wersja przedrostowa ++a; --b; • wersja przyrostkowa a++; b--;
Jednoargumentowe operatory arytmetyczne #include<iostream> usingnamespacestd; intmain() { int a=5,b=5,c=5,d=5; cout<<++a<<"\t"<<a<<endl; cout<<b++<<"\t"<<b<<endl; cout<<--c<<"\t"<<c<<endl; cout<<d--<<"\t"<<d<<endl; } 6 6 5 6 4 4 5 4
Dwuargumentowe operatory arytmetyczne • Dodawanie + • Odejmowanie - • Mnożenie * • Dzielenie / • Reszta z dzielenia %
Operatory przypisania • a+=2; oznacza a=a+2; • …