LEKCJA 10 Jakie operatory stosuje C++. _______________________________________________________________ Podczas tej lekcji: * Poznasz operatory języka C++. * Przetestujesz działanie niektórych operatorów. * Dowiesz się więcej o deklarowaniu i inicjowaniu zmiennych. _______________________________________________________________ Słów kluczowych jest w języku C++ stosunkowo niewiele, za to operatorów wyraĽnie więcej niż np. w Basicu. Z kilku operatorów już korzystałe¶ w swoich programach. pełn± listę operatorów wraz z krótkim wyja¶nieniem przedstawiam poniżej. Operatory C++ s± podzielone na 16 grup i można je scharakteryzować: * priorytetem ** najwyższy priorytet ma grupa 1 a najniższy grupa 16 - przecinek, np. mnożenie ma wyższy priorytet niż dodawanie; ** wewn±trz każdej z 16 grup priorytet operatorów jest równy; * ł±czno¶ci± (wi±zaniem). [S!] Precedence - kolejno¶ć, priorytet. ________________________________________________________________ Dwie cechy opertorów C++ priorytet i ł±czno¶ć decyduj± o sposobie obliczania warto¶ci wyrażeń. Precedence - kolejno¶ć, priorytet. Associativity - asocjatywno¶ć, ł±czno¶ć, wi±zanie. Operator jest ł±czny lewo/prawo-stronnie, je¶li w wyrażeniu zawieraj±cym na tym samym poziomie hierarchii nawiasów min. dwa identyczne operatory najpierw jest wykonywany operator lewy/prawy. Operator jest ł±czny, je¶li kolejno¶ć wykonania nie wpływa na wynik. ________________________________________________________________ Przykład: a+b+c+d = (a+d)+(c+b) [S] ________________________________________________________________ ASSIGN(ment) - Przypisanie. EQAL(ity) - Równy, odpowiadaj±cy. BITWISE - bit po bicie (bitowo). REFERENCE - odwołanie do..., powołanie się na..., wskazanie na... . Funkcje logiczne: OR - LUB - suma logiczna (alternatywa). AND - I - iloczyn logiczny. XOR (eXclusive OR) - ALBO - alternatywa wył±czaj±ca. NOT - NIE - negacja logiczna. ________________________________________________________________ Oznaczenia ł±czno¶ci przyjęte w Tabeli: {L->R} €€€(Left to Right) z lewa na prawo. {L<<-R} €€(Right to Left) z prawa na lewo. Lista operatorów języka C++. ________________________________________________________________ Kategoria€| Operator€€€€€| €€€Co robi / jak działa ----------|--------------|-------------------------------------- 1. Highest| ()€€€€€€€€€€€| * ogranicza wyrażenia, (Najwyższy|Parentheses | * izoluje wyrażenia warunkowe, priorytet)|€€€€€€€€€€€€€€| * wskazuje na wywołanie funkcji, {L->R}€€€|€€€€€€€€€€€€€€| grupuje argumenty funkcji. €€€€€€€€€€|--------------|-------------------------------------- €€€€€€€€€€| []€€€€€€€€€€€| zawarto¶ć jedno- lub wielowymiarowych €€€€€€€€€€|Brackets | tablic €€€€€€€€€€|--------------|-------------------------------------- €€€€€€€€€€| . |(direct component selector) €€€€€€€€€€| -> |(indirect, or pointer, selection) €€€€€€€€€€|€€€€€€€€€€€€€€| Bezpo¶rednie lub po¶rednie wskazanie | | elementu unii b±dĽ struktury. |--------------|-------------------------------------- | :: | Operator specyficzny dla C++. | | Pozwala na dostęp do nazw GLOBALNYCH, | | nawet je¶li zostały "przysłonięte" | | przez LOKALNE. ----------|--------------|-------------------------------------- 2. €€€€€€€| ! €€€€€€€€€€€| Negacja logiczna (NOT) Jednoar-€|--------------|------------------------------------ gumentowe | ~ | Zamiana na kod KOMPLEMENTARNY bit po (Unary) | | bicie. Dotyczy liczb typu int. {L<<-R} |--------------|-------------------------------------- | + | Bez zmiany znaku (Unary plus) |--------------|-------------------------------------- | - | Zmienia znak liczby / wyrażenia | | (Unary minus) |--------------|-------------------------------------- | ++ | PREinkrementacja/POSTinkrementacja |--------------|-------------------------------------- | -- | PRE/POSTdekrementacja |--------------|-------------------------------------- | & | Operator adresu(Referencing operator) |--------------|-------------------------------------- | * | Operator wskazania | | (Dereferencing operator) |--------------|-------------------------------------- | sizeof | Zwraca wielko¶ć argumentu w bajtach |--------------|-------------------------------------- | new | Dynamiczne zarz±dzanie pamięci±: | delete | new - przydziela pamięć, | | delete - likwiduje przydział pamięci ----------|--------------|-------------------------------------- 3. Multi- | * | Mnożenie (UWAGA: Druga rola "*") plikatywne|--------------|-------------------------------------- {L->R} | / | Dzielenie |--------------|-------------------------------------- | % | Reszta z dzielenia (modulo) ----------|--------------|-------------------------------------- 4. Dostępu| .* | Operatory specyficzne dla C++. (Member |(dereference) | Skasowanie bezpo¶redniego wskazania access) | | na członka klasy (Class Member). {L->R} |--------------|-------------------------------------- | ->* | Skasowanie po¶redniego wskazania typu objektowe | | "wskaĽnik do wskaĽnika" ----------|--------------|-------------------------------------- 5. Addy - | + | Dodawanie dwuargumentowe. tywne |--------------|-------------------------------------- {L->R} | - | Odejmowanie dwuargumentowe. ----------|--------------|-------------------------------------- 6. Przesu-| << | Binarne przesunięcie w lewo. nięcia |--------------|-------------------------------------- (Shift) | >> | Binarne przesunięcie w prawo. {L->R} | | (bit po bicie) ----------|--------------|-------------------------------------- 7. Relacji| < | Mniejsze niż... {L->R} |--------------|-------------------------------------- | > | Większe niż.... |--------------|-------------------------------------- | <= | Mniejsze lub równe. |--------------|-------------------------------------- | >= | Większe lub równe. ----------|--------------|-------------------------------------- 8.Równo¶ci| == | Równe (równa się). {L->R} | != | Nie równe. ----------|--------------|-------------------------------------- 9. | & | AND binarnie (Bitwise AND) {L->R} | | UWAGA: Druga rola "&". ----------|--------------|-------------------------------------- 10. | ^ | XOR binarnie (Alternatywa wył±czna). {L->R} | | UWAGA: To nie potęga ! ----------|--------------|------------------------------------- 11.{L->R} | | | OR binarnie (bit po bicie) ----------|--------------|------------------------------------- 12.{L->R} | && | Iloczyn logiczny (Logical AND). ----------|--------------|------------------------------------- 13.{L->R} | || | Suma logiczna (Logical OR). ----------|--------------|-------------------------------------- 14. Oper. | ?: | Zapis a ? x : y oznacza: Warunkowy | | "if a==TRUE then x else y" Conditional | gdzie TRUE to logiczna PRAWDA "1". {L<<-R} | | ----------|--------------|-------------------------------------- 15. Przy- | = | Przypisz warto¶ć (jak := w Pascalu) pisania |--------------|-------------------------------------- {L<<-R} | *= | Przypisz iloczyn. Zapis X*=7 | | oznacza: X=X*7 (o 1 bajt krócej!). |--------------|-------------------------------------- | /= | Przypisz iloraz. |--------------|-------------------------------------- | %= | Przypisz resztę z dzielenia. |--------------|-------------------------------------- | += | Przypisz sumę X+=2 oznacza "X:=X+2" |--------------|-------------------------------------- | -= | Przypisz różnicę X-=5 ozn. "X:=X-5" |--------------|-------------------------------------- | &= | Przypisz iloczyn binarny ( Bitwise | | AND) | | bit po bicie. |--------------|-------------------------------------- | ^= | Przypisz XOR bit po bicie. |--------------|-------------------------------------- | |= | Przypisz sumę log. bit po bicie. |--------------|-------------------------------------- | <<= | Przypisz wynik przesunięcia o jeden | | bit w lewo. |--------------|-------------------------------------- | >>= | j. w. o jeden bit w prawo. ----------|--------------|-------------------------------------- 16. Prze- | , | Oddziela elementy na li¶cie argu - cinek | | mentów funkcji, (Comma) | | Stosowany w specjalnych wyrażeniach {L->R} | | tzw. "Comma Expression". ----------|--------------|------------------------------------- UWAGI: * Operatory # i ## stosuje się tylko w PREPROCESORZE. * Operatory << i >> mog± w C++ przesyłać tekst do obiektów cin i cout dzięki tzw. Overloadingowi (rozbudowie, przeci±żeniu) operatorów. Takiego rozszerzenia ich działania dokonali już programi¶ci producenta w pliku nagłówkowym IOSTREAM.H> Gdyby okazało się, że oferowane przez powyższy zestaw operatory nie wystarczaj± Ci lub niezbyt odpowiadaj±, C++ pozwala na tzw. OVERLOADING, czyli przypisanie operatorom innego, wybranego przez użytkownika działania. Można więc z operatorami robić takie same sztuczki jak z identyfikatorami. S±dzę jednak, że ten zestaw nam wystarczy, w każdym razie na kilka najbliższych lekcji. Podobnie, jak pieni±dze na bezludnej wyspie, niewiele warta jest wiedza, której nie można zastosować praktycznie. PrzejdĽmy więc do czynu i przetestujmy działanie niektórych operatorów w praktyce. TEST OPERATORÓW JEDNOARGUMENTOWYCH. Otwórz plik nowego programu: * Open [F3], * Wpisz: A:\UNARY.CPP * Wybierz klawisz [Open] w okienku lub naci¶nij [Enter]. Wpisz tekst programu: [P017.CPP ] // UNARY.CPP - operatory jednoargumentowe # include # include float x; void main(void) { clrscr(); for(;;) { printf("\n Podaj liczbe...\n"); scanf("%f", &x); printf("\n%f\t%f\t%f\n", x, +x, -x ); printf("\n%f", --x ); printf("\t%f", x ); printf("\t%f", ++x); if(getch() = '.') break; }; } Zwróć uwagę, że po nawiasie zamykaj±cym pętlę nie ma tym razem żadnego rozkazu. Nie wyst±pi także ostrzeżenie (Warning:) przy kompilacji. Uruchom program Run | Run. Popraw ewentualne błędy. Podaj±c różne warto¶ci liczby x: - dodatnie i ujemne, - całkowite i rzeczywiste, przeanalizuj działanie operatorów. Przerwij program naciskaj±c klawisz [.] Zmodyfikuj w programie deklarację typu zmiennej X wpisuj±c kolejno: - float x; (rzeczywista) - int x; €€€€€€(całkowita) - short int x; €€€€€(krótka całkowita) - long int x;€€€€€(długa całkowita) Zwróć uwagę, że zmiana deklaracji zmiennej bez JEDNOCZESNEJ zmiany formatu w funkcjach scanf() i printf() spowoduje komunikaty o błędach. Spróbuj samodzielnie dobrać odpowiednie formaty w funkcjach scanf() i printf(). Spróbuj zastosować zamiast funkcji printf() i scanf() strumienie cin i cout. Pamiętaj o doł±czeniu wła¶ciwych plików nagłówkowych. Je¶li miałe¶ kłopot z dobraniem stosownych formatów, nie przejmuj się. Przyjrzyj się następnym przykładowym programom. Zajmijmy się teraz dokładniej INKREMENTACJˇ, DEKREMENTACJˇ i OPERATORAMI PRZYPISANIA. 1. Zamknij zbędne okna na ekranie. Pamuiętaj o zapisaniu programów na dyskietkę/dysk w tej wersji, która poprawnie działa lub w ostatniej wersji roboczej. 2. Otwórz plik: ASSIGN.CPP 3. Wpisz tekst programu: [P018.CPP] # include # include long int x; short int krok; char klawisz; int main() { clrscr(); printf("Test operatora przypisania += \n"); x=0; printf("Podaj KROK ? \n"); scanf("%d",&krok); for(;;) { printf("\n%d\n", x+=krok); printf("[Enter] - dalej [K] - Koniec\n"); klawisz = getch(); if (klawisz=='k'|| klawisz=='K') goto koniec; } koniec: printf("\n Nacisnij dowolny klawisz..."); getch(); return 0; } W tym programie już sami "ręcznie" sprawdzamy, czy nie pora przerwać pętlę. Zamiast użyć typowej instrukcji break (przerwij) stosujemy nielubiane goto, gdyż jest bardziej uniwersalne i w przeciwieństwie do break pozwala wyraĽnie pokazać dok±d następuje skok po przerwaniu pętli. Zwróć uwagę na nowe elementy w programie: * DEKLARACJE ZMIENNYCH: long int x; (długa, całkowita) short int krok; €€€€(krótka, całkowita) char klawisz;€€€€€(zmienna znakowa) * INSTRUKCJĘ WARUNKOWˇ: if (KLAWISZ=='k'|| KLAWISZ=='K') goto koniec; (JEŻELI zmienna KLAWISZ równa się "k" LUB równa się "K" idĽ do etykiety "koniec:") * Warunek sprawdzany po słowie if jest ujęty w nawiasy. * Nadanie warto¶ci zmiennej znakowej char klawisz przez funkcję: klawisz = getch(); 4. Skompiluj program. Popraw ewentualne błędy. 5. Uruchom program. Podaj±c różne liczby (tylko całkowite!) prze¶ledĽ działanie operatora. 6. Zapisz poprawn± wersję programu na dysk/dyskietkę [F2]. 7. Je¶li masz już do¶ć, wyjdĽ z TC - [Alt]-[X], je¶li nie, pozamykaj tylko zbędne okna i możesz przej¶ć do zadań do samodzielnego rozwi±zania -> [Z]! [Z] ________________________________________________________________ 1. Do programu przykładowego wstaw kolejno różne operatory przypisania: *=, -=, /= itp. Prze¶ledĽ działanie operatorów. 2. W programie przykładowym zmień typ zmiennych: long int x; na float x; short int KROK; float KROK; Przetestuj działanie operatorów w przypadku liczb zmiennoprzecinkowych. 3. Zapisz w języku C++ * negację iloczynu logicznego, * sumę logiczn± negacji dwu warunków. ________________________________________________________________ TEST OPERATORÓW PRE/POST-INKREMENTACJI. W następnym programie zilustrujemy działanie wszystkich pięciu operatorów inkrementacji (dekrementacja to też inkrementacja tylko w przeciwn± stronę). [P019.CPP] # include # include int b,c,d,e; int i; int STO = 100; void main(void) { clrscr(); printf("Demonstruje dzialanie \n"); printf(" PREinkrementacji POSTinkrementacji"); printf("\nNr€€€€--X€€€€€€++X€€€€€€€€€€€€X--€€€€€€€X++ \n"); b = c = d = e = STO; for(i=1; i<6; i++) { printf("%d\t%d\t%d\t\t%d\t%d\t\n", i,--b,++c,d--,e++); } getch(); } [S!] PRE / POSTINKREMENTACJA. ________________________________________________________________ INKREMENTACJA oznacza zwiększenie liczby o jeden, DEKREMENTACJA oznacza zmniejszenie liczby o jeden. PRE oznacza wykonanie in/de-krementacji przed użyciem zmiennej, POST - in/de-krementację po użyciu zmiennej. ________________________________________________________________ Działanie możesz prze¶ledzić na wydruku, który powinien Ci dać program przykładowy INDEKREM.CPP: Demonstruje dzialanie PREinkrementacji POSTinkrementacji Nr€€€€--X€€€€€€++X€€€€€€€€€€€€X--€€€€€€€X++ 1 99 101 100 100 2 98 102 99 101 3 97 103 98 102 4 96 104 97 103 5 95 105 96 104 JAK KORZYSTAĆ Z DEBUGGERA? Uruchom program powtórnie naciskaj±c klawisz [F7]. Odpowiada to poleceniu Trace into (wł±cz ¶ledzenie) z menu Run. Prze¶ledzimy działanie programu przy pomocy Debuggera. Po wykonaniu kompilacji (lub odst±pieniu od kompilacji, je¶li nie dokonałe¶ zmian w programie) pojawił się na ekranie pasek wyróżnienia wokół funkcji main(), bo to od niej rozpoczyna się zawsze wykonanie programu. Naci¶nij powtórnie [F7]. Pasek przesun±ł się na funkcję clrscr();. Mign±ł na chwilę ekran użytkownika, ale na razie nie ma po co tam zagl±dać, więc wykonamy kolejne kroki. Podam klejno: [Klawisz]-[wiersz]. [F7] - printf("Demonstruję..."); Zagl±damy na ekran użytkownika [Alt]-[F5].....[Enter] - wracamy do edytora. [F7],[F7]... doszli¶my do wiersza b=c=d=e=STO; Zapraszamy teraz debugger do pracy wydaj±c mu polecenie "Wykonaj Inspekcję" [Alt]-[D] | Inspect. Pojawia się okienko dialogowe "Inspect". * Wpisz do okienka tekstowego nazwę zmiennej b i naci¶nij [Enter]. Pojawiło się okienko dialogowe "Inspecting b" zawieraj±ce fizyczny adres pamięci RAM, pod którym umieszczono zmienn± b i warto¶ć zmiennej b (zero; instrukcja przypisania nada jej warto¶ć 100). Naci¶nij [Esc]. Okienko zniknęło. [F7] - for(i=1; i<6; i++); * NaprowadĽ kursor na zmienn± d w tek¶cie programu i wykonaj inspekcję powtórnie [Alt]-[D], [I]. Jak widzisz w okienku zmiennej d została nadana warto¶ć 100. Naci¶nij [Esc]. Dokonamy teraz modyfikacji warto¶ci zmiennej przy pomocy polecenia Evaluate and Modify (sprawdĽ i zmodyfikuj) z menu Debug. * Naci¶nij klawisze [Alt]-[D], [E]. Pojawiło się okienko dialogowe "Evaluate and Modify". W okienku tekstowym "Expression" (wyrażenie) widzisz swoj± zmienn± d. * PrzejdĽ przy pomocy [Tab] do okienka tekstowego "New Value" (nowa warto¶ć) i wpisz tam liczbę 1000. Naci¶nij [Enter] a następnie [Esc]. Okienko zamknęło się. Zmiana warto¶ci zmiennej została dokonana. [F7] - printf("...") - wnętrze pętli for. [F7] - wykonała się pętla. Obejrzyjmy wyniki [Alt]-[F5]. W czwartej kolumnie widzisz efekt wprowadzonej zmiany: Demonstruje dzialanie PREinkrementacji POSTinkrementacji Nr€€€€--X€€€€€€++X€€€€€€€€€€€€X--€€€€€€€X++ 1 99 101 1000 100 2 98 102 999 101 3 97 103 998 102 4 96 104 997 103 5 95 105 996 104 Zwróć uwagę w programie przykładowym na: * Zliczanie ilo¶ci wykonanych przez program pętli. int i; (deklaracja, że i będzie zmienn± całkowit±) ... i=1; (zainicjowanie zmiennej, nadanie pocz±tkowej warto¶ci) ... i++; (powiększanie i o 1 w każdej pętli) ... i<6 (warunek kontynuacji) * Możliwo¶ć grupowej deklaracji zmiennych tego samego typu: int b,c,d,e; [Z] ________________________________________________________________ 4. Zmień w programie przykładowym warto¶ć pocz±tkow± STO na dowoln± inn± - np. zero. Przetestuj działanie programu. 5. SprawdĽ, czy można wszystkie zmienne używane w programie przykładowym zadeklarować wspólnie (jeden wiersz zamiast trzech). ________________________________________________________________