Kurs C++
Transkrypt
Kurs C++
Podstawy Informatyki Wykład 5 Różne pożyteczne algorytmy Algorytm sprawdzania parzystości liczby We: sprawdzana liczba x y = (x/2)*2 N WY: x nieparzyste T ? x=y WY: x parzyste Algorytm sprawdzania parzystości liczby Program parzystosc; { Deklaracja zmiennych } x,y: całkowita; Początek pisz(‘podaj liczbe x’); czytaj(x); y := x/2; y := y*2; jeżeli (x=y) to pisz („liczba x jest parzysta”) w przeciwnym razie pisz („liczba x jest nieparzysta”) koniec. Uwaga: Program ma sens tylko dzięki własności dzielenia liczb całkowitych . Algorytm sprawdzania czy trójkąt jest prostokątny We: a,b,c – boki trójkąta d = a*a + b*b WY: trójkąt nie jest prostokątny N T ? d=c*c WY: trójkąt jest prostokątny Algorytm sprawdzania czy trójkąt jest prostokątny Program trojkat prostokatny; { Deklaracja zmiennych } a,b,c,d: całkowita; Początek pisz(‘podaj boki a,b,c); d:=a*a+b*b; jeżeli (d=c*c) to pisz („trójkąt prostokątny”) w przeciwnym razie pisz („trójkąt nie jest prostokątny”) Gdzie tkwi błąd? Jak poprawić ten program? koniec. . Obliczanie pierwiastka kwadratowego Obliczanie pierwiastka kwadratowego: Przykład: Jak obliczyć pierwiastek z x? Metoda Newtona: y + xy y= 2 x- liczba pierwiastkowana y - wynik pierwiastkowania . Obliczanie pierwiastka kwadratowego - algorytm: Program pierwiastek kwadratowy; { Deklaracja zmiennych } x,y: rzeczywista; i: całkowita; Początek pisz(‘podaj x); y := 1; dla i:=0 do i:= 20 y:=(y+x/y)/2; pisz („pierwiastek z”, x, „ = ” , y) . koniec. Sito Erastotenesa Wyszukiwanie liczb pierwszych 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 3 4 5 6 7 8 9 10 11 12 13 ↑ 14 15 16 17 18 19 20 21 22 23 24 25 26 Sito Erastotenesa 2 3 5 7 9 11 13 ↑ 15 2 17 3 19 5 21 23 7 25 11 13 ↑ 17 19 Kiedy koniec? Dla √n 23 25 program sito a: tablica [1...1000] elementów całkowitych i,j,n,m,x,y:całkowite pisz 'podaj górną granicę przedziału, max 1000' czytaj n m=int(sqrt(n)) {maksymalny mnoznik – pierwiastek z n) dla i=1 do n wykonuj a[i]=i {podstawienie kolejnych liczb do tablicy} dla j=2 do m wykonuj początek jeśli a[j] <>0 to początek dla i=j+1 do n wykonuj początek x=a[i] y=(x/j)*j {sprawdzanie podzielności} jeśli x=y to a[i]=0 koniec koniec koniec pisz 'w podanym zakresie liczby pierwsze to:' dla i=2 do n jeśli a[i] <>0 to drukuj a[i] koniec Krótki kurs C++ Historia •Lata 70-te XX w – język C (do pisania systemów operacyjnych) •"The C programming language" B. Kernighan, D. Ritchie – pierwszy standard •Koniec lat 80 – standard ANSI C •1983 - C++ (Bjarne Stroustrup) •Do chwili obecnej nie stosuje się jednego standardu! Kompilatory C++ •Microsoft Visual C++ (w ramach licencji MSDN AA) Darmowe: Linux (PC), Solaris (SUN) : •http://gcc.gnu.org/ - g++ Windows : •http://www.bloodshed.net/dev/devcpp.html - Dev-C++ •http://www.delorie.com/djgpp/ - DJGPP •http://www.mingw.org/ - MinGW Kompilacja *.cpp nagłówki moduły biblioteki kompilator linker błędy błędy UNIX Kompilacja: 1) g++ prog.cpp 2) g++ -o prog prog.cpp Uruchomienie: 1) a.out 2) prog programm Pierwszy program #include <iostream> #include <string> using namespace std; int main() { string komunikat; double a,b,c; komunikat = "Koniec obliczeń"; cout <<"Podaj a i b: "; cin >>a>>b; c=a+b; cout <<" suma "<<a<<" i "<<b<<" wynosi "<<c<<'\n'; cout<<komunikat<<'\n'; return 0; } Dyrektywy preprocesora #include <iostream> #include <string> Program przed kompilacją dołącza zewnętrzne pliki – np pliki nagłówkowe. Poniżej fragment pliku iostream: extern _IO_istream_withassign cin; // clog->rdbuf() == cerr->rdbuf() extern _IO_ostream_withassign cout, cerr; Zdefiniowanie przestrzeni nazw: using namespace std; Program główny int main() { ... ... return 0; } Program główny traktowany jest jak funkcja – musi zwrócić jakąś wartość (typu integer) Zwracając do systemu operacyjnego wartość 0 informujemy, że program zakończył się bez błędu. Deklaracja zmiennych string komunikat; double a,b,c; •short int - typ całkowity krótki •int - typ całkowity. •long int - typ całkowity długi •float - typ zmiennoprzecinkowy pojedynczej precyzji. •double - typ zmiennoprzecinkowy podwójnej precyzji. •long double - typ zmiennoprzecinkowy podwójnej precyzji długi. •char - typ znakowy •string – ciąg znaków Nazwy zmiennych mogą składać się z liter,cyfr i podkreślenia _ Nazwa nie może się zaczynać od cyfry unsigned – zmienna bez znaku (tylko dodatnia) – dla typów int int (–127,128) unsigned int (0,255) Operatory komunikat = "Koniec obliczeń"; c=a+b; •operator przypisania •operator dodawania •operator odejmowania •operator mnożenia •operator dzielenia •operator reszty z dzielenia (modulo) •operator znaku liczby (np. -45) = + * / % Operatory złożone += -= *= /= %= zmienna += 2 zmienna -= 7 zmienna *= 3 zmienna /= 5 zmienna %= 3 ≡ ≡ ≡ ≡ ≡ zmienna = zmienna + 2 zmienna = zmienna - 7 zmienna = zmienna * 3 zmienna = zmienna / 5 zmienna = zmienna % 3 Operatory inkrementacji i dekrementacji ++ zwiększenie wartości o 1, np. i++ to jest to samo co i=i+1 -- zmniejszenie wartości o 1, np. i-- to jest to samo co i=i-1 Uwaga! Operatory te można stosować przed i po zmiennej, tzn. liczba++ lub ++liczba. Podobnie dla --. Mimo, że działanie operatora w obu wypadkach jest podobne, to nie jest jednak identyczne! ++liczba najpierw dodaje do liczby 1, a potem zwraca jej wartość liczba++ najpierw zwraca wartość, a potem dodaje liczba =5; a) cout<<++liczba; drukuje 6 b) cout<<liczba++; drukuje 5 a liczba jest po instrukcji a lub b zawsze równa 6 Operatory relacji == != > >= < <= równa się jest różne jest większe jest większe lub równe jest mniejsze jest mniejsze lub równe Operatory logiczne || suma - prawdziwe jeśli którekolwiek z wyrażeń jest prawdziwe && iloczyn - prawdziwe jeśli oba wyrażenia są prawdziwe ! negacja logiczna - powoduje zaprzeczenie wyrażenia Uwaga! Przypisanie = zwraca wartość przypisania czyli np. a=3 zwraca wartość 3, a każda liczba różna od zera jest w języku C++ traktowana jako prawda. Tylko wartość 0 jest traktowana jako fałsz. (a=2) || (3==5) ⇒ zawsze prawda; (a==2)||(3==5) niekoniecznie Opercje wejścia i wyjścia Strumienie – biblioteka iostream cout - powiązany ze standardowym urządzeniem wyjścia cin - powiązany ze standardowym urządzeniem wejścia cerr - strumień błędów - połączony ze standardowym urządzeniem wyjścia clog - podobnie jak cerr, ale wydajniejszy przy wielu danych << - operator wysyłania do strumienia >> - operator pobierania ze strumienia np. cin >>a>>b; cout <<x1; cout <<y1<<' '<<y2<<'\n'; Instrukcja warunkowa if (warunek) instrukcja1; else instrukcja2; if (warunek) { instrukcja1; instrukcja2; ... instrukcjan; } else { instrukcja1; instrukcja2; ... instrukcjan; } Tablice int calkowite[20]; char znaki[5]; double liczby[1000]; string napisy[5]; - przechowuje 20 liczb typu int - p. 5 znaków - p. 1000 liczb typu double - p. 5 napisów (wieloznakowych) Uwaga! Rozmiar tablicy musi być podany przed kompilacją znaki[0] - pierwszy element tablicy znaki znaki[4] – piąty element tablicy Inicjacja tablicy int calk[5]={2,-3,4,8,12}; int aa[3]={12,-3}; Nie zainicjowane wyrazy otrzymują wartość 0 Nie zainicjowana tablica ma nieokreślone wartości. int bb[3]={2,-3,4,8}; //Kompilator wykaże błąd! a=bb[4] – program nie zasygnalizuje błędu, ale przeczyta nieprzewidywalne dane! Pętle (1) - for for (licznik=pocz;licznik<konc;++licznik) { Instrukcje w pętli .... } licznik – zmienna sterująca pętlą Wykonuje się dla wartości licznik: od pocz do konc z dodaniem 1 (++licznik) za każdym cyklem -------------------------------------------------------------------------------------------for (licznik=pocz;licznik<konc;++licznik) { Instrukcje w pętli .... ++licznik } Licznik zwiększamy dwa razy! int licznik; for (licznik=pocz;licznik<konc;++licznik) { Instrukcje w pętli .... } Pętla wykona się 9 razy Po zakończeniu pętli zmienna licznik wynosi 10 --------------------------------------------------------------------------------Nie musimy deklarować oddzielnej zmiennej licznik: for (int licznik=pocz;licznik<konc;++licznik) { Instrukcje w pętli .... } Po zakończeniu pętli zmienna licznik... nie istnieje Odliczanie "z góry" int licznik; for (licznik=10;licznik>=0;--licznik) { Instrukcje w pętli .... } Pętla wykona się 11 razy Po zakończeniu pętli zmienna licznik wynosi -1 Nie możemy w tym przypadku zadeklarować zmiennej licznik jako unsigned int Pętle zagnieżdżone int i, j,k=1; for (i=1;i<=10; i+=3) { for (j=5;j>=2;--j) { Instrukcje w pętli ....... cout<<i<<j<<k; ++k; } } i j k 1 5 1 1 4 2 1 3 3 1 2 4 4 5 5 4 4 6 4 3 7 4 2 8 7 5 9 7 4 10 7 3 11 7 2 12 10 5 13 10 4 14 10 3 15 10 2 16 Pętle (2) – do ... while do { instrukcje w pętli ... } while (warunek); Wykonuje się dla wartości warunek: prawda Gdy warunek przestaje być prawdziwy – wychodzimy z pętli -------------------------------------------------------------------------------------------Pętla wykona się co najmniej jeden raz! W pętli for warunek (zakresu) był sprawdzany na początku i instrukcje w pętli mogły się nie wykonać ani raz! Pętle (2) – do ... while int i=3; do { instrukcje w pętli ..... cout<<i<<'\n'; ++i; } while (i<10); 3 4 5 6 7 8 9 int i=3; do { instrukcje w pętli ..... cout<<i<<'\n'; ++i; } while (i<1); 3 Pętle (3) – while while (warunek) { instrukcje w pętli ... } Wykonuje się dla wartości warunek: prawda Gdy warunek przestaje być prawdziwy – wychodzimy z pętli -------------------------------------------------------------------------------------------Pętla może się nie wykonać ani jeden raz! W pętli while warunek jest sprawdzany na początku i instrukcje w pętli mogą się w ogóle nie wykonać Pętle (3) – while int i=3; while (i<10) { instrukcje w pętli ..... cout<<i<<'\n'; ++i; } 3 4 5 6 7 8 9 int i=3; while (i<1) { instrukcje w pętli ..... cout<<i<<'\n'; ++i; } (nic) Pętle i tablice int tabl[n]; //tablica n-elementowa unsigned int i; //zmienna sterujaca petlami for (i=0;i<n;++i) // wczytanie elementow tablicy { cout <<"Podaj "<<i+1<<". element tablicy: "; cin >>tabl[i]; } for (i=0;i<n;++i) // dodanie liczby 10 do kazdego elementu tablicy tabl [i]+=10; for (i=0;i<n;++i) // wypisanie elementow tablicy cout <<tabl[i]<<'\n '; Pętle i tablice const int n=26; // rozmiar tablicy z danymi float dane[n]; unsigned int i; //zmienna sterujaca petlami float suma,srednia; // suma wyrazow, petla while i=0; suma=0; while (i<n) { suma+=dane[i]; ++i; } srednia=suma/n; Break – przerwanie pętli Liczymy średnią arytmetyczną wczytanych liczb (max 100). Element równy zero kończy wczytywanie. int i; float a,suma=0,srednia; for (i=0;i<99;++i) { cin>>a; if (a==0) break; suma+=a; } srednia=suma/i; cout<<srednia<<'\n' Jeśli stosujemy zagnieżdżone pętle i użyjemy instrukcji break w pętli najbardziej wewnętrznej, to zostanie przerwana jedynie ta najbardziej wewnętrzna pętla, pozostałe pętle będą się wykonywać. Continue – przerwanie kroku pętli Z przedziału 1..n podajemy liczby podzielne przez 3 for (unsigned int i=0;i<=n;++i) { if ((i%3)!=0) continue; cout <<"Liczba "<<i<<"jest podzielna przez 3\n"; } Program wraca na początek pętli i wykonuje kolejny krok Etykiety i instrukcje skoku goto { instrukcje programu ...... goto NazwaEtykiety2; ....... NazwaEtykiety1: ......... ........ goto NazwaEtykiety1; ....... ....... NazwaEtykiety2: ..... ..... } W miejscu umieszczenia etykiety dwukropek Po instrukcji goto średnik Operator warunkowy wyrażenie1 ? wyrażenie2 : wyrażenie3; Jeżeli wyrażenie1 jest prawdziwe, to wykonuj wyrażenie2 , a jeśli jest fałszywe – wykonuj wyrażenie3 (a<b) ? cout <<"a jest mniejsze" : cout <<"b jest mniejsze"; zastępuje: if (a<b) cout <<"a jest mniejsze"; else cout <<"b jest mniejsze"; Instrukcja wyboru switch switch (wyrażenie) { case wartosc1: Instrukcje1; break; case wartosc2: Instrukcje2; break; ... case wartoscn: InstrukcjeN; break; default: InstrukcjaDomyslna; } Obliczana jest wartość wyrażenia. Jeśli jest równa wartosc1 – wykonywane są instrukcje1, jeśli wynik wynosi wartość2 – wykonywane są instrukcje2 itd. Jeśli wynik wyrażenia nie jest równy żadnemu przypadkowi (case) – wykonywana jest instrukcja domyślna (default)