Java. Ćwiczenia praktyczne. Wydanie III
Transkrypt
Java. Ćwiczenia praktyczne. Wydanie III
Idź do • Spis treści • Przykładowy rozdział Katalog książek Java. Ćwiczenia praktyczne. Wydanie III Autor: Marcin Lis ISBN: 978-83-246-2785-1 Format: A5, stron: 224 • Katalog online • Zamów drukowany katalog Obudź się! Czas na Javę! Twój koszyk • Dodaj do koszyka Cennik i informacje • Zamów informacje o nowościach • Zamów cennik Czytelnia • Fragmenty książek online Kontakt Helion SA ul. Kościuszki 1c 44-100 Gliwice tel. 32 230 98 63 e-mail: [email protected] © Helion 1991–2011 • Poznaj podstawowe zasady programowania • Dowiedz się, jak tworzyć aplikacje i aplety • Opanuj podstawy tworzenia programów z graficznym interfejsem Java, jeden z najpopularniejszych dziś obiektowych języków programowania, ma całe mnóstwo zalet. Jest funkcjonalna, świetnie skonstruowana i łatwa do zastosowania przy programowaniu różnego typu urządzeń. Te cechy sprawiają, że wielu programistów nie wyobraża sobie codziennej pracy bez używania tego języka – przy tworzeniu apletów na strony WWW, programów działających w telefonach komórkowych czy rozbudowanych aplikacji dla komputerów osobistych i serwerów. Java na dobre zadomowiła się w globalnej sieci, więc najwyższy czas poznać chociaż jej podstawy! Z książką „Java. Ćwiczenia praktyczne” nie będzie to wcale takie trudne. Znajdziesz tu najważniejsze informacje o tym języku i niezbędnych narzędziach, omówienie zmiennych, operatorów i funkcji oraz wyjaśnienie zastosowania tablic. Dowiesz się, na czym polega programowanie obiektowe, do czego służą obiekty i klasy, jak zapewnić obsługę błędów i wyjątków oraz jak wykonywać operacje wejścia-wyjścia. Nauczysz się odróżniać aplet od aplikacji, zapewnisz interakcję programu z użytkownikiem i stworzysz aplikacje z interfejsem graficznym. Każde z tych zagadnień będziesz mógł od razu przećwiczyć, a ćwiczenia te zagwarantują Ci dogłębne, praktyczne zrozumienie działania poszczególnych fragmentów kodu. • Programowanie w Javie • Zmienne, operatory i instrukcje • Tablice • Obiekty i klasy • Obsługa błędów i wyjątki • Operacje wejścia-wyjścia • Aplety • Interakcja z użytkownikiem • Aplikacje z interfejsem graficznym • Grafika i komponenty Java – na pewno Ci się spodoba! Spis treci Wstp Rozdzia 1. Krótkie wprowadzenie Instalacja JDK Instalacja w systemie Linux Instalacja w systemie Windows Tryb tekstowy Pierwszy program B-kod, kompilacja i maszyna wirtualna Java a C++ Obiektowy jzyk programowania Struktura programu Rozdzia 2. Zmienne, operatory i instrukcje Zmienne Typy podstawowe Deklarowanie zmiennych typów podstawowych Typy odnonikowe Deklarowanie zmiennych typów odnonikowych Operatory Operatory arytmetyczne Operatory bitowe Operatory logiczne Operatory przypisania Operatory porównania (relacyjne) Operator warunkowy Priorytety operatorów 7 11 11 11 13 13 14 16 17 17 18 21 21 21 23 26 27 30 30 36 38 39 39 40 41 4 Java • wiczenia praktyczne Instrukcje Instrukcja warunkowa if…else Instrukcja wyboru switch Ptla for Ptla while Ptla do…while Ptla foreach Rozdzia 3. Tablice Tworzenie tablic Zapis i odczyt elementów Operacje z uyciem ptli Rozmiar tablicy Rozdzia 4. Obiekty i klasy Metody Konstruktory Specyfikatory dostpu Pakiety i typy klas Dziedziczenie Rozdzia 5. Obsuga bdów i wyjtki Bdy w programach Instrukcja try…catch Zgaszanie wyjtków Hierarchia wyjtków Rozdzia 6. Operacje wejcia-wyjcia Wywietlanie danych na ekranie Wczytywanie danych z klawiatury Nowe sposoby wprowadzania danych Obsuga konsoli Operacje na plikach Rozdzia 7. Aplety Aplikacja a aplet Pierwszy aplet Jak to dziaa? Cykl ycia apletu Kroje pisma (fonty) Rysowanie grafiki Kolory Wywietlanie obrazów 42 42 47 49 54 56 57 59 59 62 64 69 73 75 84 90 97 98 105 105 110 113 115 117 117 120 128 131 137 145 145 146 148 150 150 153 160 164 Spis treci Rozdzia 8. Interakcja z uytkownikiem 5 171 Obsuga myszy Rysowanie figur (I) Rysowanie figur (II) Rysowanie figur (III) 171 175 180 182 Rozdzia 9. Aplikacje z interfejsem graficznym 187 Tworzenie okna aplikacji Budowanie menu Wielopoziomowe menu Okna dialogowe Rozdzia 10. Grafika i komponenty Rysowanie elementów graficznych Obsuga komponentów Przyciski JButton Pola tekstowe JTextField Pola tekstowe JTextArea Etykiety JLabel Pola wyboru JCheckBox Listy rozwijane JComboBox „Prawdziwa” aplikacja 187 191 197 200 205 205 206 207 209 211 214 216 218 220 2 Zmienne, operatory i instrukcje Zmienne Zmienna jest to miejsce, w którym moemy przechowywa jakie dane, np. liczby czy cigi znaków. Kada zmienna musi mie swoj nazw, która j jednoznacznie identyfikuje, a take typ, który informuje o tym, jakiego rodzaju dane mona w niej przechowywa. Np. zmienna typu int przechowuje liczby cakowite, a zmienna typu float — liczby zmiennoprzecinkowe. Typy w Javie dziel si na dwa rodzaje: typy podstawowe (ang. primitive types) oraz typy odnonikowe (ang. reference types). Typy podstawowe Typy podstawowe dziel si na: 1. typy cakowitoliczbowe (z ang. integral types), 2. typy zmiennopozycyjne (rzeczywiste, z ang. floating-point types), 3. typ boolean, 4. typ char. 22 Java • wiczenia praktyczne Typy cakowitoliczbowe Rodzina typów cakowitoliczbowych skada si z czterech typów: 1. byte, 2. short, 3. int, 4. long. W przeciwiestwie do innych jzyków, takich jak C++, szczegóowo okrelono sposób reprezentacji tych danych. Niezalenie wic od tego, w jakim systemie pracujemy (16-, 32- czy 64-bitowym), dokadnie wiadomo, na ilu bitach zapisana jest zmienna danego typu. Wiadomo te, z jakiego zakresu wartoci moe ona przyjmowa, nie ma wic dowolnoci, która w przypadku np. jzyka C moga prowadzi do trudnoci przy przenoszeniu programów midzy rónymi platformami. W tabeli 2.1 zaprezentowano zakresy poszczególnych typów danych oraz liczb bitów niezbdn do zapisania zmiennych danego typu. Tabela 2.1. Zakresy dla typów arytmetycznych w Javie Typ Liczba bitów Liczba bajtów Zakres byte 8 1 od –128 do 127 short 16 2 od –32 768 do 32 767 int 32 4 od –2 147 483 648 do 2 147 483 647 long 64 8 od –9 223 372 036 854 775 808 do 9 223 372 036 854 775 807 Typy zmiennoprzecinkowe Typy zmiennoprzecinkowe wystpuj tylko w dwóch odmianach: 1. float (pojedynczej precyzji), 2. double (podwójnej precyzji). Zakres oraz liczb bitów i bajtów potrzebnych do zapisu tych zmiennych zaprezentowano w tabeli 2.2. Rozdzia 2. • Zmienne, operatory i instrukcje 23 Tabela 2.2. Zakresy dla typów zmiennoprzecinkowych w Javie Typ Liczba bitów Liczba bajtów Zakres float 32 4 od –3,4e38 do 3,4e38 double 64 8 od –1,8e308 do 1,8e308 Format danych float i double jest zgodny ze specyfikacj standardu ANSI/IEEE 754. Zapis 3,4e38 oznacza 3,4·1038. Typ boolean Jest to typ logiczny. Moe on reprezentowa jedynie dwie wartoci: true (prawda) i false (fasz). Moe by wykorzystywany przy sprawdzaniu rónych warunków w instrukcjach if, a take w ptlach i innych konstrukcjach programistycznych, które zostan przedstawione w dalszej czci rozdziau. Typ char Typ char suy do reprezentacji znaków (liter, znaków przestankowych, ogólnie wszelkich znaków alfanumerycznych), przy czym w Javie jest on 16-bitowy i zawiera znaki Unicode. Poniewa znaki s reprezentowane tak naprawd jako 16-bitowe kody liczbowe, typ ten zalicza si czasem do typów arytmetycznych. Deklarowanie zmiennych typów podstawowych Aby móc uy jakiej zmiennej w programie, najpierw trzeba j zadeklarowa, tzn. poda jej typ oraz nazw. Ogólna deklaracja wyglda nastpujco: typ_zmiennej nazwa_zmiennej; Po takiej deklaracji zmienna jest ju gotowa do uycia, tzn. mona jej przypisywa róne wartoci bd te wykonywa na niej róne operacje, np. dodawanie. Przypisanie wartoci zmiennej odbywa si przy uyciu znaku (operatora) =. Pierwsze przypisanie wartoci zmiennej nazywamy inicjacj zmiennej lub inicjalizacj zmiennej. 24 Java • wiczenia praktyczne W I C Z E N I E 2.1 Deklarowanie zmiennych Zadeklaruj dwie zmienne cakowite i przypisz im dowolne wartoci. Wyniki wywietl na ekranie. class Main { public static void main (String args[]) { int pierwszaLiczba; int drugaLiczba; pierwszaLiczba = 10; drugaLiczba = 20; System.out.println ("pierwsza liczba: " + pierwszaLiczba); System.out.println ("druga liczba: " + drugaLiczba); } } Zostay tu zadeklarowane dwie zmienne typu int (umoliwiajce przechowywanie liczb cakowitych): pierwszaLiczba i drugaLiczba. Nastpnie przypisano im dwie wartoci cakowite: 10 i 20. Na zakoczenie zostaa uyta instrukcja1 System.out.println, która pozwala wyprowadzi cig znaków na ekran (cigi znaków ujte w cudzysowy zostay poczone za pomoc operatora + z wartociami zmiennych). Po skompilowaniu i uruchomieniu takiego programu zobaczymy wic na ekranie widok przedstawiony na rysunku 2.1. Rysunek 2.1. Wynik dziaania programu z wiczenia 2.1 Warto zmiennej mona równie przypisa ju w trakcie deklaracji, piszc: typ_zmiennej nazwa_zmiennej = warto; 1 W rzeczywistoci jest to wywoanie statycznej metody println. Ten temat zostanie poruszony w dalszej czci ksiki. Rozdzia 2. • Zmienne, operatory i instrukcje 25 Mona równie zadeklarowa wiele zmiennych danego typu, oddzielajc ich nazwy przecinkami. Cz z nich moe by te od razu zainicjowana: typ_zmiennej nazwa1, nazwa2, nazwa3; typ_zmiennej nazwa1 = warto1, nazwa2, nazwa3 = warto2; Zmienne w Javie, podobnie jak w C czy C++, ale inaczej ni w Pascalu, mona deklarowa wedle potrzeb w dowolnym miejscu programu2. W I C Z E N I E 2.2 Jednoczesna deklaracja i inicjacja zmiennych Zadeklaruj i jednoczenie zainicjuj dwie zmienne typu cakowitego. Wynik wywietl na ekranie. class Main { public static void main (String args[]) { int pierwszaLiczba = 10; int drugaLiczba = 20; System.out.println ("pierwsza liczba: " + pierwszaLiczba); System.out.println ("druga liczba: " + drugaLiczba); } } W I C Z E N I E 2.3 Deklarowanie zmiennych w jednym wierszu Zadeklaruj kilka zmiennych typu cakowitego w jednym wierszu. Niektóre z nich zainicjuj. class Main { public static void main (String args[]) { int pierwszaLiczba = 10, drugaLiczba = 20, i, j, k; System.out.println ("pierwsza liczba: " + pierwszaLiczba); System.out.println ("druga liczba: " + drugaLiczba); } } 2 Oczywicie w dowolnym miejscu, w którym ze wzgldów skadniowych deklaracja jest dopuszczalna. 26 Java • wiczenia praktyczne Przy nazywaniu zmiennych obowizuj pewne zasady. Otó nazwa moe si skada z wielkich i maych liter oraz cyfr, ale nie moe si zaczyna od cyfry. Mona przy tym uywa polskich znaków (a take innych liter spoza alfabetu aciskiego), cho czsto s one pomijane. Nazwa zmiennej powinna take odzwierciedla funkcj penion w programie. Jeeli na przykad okrela ona liczb punktów w jakim zbiorze, to najlepiej nazwa j liczbaPunktow lub nawet liczbaPunktowWZbiorze (poprawne bd te nazwy liczbaPunktów i liczbaPunktówWZbiorze). Mimo e tak duga nazwa moe wydawa si dziwna, jednak bardzo poprawia czytelno programu oraz uatwia jego analiz. Naprawd warto ten sposób stosowa. Z reguy przyjmuje si te, co równie jest bardzo wygodne, e nazw zmiennej rozpoczynamy ma liter, a poszczególne czony tej nazwy (wyrazy, które si na ni skadaj) wielk liter — dokadnie tak jak w powyszych przykadach3. Typy odnonikowe Typy odnonikowe (ang. reference types) moemy podzieli na dwa umowne rodzaje: 1. typy klasowe (ang. class types)4, 2. typy tablicowe (ang. array types). Zacznijmy od typów tablicowych. Tablice s to wektory elementów danego typu i su do uporzdkowanego przechowywania wartoci tego typu. Mog by jedno- bd wielowymiarowe. Dostp do danego elementu tablicy jest realizowany przez podanie jego indeksu, czyli miejsca w tablicy, w którym si on znajduje. Dla tablicy jednowymiarowej bdzie to po prostu kolejny numer elementu, dla tablicy dwuwymiarowej trzeba ju poda numer wiersza i kolumny itd. Jeli chcemy zatem przechowa w programie 10 liczb cakowitych, najwygodniej bdzie uy w tym celu 10-elementowej tablicy typu int. Typy klasowe pozwalaj na tworzenie klas i deklarowanie zmiennych obiektowych. Zajmiemy si nimi w rozdziale 3. 3 Jest to zatem standard Lower Camel Case. Nie jest to jednak zapis obligatoryjny, mona oczywicie stosowa inne standardy. 4 Typy klasowe moglibymy podzieli z kolei na obiektowe i interfejsowe; s to jednak rozwaania, którymi nie bdziemy si w niniejszej publikacji zajmowa. Rozdzia 2. • Zmienne, operatory i instrukcje 27 Deklarowanie zmiennych typów odnonikowych Zmienne typów odnonikowych deklarujemy podobnie jak w przypadku zmiennych typów podstawowych, tzn. piszc: typ_zmiennej nazwa_zmiennej; lub: typ_zmiennej nazwa_zmiennej_1, nazwa_zmiennej_2, nazwa_zmiennej_3; Stosujc taki zapis, inaczej ni w przypadku typów prostych, zadeklarowalimy jednak jedynie tzw. odniesienie (ang. reference) do obiektu, a nie sam byt jakim jest obiekt! Takiemu odniesieniu jest domylnie przypisana warto pusta (null), czyli praktycznie nie moemy wykonywa na nim adnej operacji. Dopiero po utworzeniu odpowiedniego obiektu w pamici moemy powiza go z tak zadeklarowan zmienn. Jeli zatem napiszemy np.: int a; bdziemy mieli gotow do uycia zmienn typu cakowitego. Moemy jej przypisa np. warto 10. eby jednak móc skorzysta z tablicy, musimy zadeklarowa zmienn odnonikow typu tablicowego, utworzy obiekt tablicy i powiza go ze zmienn. Dopiero wtedy bdziemy mogli swobodnie odwoywa si do kolejnych elementów. Piszc zatem: int tablica[]; zadeklarujemy odniesienie do tablicy, która bdzie moga zawiera elementy typu int, czyli 32-bitowe liczby cakowite. Samej tablicy jednak jeszcze wcale nie ma. Przekonamy si o tym, wykonujc kolejne wiczenia. W I C Z E N I E 2.4 Deklarowanie tablicy Zadeklaruj tablic elementów typu cakowitego. Przypisz zerowemu elementowi tablicy dowoln warto. Spróbuj skompilowa i uruchomi program. class Main { public static void main (String args[]) { int tablica[]; tablica[0] = 11; 28 Java • wiczenia praktyczne System.out.println ("Zerowy element tablicy to: " + tablica[0]); } } Ju przy próbie kompilacji kompilator wypisze na ekranie tekst: variable tablica might not have been initialized, informujcy nas, e chcemy odwoa si do zmiennej, która prawdopodobnie nie zostaa zainicjalizowana (rysunek 2.2). Widzimy te wyranie, e w razie wystpienia bdu na etapie kompilacji otrzymujemy kilka wanych i pomocnych informacji. Przede wszystkim jest to nazwa pliku, w którym wystpi bd (to wane, gdy program moe skada si z bardzo wielu plików), numer wiersza w tym pliku oraz konkretne miejsce wystpienia bdu. Na samym kocu kompilator podaje te cakowit liczb bdów. Rysunek 2.2. Bd kompilacji. Nie zainicjowalimy zmiennej tablica Skoro jednak wystpi bd, naley go natychmiast naprawi. W tym przypadku oznacza to utworzenie tablicy i przypisanie jej zmiennej tablica. W I C Z E N I E 2.5 Deklaracja i utworzenie tablicy Zadeklaruj i utwórz tablic elementów typu cakowitego. Przypisz zerowemu elementowi tablicy dowoln warto. Spróbuj wywietli zawarto tego elementu na ekranie. class Main { public static void main (String args[]) { int tablica[] = new int[10]; tablica[0] = 11; System.out.println ("Zerowy element tablicy to: " + tablica[0]); } } Rozdzia 2. • Zmienne, operatory i instrukcje 29 Wyraenie new int[10] oznacza utworzenie nowej, jednowymiarowej tablicy liczb typu int o rozmiarze 10 elementów. Ta nowa tablica zostaa przypisana zmiennej odnonikowej o nazwie tablica. Po takim przypisaniu moemy odwoywa si do kolejnych elementów tej tablicy, piszc: tablica[index] Zapis tablica[0] = 11; oznacza wic: przypisz warto 11 elementowi tablicy o indeksie 0. Warto zwróci szczególn uwag, e elementy tablicy s numerowane od zera, a nie od 1. Oznacza to, i pierwszy element tablicy 10-elementowej ma indeks 0, a ostatni 9 (a nie 10!). Co si jednak stanie, jeli — nieprzyzwyczajeni do takiego sposobu indeksowania — odwoamy si do indeksu o numerze 10? Sprawdmy to, wykonujc wiczenie 2.6. W I C Z E N I E 2.6 Odwoanie do nieistniejcego indeksu tablicy Zadeklaruj i zainicjalizuj tablic 10-elementow. Spróbuj przypisa elementowi o indeksie 10 dowoln liczb cakowit. class Main { public static void main (String args[]) { int tablica[] = new int[10]; tablica[10] = 11; System.out.println ("Dziesity element tablicy to: " + tablica[10]); } } Efekt dziaania kodu jest widoczny na rysunku 2.3. Wbrew pozorom nie stao si jednak nic strasznego. Wystpi bd, zosta on jednak obsuony przez maszyn wirtualn Javy. Konkretnie zosta wygenerowany tzw. wyjtek i program standardowo zakoczy dziaanie. Taki wyjtek moemy jednak przechwyci i tym samym zapobiec niekontrolowanemu zakoczeniu aplikacji. Jest to jednak odrbny, aczkolwiek bardzo wany temat; zajmiemy si nim nieco póniej. Godne uwagi jest to, e próba odwoania si do nieistniejcego elementu zostaa wykryta i to odwoanie tak naprawd nie wystpio! Program nie naruszy wic niezarezerwowanego dla niego obszaru pamici. 30 Java • wiczenia praktyczne Rysunek 2.3. Próba odwoania si do nieistniejcego elementu tablicy Operatory Poznalimy ju zmienne, musimy jednak wiedzie, jakie operacje moemy na nich wykonywa. Operacje wykonujemy za pomoc rónych operatorów, np. odejmowania, dodawania, przypisania itd. Podstawowe operatory moemy podzieli na nastpujce grupy5: 1. arytmetyczne, 2. bitowe, 3. logiczne, 4. przypisania, 5. porównania. Operatory arytmetyczne Wród tych operatorów znajdziemy standardowo dziaajce: 1. + — dodawanie, 2. – — odejmowanie, 3. * — mnoenie, 4. / — dzielenie. 5 Mona wydzieli równie inne grupy, co wykracza jednak poza ramy tematyczne niniejszej publikacji. Rozdzia 2. • Zmienne, operatory i instrukcje 31 W I C Z E N I E 2.7 Operacje arytmetyczne na zmiennych Zadeklaruj dwie zmienne typu cakowitego. Wykonaj na nich kilka operacji arytmetycznych. Wyniki wywietl na ekranie. class Main { public static void main(String args[]) { int a, b, c; a = 10; b = 25; c = b - a; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("b - a = " + c); c = a * b; System.out.println("a * b = " + c); } } Najpierw zostay zadeklarowane trzy zmienne typu int: a, b i c. Dwie pierwsze otrzymay wartoci liczbowe (10 i 25), natomiast trzecia — warto wynikajc z odejmowania b – a (bdzie to zatem 15). Nastpnie wartoci zmiennych zostay wywietlone na ekranie. W kolejnym kroku zmienna c otrzymaa now warto wynikajc z mnoenia a * b i ta warto (250) równie zostaa wywietlona. Do operatorów arytmetycznych naley równie znak %, przy czym nie oznacza on obliczania procentów, ale dzielenie modulo (reszt z dzielenia). Np. wynik dziaania 12 % 5 wynosi 2, pitka mieci si bowiem w dwunastu 2 razy, pozostawiajc reszt 2 (5 2 = 10, 10 + 2 = 12). W I C Z E N I E 2.8 Dzielenie modulo Zadeklaruj kilka zmiennych. Wykonaj na nich operacje dzielenia modulo. Wyniki wywietl na ekranie. class Main { public static void main(String args[]) { int a, b, c; a = 10; b = 25; c = b % a; 32 Java • wiczenia praktyczne System.out.println("b % a = " + c); System.out.println("a % 3 = " + a % 3); c = a * b; System.out.println("(a * b) % 120 = " + c % 120); } } Pierwsza cz kodu jest tu taka sama jak w wiczeniu 2.8. Zmiennej c zostaa jednak przypisana warto dzielenia modulo b % a. Tym samym pierwsz jej wartoci bdzie 5 (25 % 10 = 5, bo 2 * 10 = 20, 20 + 5 = 25). Wynik tego dziaania (warto zmiennej c) zosta wywietlony za pomoc znanej nam konstrukcji System.out.println. W kolejnej instrukcji na ekran zostaa wyprowadzona warto dziaania a % 3, czyli 1 (10 % 3 = 1, bo 3 * 3 = 9, 9 + 1 = 10). Nastpnie zmiennej c przypisano warto mnoenia a * b (tak samo jak w wiczeniu 2.7), a na ekran zosta wyprowadzony wynik dziaania c % 20 (czyli (a * b) % 120). Wynik tego dziaania to 10 (c = 250, 250 % 120 = 10, bo 2 * 120 = 240, 240 + 10 = 250). Kolejne operatory typu arytmetycznego to operator inkrementacji i dekrementacji. Operator inkrementacji (czyli zwikszania), którego symbolem jest ++, powoduje przyrost wartoci zmiennej o jeden. Moe wystpowa w formie przyrostkowej bd przedrostkowej. Oznacza to, e jeli mamy zmienn, która nazywa si np. x, forma przedrostkowa bdzie wyglda: ++x, natomiast przyrostkowa: x++. Oba te wyraenia zwiksz warto zmiennej x o jeden, jednak nie s one równowane. Otó operacja x++ zwiksza warto zmiennej po jej wykorzystaniu, natomiast ++x przed jej wykorzystaniem. Czasem takie rozrónienie jest bardzo pomocne przy pisaniu programu. W I C Z E N I E 2.9 Operator inkrementacji Przeanalizuj poniszy kod. Nie uruchamiaj programu, ale zastanów si, jaki cig liczb bdzie wywietlony. Nastpnie, po uruchomieniu kodu, sprawd swoje przypuszczenia. class Main { public static void main (String args[]) { /*1*/ int x = 1, y; /*2*/ System.out.println (++x); /*3*/ System.out.println (x++); Rozdzia 2. • Zmienne, operatory i instrukcje /*4*/ /*5*/ /*6*/ /*7*/ /*8*/ 33 System.out.println (x); y = x++; System.out.println (y); y = ++x; System.out.println (++y); } } Dla uatwienia poszczególne wiersze w programie zostay oznaczone kolejnymi liczbami (w tym celu uyto komentarzy blokowych przedstawionych w rozdziale 1.). Wynikiem dziaania tego programu bdzie cig liczb 2, 2, 3, 3, 6. Dlaczego? Na pocztku zmienna x przyjmuje warto 1. W drugim wierszu metody main wystpuje operator ++x, zatem najpierw jest ona zwikszana o jeden (x = 2), a dopiero potem wywietlana na ekranie. W wierszu o numerze 3 jest odwrotnie. Najpierw warto zmiennej x jest wywietlana (x = 2), a dopiero potem zwikszana o 1 (x = 3). W wierszu czwartym po prostu wywietlamy warto x (x = 3). W wierszu pitym najpierw zmiennej y jest przypisywana dotychczasowa warto x (x = 3, y = 3), a nastpnie warto x jest zwikszana o jeden (x = 4). W wierszu szóstym wywietlamy warto y (y = 3). W wierszu siódmym najpierw zwikszamy warto x o jeden (x = 5), a póniej przypisujemy t warto zmiennej y. W wierszu ostatnim, ósmym, zwikszamy y o jeden (y = 6) i wywietlamy na ekranie. Operator dekrementacji (--) dziaa analogicznie, z tym e zamiast zwiksza wartoci zmiennych, zmniejsza je, oczywicie zawsze o jeden. W I C Z E N I E 2.10 Operator dekrementacji Zmie kod z wiczenia 2.9 tak, aby operator ++ zosta zastpiony operatorem --. Nastpnie przeanalizuj jego dziaanie i sprawd, czy otrzymany wynik jest taki sam, jak otrzymany na ekranie po uruchomieniu kodu. class Main { public static void main (String args[]) { /*1*/ int x = 1, y; /*2*/ System.out.println (--x); /*3*/ System.out.println (x--); 34 Java • wiczenia praktyczne /*4*/ /*5*/ /*6*/ /*7*/ /*8*/ System.out.println (x); y = x--; System.out.println (y); y = --x; System.out.println (--y); } } Kod dziaa tu analogicznie do przedstawionego w wiczeniu 2.9, z t rónic, e warto zmiennych jest zmniejszana. W zwizku z tym po uruchomieniu programu zostanie uzyskany cig liczb: 0, 0, -1, -1, -4. Dziaania operatorów arytmetycznych na liczbach cakowitych nie trzeba chyba wyjania, moe z dwoma wyjtkami. Otó co si stanie, jeeli wynik dzielenia dwóch liczb cakowitych nie bdzie liczb cakowit? Odpowied na szczcie jest prosta — wynik zostanie zaokrglony w dó (zostanie utracona cz uamkowa wyniku). Zatem wynikiem dziaania 7 / 2 w arytmetyce liczb cakowitych bdzie 3 („prawdziwym” wynikiem jest oczywicie 3,5, która to warto zostaje zaokrglona w dó do najbliszej liczby cakowitej, czyli trzech). W I C Z E N I E 2.11 Dzielenie liczb cakowitych Wykonaj dzielenie zmiennych typu cakowitego. Sprawd rezultaty w sytuacji, gdy rzeczywisty wynik jest uamkiem. class Main { public static void main(String args[]) int a = 8, b = 3, c = 2; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("c = " + c); System.out.println("a / b = " + a / System.out.println("a / c = " + a / System.out.println("b / c = " + b / } } { b); c); c); Zostay zadeklarowane i jednoczenie zainicjowane trzy zmienne typu int, a ich wartoci wypisane na ekranie: a = 8, b = 3 i c = 2. Nastpnie zostay wywietlone wyniki dzielenia cakowitoliczbowego a / b, czyli 2 („prawdziwym” wynikiem jest 2 i dwie trzecie), a / c, czyli 4, i b / c, czyli 1 („prawdziwym” wynikiem jest 1,5). Rozdzia 2. • Zmienne, operatory i instrukcje 35 Drugim problemem jest to, co si stanie, jeeli przekroczymy zakres jakiej zmiennej. Pamitamy np., e zmienna typu byte jest zapisywana na 8 bitach i moe przyjmowa wartoci od –128 do 127 (patrz tabela 2.1). Spróbujmy zatem przypisa zmiennej tego typu warto 128. W I C Z E N I E 2.13 Przekroczenie zakresu w trakcie kompilacji Zadeklaruj zmienn typu byte. Przypisz jej warto 128. Spróbuj dokona kompilacji otrzymanego kodu. class Main { public static void main (String args[]) { byte zmienna; zmienna = 128; System.out.println(zmienna); } } Próbujc wykona kompilacj kodu z wiczenia, szybko przekonamy si, e nie bdzie to moliwe. Kompilator nie dopuci do przypisania zmiennej wartoci wykraczajcej poza zakres jej typu. Zobaczymy zatem komunikat o bdzie przedstawiony na rysunku 2.4. Rysunek 2.4. Próba przekroczenia dopuszczalnej wartoci zmiennej Niestety, kompilator nie zawsze bdzie w stanie wykry tego typu bd. Moe si bowiem zdarzy, e zakres przekroczymy w trakcie wykonywania programu. Co wtedy? 36 Java • wiczenia praktyczne W I C Z E N I E 2.13 Przekroczenie zakresu w trakcie dziaania kodu Zadeklaruj zmienne typu long. Wykonaj operacje arytmetyczne przekraczajce dopuszczaln warto takiej zmiennej. Wynik wywietl na ekranie. class Main { public static void main (String args[]) { int a, b = (int) Math.pow(2, 32) + 1; a = b + b; System.out.println ("a = " + a); } } Operacja (int) Math.pow(2, 32) oznacza podniesienie liczby 2 do potgi 32., a nastpnie skonwertowanie wyniku (który jest liczb typu double) do typu int. Zmiennej a jest przypisywany wynik dziaania b + b i okazuje si, e jest to 0. Dlaczego? Otó jeeli jaka warto przekracza dopuszczalny zakres swojego typu, jest „zawijana” do pocztku tego zakresu. Obrazowo ilustruje to rysunek 2.5. Rysunek 2.5. Przekroczenie dopuszczalnego zakresu dla typu int Operatory bitowe Operacje te, jak sama nazwa wskazuje, s dokonywane na bitach. Przypomnijmy zatem podstawowe wiadomoci o systemach liczbowych. W systemie dziesitnym, z którego korzystamy na co dzie, wykorzystywanych jest dziesi cyfr — od 0 do 9. W systemie dwójkowym bd zatem wykorzystywane jedynie dwie cyfry — 0 i 1. Rozdzia 2. • Zmienne, operatory i instrukcje 37 Kolejne liczby budowane s z tych dwóch cyfr dokadnie tak samo jak w systemie dziesitnym; przedstawia to tabela 2.3. Wida wyranie, e np. 4 dziesitnie to 100 dwójkowo, a 10 dziesitnie to 1010 dwójkowo. Tabela 2.3. Reprezentacja liczb w systemie dwójkowym i dziesitnym System dwójkowy System dziesitny 0 0 1 1 10 2 11 3 100 4 101 5 110 6 111 7 1000 8 1001 9 1010 10 1011 11 1100 12 1101 13 1110 14 1111 15 Na liczbach moemy dokonywa znanych ze szkoy operacji bitowych AND (iloczyn bitowy), OR (suma bitowa), NOT (negacja bitowa) oraz XOR (bitowa alternatywa wykluczajca). Symbolem operatora AND jest znak & (ampersand), operatora OR znak | (pionowa kreska), operatora NOT znak ~ (tylda), natomiast operatora XOR znak ^ (strzaka w gór, daszek). Oprócz tego mona równie wykonywa operacje przesuni bitów. Zestawienie wystpujcych w Javie operatorów bitowych zostao przedstawione w tabeli 2.4. 38 Java • wiczenia praktyczne Tabela 2.4. Operatory bitowe w Javie Operator Symbol AND & OR | NOT ~ XOR ^ Przesunicie bitowe w prawo >> Przesunicie bitowe w lewo << Przesunicie bitowe w prawo z wypenieniem zerami >>> Operatory logiczne Argumentami operacji logicznych musz by wyraenia posiadajce warto logiczn, czyli true lub false (prawda i fasz). Przykadowo wyraenie 10 < 20 jest niewtpliwie prawdziwe (10 jest mniejsze od 20), zatem jego warto logiczna jest równa true. W grupie tej wyróniamy trzy operatory: T logiczne AND (&&), T logiczne OR (||), T logiczna negacja (!). Warto zauway, e w czci przypadków stosowania operacji logicznych aby otrzyma wynik, wystarczy obliczy tylko pierwszy argument6. Wynika to oczywicie z waciwoci operatorów. Jeli wynikiem obliczenia pierwszego argumentu jest bowiem warto true, a wykonujemy operacj OR, to niezalenie od stanu drugiego argumentu wartoci caego wyraenia bdzie true. Podobnie przy stosowaniu operatora AND — jeeli wartoci pierwszego argumentu bdzie false, to i wartoci caego wyraenia bdzie false. 6 cilej rzecz ujmujc, moe wystarczy znajomo wartoci dowolnego jednego argumentu. Rozdzia 2. • Zmienne, operatory i instrukcje 39 Operatory przypisania Operacje przypisania s dwuargumentowe i powoduj przypisanie wartoci argumentu znajdujcego si z prawej strony do argumentu znajdujcego si z lewej strony. Najprostszym operatorem tego typu jest oczywicie klasyczny znak równoci. Zapis liczba = 5 oznacza, e zmiennej liczba chcemy przypisa warto 5. Oprócz tego mamy jeszcze do dyspozycji operatory czce klasyczne przypisanie z innym operatorem arytmetycznym bd bitowym. Zostay one zebrane w tabeli 2.5. Tabela 2.5. Operatory przypisania i ich znaczenie w Javie Argument 1 Operator Argument 2 Znaczenie x = y x = y x += y x = x + y x -= y x = x – y x *= y x = x * y x /= y x = x / y x %= y x = x % y x <<= y x = x << y x >>= y x = x >> y x >>>= y x = x >>> y x &= y x = x & y x |= y x = x | y x ^= y x = x ^ y Operatory porównania (relacyjne) Operatory porównania, czyli relacyjne, su oczywicie do porównywania argumentów. Wynikiem takiego porównania jest warto logiczna true (jeli jest ono prawdziwe) lub false (jeli jest faszywe). Zatem wynikiem operacji argument1 == argument2 bdzie true, jeeli argumenty s sobie równe, lub false, jeeli argumenty s róne. Czyli 4 == 5 ma warto false, a 2 == 2 ma warto true. Do dyspozycji mamy operatory porównania zawarte w tabeli 2.6. 40 Java • wiczenia praktyczne Tabela 2.6. Operatory porównania w Javie Operator Opis == Jeli argumenty s sobie równe, wynikiem jest true, w przeciwnym razie wynikiem jest false. != Jeli argumenty s róne, wynikiem jest true, w przeciwnym razie wynikiem jest false. > Jeli argument prawostronny jest mniejszy od lewostronnego, wynikiem jest true, w przeciwnym razie wynikiem jest false. < Jeli argument prawostronny jest wikszy od lewostronnego, wynikiem jest true, w przeciwnym razie wynikiem jest false. >= Jeli argument prawostronny jest mniejszy od lewostronnego lub równy lewostronnemu, wynikiem jest true, w przeciwnym razie wynikiem jest false. <= Jeli argument prawostronny jest wikszy od lewostronnego lub równy lewostronnemu, wynikiem jest true, w przeciwnym razie wynikiem jest false. Operator warunkowy Operator warunkowy ma nastpujc skadni: warunek ? warto1 : warto2; Wyraenie takie przybiera warto1, jeeli warunek jest prawdziwy, lub warto2 w przeciwnym przypadku. W I C Z E N I E 2.14 Wykorzystanie operatora warunkowego Uyj operatora warunkowego do zmodyfikowania wartoci dowolnej zmiennej typu cakowitego (int). class Main { public static void main (String args[]) { int x = 1, y; y = (x == 1 ? 10 : 20); System.out.println ("y = " + y); } } Rozdzia 2. • Zmienne, operatory i instrukcje 41 W powyszym wiczeniu najwaniejszy jest oczywicie wiersz: y = (x == 1? 10 : 20); który oznacza: jeeli x jest równe 1, przypisz zmiennej y warto 10, w przeciwnym razie przypisz zmiennej y warto 20. Poniewa zmienn x zainicjalizowalimy wartoci 1, na ekranie zostanie wywietlony cig znaków y = 10. Uyte w instrukcji nawiasy okrge nie s konieczne i su wycznie zwikszeniu czytelnoci kodu ródowego. Równie poprawna byaby instrukcja w postaci: y = x == 1 ? 10 : 20;. Priorytety operatorów Sama znajomo operatorów to jednak nie wszystko. Niezbdna jest jeszcze wiedza na temat tego, jaki maj one priorytet, czyli jaka jest kolejno ich wykonywania. Wiadomo na przykad, e mnoenie jest „silniejsze” od dodawania, zatem najpierw mnoymy, potem dodajemy. W Javie jest podobnie, sia kadego operatora jest cile okrelona. Przedstawia to tabela 2.77. Im wysza pozycja w tabeli, tym wyszy priorytet operatora. Operatory znajdujce si na jednym poziomie (w jednym wierszu) maj ten sam priorytet. Tabela 2.7. Priorytety operatorów w Javie 7 Grupa operatorów Symbole inkrementacja przyrostkowa ++, -- inkrementacja przedrostkowa, negacje ++, --, ~, ! mnoenie, dzielenie *, /, % przesunicia bitowe <<, >>, >>> porównania <, >, <=, >= porównania ==, != bitowe AND & bitowe XOR ^ Tabela nie przedstawia wszystkich operatorów wystpujcych w Javie, a jedynie omawiane w ksice. 42 Java • wiczenia praktyczne Tabela 2.7. Priorytety operatorów w Javie — cig dalszy Grupa operatorów Symbole bitowe OR | logiczne AND && logiczne OR || warunkowe ? przypisania =, +=, -=, *=, /=, %=, >>=, <<=, >>>=, &=, ^=, |= Instrukcje Instrukcja warunkowa if…else Bardzo czsto w programie niezbdne jest sprawdzenie jakiego warunku i w zalenoci od tego, czy jest on prawdziwy, czy faszywy, wykonanie rónych instrukcji. Do takiego sprawdzania suy wanie instrukcja warunkowa if...else. Ma ona ogóln posta: if (wyraenie warunkowe){ //instrukcje do wykonania, jeeli warunek jest prawdziwy } else{ //instrukcje do wykonania, jeeli warunek jest faszywy } Trzeba przy tym zaznaczy, e wyraenie warunkowe, inaczej ni w C i C++, musi da w wyniku warto typu boolean, tzn. true lub false. W I C Z E N I E 2.15 Uycie instrukcji warunkowej if…else Wykorzystaj instrukcj warunkow if...else do stwierdzenia, czy warto zmiennej typu cakowitego jest mniejsza od zera. class Main { public static void main (String args[]) { int a = -10; if (a > 0){ Rozdzia 2. • Zmienne, operatory i instrukcje 43 System.out.println ("Zmienna a jest wiksza od zera."); } else{ System.out.println ("Zmienna a nie jest wiksza od zera."); } } } W instrukcji warunkowej if jest badany warunek a > 0, czyli czy warto zmiennej a jest wiksza od 0. Jeli warunek jest prawdziwy (warto zmiennej a jest wiksza od 0), wykonywana jest instrukcja z bloku if, w przeciwnym razie (warto zmiennej a nie jest wiksza od 0) wykonywana jest instrukcja z bloku else. Poniewa pocztkowo do a zostaa przypisana warto -10, po skompilowaniu i uruchomieniu przykadu na ekranie pojawi si napis Zmienna a nie jest wiksza od zera. Zmiana wartoci a na wiksz od 0 i ponowna kompilacja oraz uruchomienie spowoduje wywietlenie drugiego napisu. Spróbujmy teraz czego nieco bardziej skomplikowanego. Zajmijmy si klasycznym przykadem liczenia pierwiastków równania kwadratowego. Przypomnijmy, e jeli mamy równanie o postaci Ax 2 Bx C 0 , to aby obliczy jego rozwizanie, liczymy tzw. delt ('), która jest równa B2 4AC . Jeeli delta jest wiksza od zera, mamy dwa pierwiastki: x1 B ' i x2 2A B ' . 2A Jeeli delta jest równa zeru, istnieje tylko jedno rozwizanie — mianowicie x B . W przypadku trzecim, jeeli delta jest mniejsza od zera, 2A równanie takie nie ma rozwiza w zbiorze liczb rzeczywistych. Skoro jest tutaj tyle warunków do sprawdzenia, jest to doskonay przykad do potrenowania zastosowania instrukcji if...else. Aby nie komplikowa zagadnienia, nie bdziemy si w tej chwili zajmowa wczytywaniem parametrów równania z klawiatury (ten temat zostanie omówiony w rozdziale 6.), ale podamy je bezporednio w kodzie. 44 Java • wiczenia praktyczne W I C Z E N I E 2.16 Pierwiastki równania kwadratowego Wykorzystaj operacje arytmetyczne oraz instrukcj if...else do obliczenia pierwiastków równania kwadratowego o parametrach podanych bezporednio w kodzie programu. class Main { public static void main (String args[]) { int parametrA = 1, parametrB = -1, parametrC = -6; System.out.println ("Parametry równania:"); System.out.println ("A: " + parametrA + " B: " + parametrB + " C: ´" + parametrC); if (parametrA == 0){ System.out.println ("To nie jest równanie kwadratowe: A = 0!"); } else{ double delta = parametrB * parametrB - 4 * parametrA * parametrC; if (delta < 0){ System.out.println ("Delta < 0."); System.out.println ("To równanie nie ma rozwizania w zbiorze ´liczb rzeczywistych"); } else{ double wynik; if (delta == 0){ wynik = - parametrB / 2 * parametrA; System.out.println ("Rozwizanie: x = " + wynik); } else{ wynik = (- parametrB + Math.sqrt(delta)) / 2 * parametrA; System.out.print ("Rozwizanie: x1 = " + wynik); wynik = (- parametrB - Math.sqrt(delta)) / 2 * parametrA; System.out.println (", x2 = " + wynik); } } } } } Na pocztku kodu s definiowane zmienne okrelajce parametry równania, a ich wartoci wywietlane na ekranie. Nastpnie za pomoc pierwszej instrukcji warunkowej if badany jest stan parametru A, czyli zmiennej parametrA. Po stwierdzeniu, e parametrA jest równy 0, wywietlana jest informacja, e nie mamy do czynienia z równaniem Rozdzia 2. • Zmienne, operatory i instrukcje 45 kwadratowym. W przeciwnym przypadku wykonywane s instrukcje z bloku else. Jest w nim obliczana delta, a nastpnie wykonywana kolejna instrukcja if badajca, czy delta jest mniejsza od 0. Jeli jest mniejsza, wywietlana jest informacja o braku rozwiza. W przeciwnym razie (delta wiksza od 0 bd równa 0) w bloku else jest wykonywana kolejna instrukcja warunkowa badajca tym razem, czy delta jest równa 0. Gdy jest równa 0, jedyny wynik jest obliczany i wywietlany na ekranie. W przeciwnym przypadku (delta wiksza od 0) obliczane s dwa pierwiastki, a wynik oblicze jest wywietlany na ekranie. Jak atwo zauway, instrukcj warunkow mona zagnieda, tzn. po jednym if moe wystpowa kolejne, po nim nastpne itd. Jednak jeeli zapiszemy to w sposób podany w poprzednim wiczeniu, przy wielu zagniedeniach otrzymamy bardzo nieczytelny kod. Aby temu zapobiec, moemy posuy si zoon instrukcj warunkow if...else if. Zamiast tworzy mniej wygodn konstrukcj, tak jak przedstawiona poniej: if (warunek1){ //instrukcje 1 } else{ if (warunek2){ //instrukcje 2 } else{ if (warunek3){ //instrukcje 3 } else{ //instrukcje 4 } } } cao mona zapisa duo prociej i czytelniej w postaci: if (warunek1){ //instrukcje 1 } else if (warunek2){ //instrukcje 2 } else if (warunek3){ //instrukcje 3 46 Java • wiczenia praktyczne } else{ //instrukcje 4 } W I C Z E N I E 2.17 Zastosowanie instrukcji if…else if Napisz kod obliczajcy pierwiastki równania kwadratowego o parametrach zadanych w programie. Wykorzystaj instrukcj if...else if. class Main { public static void main (String args[]) { int parametrA = 1, parametrB = -1, parametrC = -6; System.out.println ("Parametry równania:"); System.out.println ("A: " + parametrA + " B: " + parametrB + " C: ´" + parametrC); if (parametrA == 0){ System.out.println ("To nie jest równanie kwadratowe: A = 0!"); } else{ double delta = parametrB * parametrB - 4 * parametrA * parametrC; double wynik; if (delta < 0){ System.out.println ("Delta < 0."); System.out.println ("To równanie nie ma rozwizania w zbiorze ´liczb rzeczywistych"); } else if (delta == 0){ wynik = - parametrB / 2 * parametrA; System.out.println ("Rozwizanie: x = " + wynik); } else{ wynik = (- parametrB + Math.sqrt(delta)) / 2 * parametrA; System.out.print ("Rozwizanie: x1 = " + wynik); wynik = (- parametrB - Math.sqrt(delta)) / 2 * parametrA; System.out.println (", x2 = " + wynik); } } } } Rozdzia 2. • Zmienne, operatory i instrukcje 47 Instrukcja wyboru switch Instrukcja switch pozwala w wygodny i przejrzysty sposób sprawdza wiele warunków i wykonywa róny kod w zalenoci od tego, czy warunki s prawdziwe, czy faszywe. Mona ni zastpi cig instrukcji if...else if. Jeeli mamy w kodzie przykadow konstrukcj o schematycznej postaci: if (wyraenie == X){ instrukcja1; } else if (wyraenie == Y){ instrukcja2; } else if (wyraenie == Z){ instrukcja3; } else{ instrukcja4; } to moemy j zastpi tak: switch (wyraenie){ case X: instrukcje1; break; case Y: instrukcje2; break; case Z: instrukcje3; break; default: instrukcje4; } Po kolei jest tu sprawdzane, czy wyraenie przyjmuje jedn z wartoci X, Y i Z. Jeeli równo zostanie w jednym z przypadków stwierdzona, wykonywane s instrukcje po odpowiedniej klauzuli case. Jeeli równo nie zostanie stwierdzona, wykonywane s instrukcje po sowie default. Instrukcja break powoduje wyjcie z bloku switch. Wyraeniem jest z reguy po prostu nazwa zmiennej. W wersjach Javy do 7 (1.7) wartociami wyraenia (symbole X, Y, Z w kodzie) mog by tylko wartoci typu char, byte, short i int, natomiast w Javie 7 dodatkowo uwzgldniany jest te typ String (czyli cig znaków). 48 Java • wiczenia praktyczne W I C Z E N I E 2.18 Uycie instrukcji wyboru switch Uywajc instrukcji switch, napisz program sprawdzajcy, czy warto zadeklarowanej zmiennej jest równa 1, czy 10. Wywietl na ekranie stosowny komunikat. class Main { public static void main (String args[]) { int a = 10; switch (a){ case 1 : System.out.println("a jest równe 1"); break; case 10: System.out.println("a jest równe 10"); break; default: System.out.println("a nie jest równe ani 1, ani 10."); } } } Uwaga! Jeeli w którym z przypadków case zapomnimy o sowie (instrukcji) break, wykonywanie instrukcji switch bdzie kontynuowane a do osignicia pierwszej instrukcji break lub wykonania caego bloku switch. To moe prowadzi do otrzymania niespodziewanych efektów. W szczególnoci zostanie wtedy wykonany blok instrukcji wystpujcy po default. Moe to by oczywicie efekt zamierzony, moe te jednak powodowa trudne do wykrycia bdy. W I C Z E N I E 2.19 Efekt pominicia instrukcji break Zmodyfikuj kod z wiczenia 2.18, usuwajc instrukcj break. Zaobserwuj, jak zmienio si dziaanie programu. class Main { public static void main (String args[]) { int a = 10; switch (a){ case 1: System.out.println("a = 1"); case 10: Rozdzia 2. • Zmienne, operatory i instrukcje 49 System.out.println("a = 10"); default: System.out.println("a nie jest równe ani 1, ani 10."); } } } Po skompilowaniu i uruchomieniu kodu zobaczymy widok zaprezentowany na rysunku 2.6. Jak wida, wedug naszego programu zmienna a jest jednoczenie równa 10, jak i róna od 10. Bezporednim powodem jest oczywicie usunicie sowa break. Instrukcja switch dziaa teraz w ten sposób, e najpierw warto a jest porównywana z wartoci 1 (pierwszy przypadek case). Równo nie jest stwierdzona, zatem nastpuje przejcie do kolejnego bloku case (case 10). W tym bloku równo zostanie stwierdzona (a = 10), jest wic wykonywana instrukcja z tego bloku (System.out.println("a = 10");). Poniewa jednak w bloku case 10 nie ma instrukcji break, zostan wykonane wszystkie instrukcje z innych bloków case (o ile takie wystpuj) oraz bloku default, chyba e w którym z nich wystpi jednak instrukcja break. W tym przypadku za case 10 mamy tylko blok default i adnej instrukcji break, zatem zostanie wykonana instrukcja System. ´out.println("a nie jest równe ani 1, ani 10.");. Rysunek 2.6. Ilustracja bdu z wiczenia 2.19 Ptla for Ptle w jzykach programowania pozwalaj na wykonywanie powtarzajcych si czynnoci. Nie inaczej jest w Javie. Jeli chcemy np. wypisa na ekranie 10 razy napis Java, moemy zrobi to, piszc 10 razy System.out.println("Java");. Jeeli jednak chcielibymy mie ju 150 takich napisów, to, pomijajc oczywicie kwesti sensownoci tej czynnoci, byby to ju problem. Na szczcie z pomoc przychodz nam wanie ptle. Ptla typu for ma nastpujc skadni: 50 Java • wiczenia praktyczne for (wyraenie pocztkowe; wyraenie warunkowe; wyraenie modyfikujce){ //instrukcje do wykonania } wyraenie pocztkowe jest stosowane do zainicjalizowania zmiennej uywanej jako licznik liczby wykona ptli, wyraenie warunkowe okrela warunek, który musi by speniony, aby dokona kolejnego przejcia w ptli, wyraenie modyfikujce jest zwykle uywane do modyfikacji zmiennej bdcej licznikiem. W I C Z E N I E 2.20 Budowa ptli for Wykorzystujc ptl typu for, napisz program wywietlajcy na ekranie 10 razy napis Java. class Main { public static void main (String args[]) { for (int i = 1; i <= 10; i++){ System.out.println ("Java"); } } } Zmienna i to tzw. zmienna iteracyjna, której na pocztku przypisujemy warto 1 (int i = 1). Nastpnie w kadym przebiegu ptli jest ona zwikszana o jeden (i++) oraz wykonywana jest instrukcja System. ´out.println ("Java");. Wszystko trwa, a i osignie warto 10 (i <= 10). Wyraenie modyfikujce jest zwykle uywane do modyfikacji zmiennej iteracyjnej. Takiej modyfikacji moemy jednak dokona równie wewntrz ptli. Struktura tego typu wyglda nastpujco: for (wyraenie pocztkowe; wyraenie warunkowe;){ instrukcje do wykonania wyraenie modyfikujce } Rozdzia 2. • Zmienne, operatory i instrukcje 51 W I C Z E N I E 2.21 Wyraenie modyfikujce w bloku instrukcji Zmodyfikuj ptl typu for z wiczenia 2.20, tak aby wyraenie modyfikujce znalazo si w bloku instrukcji. class Main { public static void main (String args[]) { for (int i = 1; i <= 10;){ System.out.println ("Java"); i++; } } } Zwrómy uwag, e mimo i wyraenie modyfikujce jest teraz wewntrz ptli, rednik znajdujcy si po i <= 10 jest niezbdny! Jeli o nim zapomnimy, kompilator zgosi bd. Kolejn ciekaw moliwoci jest poczenie wyraenia warunkowego i modyfikujcego. W I C Z E N I E 2.22 czenie wyraenia warunkowego i modyfikujcego Napisz tak ptl typu for, aby wyraenie warunkowe byo jednoczenie wyraeniem modyfikujcym. class Main { public static void main (String args[]) { for (int i = 1; i++ <= 10;){ System.out.println ("Java"); } } } W podobny sposób jak w poprzednich przykadach moemy si pozby wyraenia pocztkowego, które przeniesiemy przed ptl. Schemat wyglda nastpujco: wyraenie pocztkowe; for (; wyraenie warunkowe;){ instrukcje do wykonania wyraenie modyfikujce } 52 Java • wiczenia praktyczne W I C Z E N I E 2.23 Wyraenie pocztkowe przed ptl Zmodyfikuj ptl typu for w taki sposób, aby wyraenie pocztkowe znalazo si przed ptl, a wyraenie modyfikujce wewntrz niej. class Main { public static void main (String args[]) { int i = 1; for (; i <= 10;){ System.out.println ("Java"); i++; } } } Skoro zaszlimy ju tak daleko w pozbywaniu si wyrae sterujcych, usumy równie wyraenie warunkowe. Jest to jak najbardziej moliwe! W I C Z E N I E 2.24 Ptla bez wyrae Zmodyfikuj ptl typu for w taki sposób, aby wyraenie pocztkowe znalazo si przed ptl, natomiast wyraenie modyfikujce i warunkowe wewntrz ptli. class Main { public static void main (String args[]) { int i = 1; for ( ; ; ){ System.out.println ("Java"); if (i++ >= 10) break; } } } Przy stosowaniu tego typu konstrukcji pamitajmy, e oba redniki w nawiasach okrgych wystpujcych po for s niezbdne do prawidowego funkcjonowania kodu. Warto te zwróci uwag na zmian kierunku nierównoci. We wczeniejszych przykadach sprawdzalimy bowiem, czy i jest mniejsze od 10 bd równe 10, a teraz — czy jest wiksze bd równe. Dzieje si tak, dlatego e poprzednio sprawdzalimy, czy ptla ma by dalej wykonywana, natomiast obecnie — czy ma zosta zakoczona. Wykorzystalimy te instrukcj break. Suy ona do natychmiastowego przerwania wykonywania ptli. Rozdzia 2. • Zmienne, operatory i instrukcje 53 Przydatn instrukcj jest continue. Powoduje ona rozpoczcie kolejnej iteracji (przebiegu) ptli, tzn. w miejscu jej wystpienia wykonywanie biecej iteracji jest przerywane i rozpoczyna si kolejny przebieg. W I C Z E N I E 2.25 Zastosowanie instrukcji continue Napisz program wywietlajcy na ekranie liczby od 1 do 20, które nie s podzielne przez 2. Skorzystaj z ptli for i instrukcji continue. class Main { public static void main (String args[]) { for (int i = 1; i <= 20; i++){ if (i % 2 == 0) continue; System.out.println (i); } } } Przypomnijmy, e % to operator dzielenia modulo, tzn. daje on reszt z dzielenia. To oznacza, e jeli wynikiem dziaania i % 2 jest 0, to warto i z pewnoci jest parzysta (podzielna przez 2). Jest to badane w instrukcji warunkowej if. Zatem gdy warunek i % 2 == 0 jest prawdziwy (i jest podzielne przez 2), wykonywana jest instrukcja continue. Tym samym natychmiast rozpoczyna si kolejna iteracja ptli i nie jest wykonywana instrukcja System.out.println (i);. Gdy warunek jest faszywy (i nie jest podzielne przez 2), instrukcja wywietlajca warto i jest wykonywana, dziki czemu na ekranie pojawiaj si nieparzyste liczby z zakresu 1 – 20. Oczywicie nic nie stoi na przeszkodzie, aby aplikacj dziaajc w taki sam sposób jak w wiczeniu 2.25 napisa bez uycia instrukcji continue. W I C Z E N I E 2.26 Liczby niepodzielne przez dwa Zmodyfikuj kod z wiczenia 2.25 tak, aby nie byo koniecznoci uycia instrukcji continue. 54 Java • wiczenia praktyczne class Main { public static void main (String args[]) { for (int i = 1; i <= 20; i++){ if (i % 2 != 0) System.out.println (i); } } } Tym razem instrukcja wywietlajca warto i jest wykonywana tylko wtedy, gdy prawdziwy jest warunek i % 2 != 0, a wic wtedy, gdy reszta z dzielenia i przez 2 jest róna od zera (co oznacza, e warto i jest nieparzysta). Dziki takiej konstrukcji zosta osignity taki sam efekt jak w wiczeniu 2.25, ale bez uycia instrukcji continue. Ptla while O ile ptla typu for suy zwykle do wykonywania znanej z góry liczby operacji, to w przypadku ptli while liczba ta nie jest zazwyczaj znana. Nie jest to oczywicie obligatoryjny podzia. Tak naprawd obie mona napisa w taki sposób, aby byy swoimi funkcjonalnymi odpowiednikami. Ogólna konstrukcja ptli typu while jest nastpujca: while (wyraenie warunkowe){ instrukcje } Instrukcje s wykonywane dopóty, dopóki wyraenie warunkowe jest prawdziwe. Oznacza to, e gdzie w ptli musi wystpi modyfikacja warunku bd te instrukcja break. Inaczej bdzie si wykonywaa w nieskoczono! W I C Z E N I E 2.27 Budowa ptli while Uywajc ptli typu while, napisz program wywietlajcy na ekranie 10 razy napis Java. class Main { public static void main (String args[]) { int i = 1; while (i <= 10){ System.out.println ("Java"); Rozdzia 2. • Zmienne, operatory i instrukcje 55 i++; } } } Taka ptla dziaa, dopóki prawdziwy jest warunek i <= 10. Poniewa pocztkow wartoci i jest 1, a we wntrzu ptli warto tej zmiennej w kadym przebiegu jest zwikszana o 1, ptla (a tym samym instrukcja System.out.println ("Java");) zostanie wykonana dokadnie 10 razy. Podobnie jak w przypadku ptli for mamy du dowolno w ksztatowaniu ptli while. Przykadowo wyraenie modyfikujce warto zmiennej kontrolujcej przebiegi ptli moe by z powodzeniem poczone z wyraeniem warunkowym. W I C Z E N I E 2.28 Poczone wyraenia Zmodyfikuj kod z wiczenia 2.27 tak, aby wyraenie warunkowe zmieniao jednoczenie warto zmiennej i. class Main { public static void main (String args[]) { int i = 1; while (i++ <= 10){ System.out.println ("Java"); } } } W I C Z E N I E 2.29 Liczby nieparzyste i ptla while Korzystajc z ptli while, napisz program wywietlajcy na ekranie liczby od 1 do 20 niepodzielne przez 2. class Main { public static void main (String args[]) { int i = 1; while (i <= 20){ if (i % 2 != 0) 56 Java • wiczenia praktyczne System.out.println (i); i++; } } } Ptla do…while Istnieje jeszcze jedna odmiana ptli. Jest to do...while. Jej konstrukcja jest nastpujca: do{ instrukcje; } while (warunek); Oznacza to: wykonuj instrukcje, dopóki prawdziwy jest warunek. W I C Z E N I E 2.30 Budowa ptli do…while Korzystajc z ptli do...while, napisz program wywietlajcy na ekranie 10 razy dowolny napis. class Main { public static void main (String args[]) { int i = 1; do{ System.out.println ("Java"); } while (i++ <= 9); } } Cho w pierwszej chwili wydawa by si mogo, e to przecie to samo co zwyka ptla while, jest jednak pewna znaczca rónica. Otó w przypadku ptli do...while warunek zakoczenia jest sprawdzany dopiero po jej wykonaniu (w ptli while warunek jest sprawdzany przed wykonaniem instrukcji z wntrza). To oznacza, e instrukcje s wykonane co najmniej jeden raz, nawet jeli warunek jest na pewno faszywy. Rozdzia 2. • Zmienne, operatory i instrukcje 57 W I C Z E N I E 2.31 Ptla do…while z faszywym warunkiem Zmodyfikuj kod z wiczenia 2.30 w taki sposób, aby wyraenie warunkowe na pewno byo faszywe. Zaobserwuj wyniki dziaania programu. class Main { public static void main (String args[]) { int i = 10; do{ System.out.println ("Java"); } while (i++ <= 9); } } W tym programie warunek zakoczenia ptli (i++ <= 9) z pewnoci jest faszywy, przed wykonaniem ptli zmiennej i zostaa bowiem przypisana warto 10 (która oczywicie nie jest ani mniejsza od 10, ani równa 10). Mimo tego, gdy skompilujemy i uruchomimy program, na ekranie pojawi si jeden napis Java. To najlepszy dowód, e warunek zosta wykonany po wykonaniu instrukcji z wntrza ptli, a nie przed ich wykonaniem. Ptla foreach Poczwszy od wersji 1.5 (5.0), Java udostpnia jeszcze jeden rodzaj ptli. Jest ona nazywana ptl foreach lub rozszerzon ptl for (z ang. enhanced for) i pozwala na automatyczn iteracj po kolekcji obiektów lub te po tablicy. Zostanie przedstawiona w kolejnym rozdziale, omawiajcym tablice.