5 Přehled operátorů, příkazy, přetypování Studijní cíl Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně budou uvedeny detaily týkající se operátorů. Doba nutná k nastudování 2 2,5 hodiny 5.1 Přehled operátorů V předchozí kapitole jsme si uvedli základní informace o operátorech a nyní si uvedeme detailní informace ke všem základním operátorům dostupným v jazyce Java. Operátory lze rozdělit do těchto základních skupin: operátor přiřazení aritmetické operátory relační operátory logické operátory ternární operátor bitové operátory operátor instanceof Operátory mají různé priority (pořadí při jejich zpracování). V jazyce Java je standardní zpracování operátorů zleva doprava, pořadí lze ale měnit uplatněním kulatých závorek (zvýšení priority). Nyní si můžeme uvést kompletní přehled operátorů dostupných v jazyce Java, který je uveden v následující tabulce, kde je v prvním sloupci uvedena priorita operátů, dále potom syntaxe daného operátoru, ve třetím sloupci je k dispozici popis operátoru a v posledním sloupci asociativita operátorů. KST/IZAPR - Základy programování blok 5, strana 1 (11) Michael Bažant
Pri. Operátor Popis Asoc. 1 (), [] Primární výrazový L 2 ++, -- Inkrement (post, pre) P 2 +, - Unární plus, minus (změna znaménka) P 2 ~ Bitový doplněk P 2 () Přetypování P 2! Logická negace P 3 *, /, % Násobení, dělení, zbytek po dělení L 4 +, - Součet, rozdíl, spojování řetězců L 5 <<, >>, >>> Posun vpravo, posun vlevo L 6 <, <=, >, >= Menší, menší rovno, větší, větší rovno (vrací boolean) L 6 instanceof Porovnání typů (vrací boolean) L 7 ==,!= Rovno, není rovno (vrací boolean) L 8 & Logické a bitové AND L 9 ^ Logické a bitové XOR L 10 Logické a bitové OR L 11 && Podmínkové AND (vrací boolean) L 12 Podmínkové OR (vrací boolean) L 13 (? : ) Podmínkový operátor P 14 =, +=, /=, *=, %=, -=, <<=, >>=, >>>=, &=, ~=, ^= Operátory přiřazení P 5.2 Operátor přiřazení Operátor přiřazení kopíruje hodnotu výrazu na své pravé straně do proměnné na levé straně. Pro označení levé a pravé strany výrazu se také často používají pojmy L-hodnota a P-hodnota viz Obrázek 1. L-hodnota představuje místo v paměti, kterému lze přiřadit hodnotu, P-hodnota výraz, který má vždy hodnotu a který vystupuje na pravé straně operátoru přiřazení. Obrázek 1: Operátor přiřazení s vyznačením L-hodnoty a P-hodnoty KST/IZAPR - Základy programování blok 5, strana 2 (11) Michael Bažant
Operátorem přiřazení lze provést přiřazení: literální hodnoty např. int x = 7; výsledku výrazu s literální hodnotou např. int y = x + 2; výsledku výrazu např. int z = x * y; Příklady na operátor přiřazení při použití primitivních datových typů: (poceta + pocetb) = 30; // takto nelze pouzit a = (b = c / 3);//syntakticky v poradku, ale //z duvodu citelnosti se tento //způsob zapisu nedoporucuje b = c / 3; // spravna alternativa k a = b; // predchozimu zapisu Příklady na operátor přiřazení při použití referenčních datových typů: Student student = new Student(); Student student = null; Složené operátory přiřazení Jsou kombinací aritmetické operace a operátoru přiřazení, nejprve se vykoná aritmetická operace a výsledek této operace je přiřazen L-hodnotě. K dispozici jsou celkem čtyři složené operátory přiřazení (pro součet, rozdíl, součin a podíl): +=, -=, *=, /= Příklady na složené operátory přiřazení y = y 6; y -= 6; //oba zapisy jsou mozne x = x + 2 * 5; x += 2 * 5; //oba zapisy jsou mozne x = x * 2 + 5; x *= 2 + 5; //x=x*(2+5), ne x=x*2+5 5.3 Aritmetické operátory V jazyce Java jsou samozřejmě k dispozici základní operátory pro aritmetické výpočty. Tyto operátory standardně vyžadují dva operandy. operátor součtu +, např. int pocet = poceta + pocetb; operátor rozdílu -, např. int pocet = poceta - pocetb; KST/IZAPR - Základy programování blok 5, strana 3 (11) Michael Bažant
operátor součinu *, např. int celkovacena = pocetkusu * jednotkovacena; operátor podílu /, např. int jednotkovacena = celkovacena / pocetkusu; operátor modulo % (zbytek po dělení), např. int zbytek = x % y; // zbytek >= 0, zbytek < y Při použití některých operátorů je nutné mít na paměti, že výsledný datový typ výrazu záleží na datovém typu operandů, např. u operátoru podílu: 5.3.1 Příklady na aritmetické operátory Práci s aritmetickými operátory si vyzkoušíme na několika příkladech, z nichž některé budou také demonstrovat důležité vlastnosti jazyka Java. int i = 7; int j = 2; double k = i / j; // vysledek 3.0 double i = 7; int j = 2; double k = i / j; // vysledek 3.5 Z předchozích příkladů j zřejmé, že pokud jsou oba operandy celočíselného datového typu, tak bude výsledek celočíselný. Pokud bude i jen jeden operand datového typu s plovoucí desetinnou čárkou, tak bude výsledek rovněž datového typu s plovoucí des. čárkou. Pokud bychom se podívali na opačný případ kdy by výsledek operace vedl na datový typ s plovoucí des. čárkou a l-hodnota by byla celočíselného datového typu, tak by kompilace neproběhla úspěšně (chyba ztráty přesnosti výsledku viz Obrázek 2). double i = 7; int j = 2; int k = i / j; //chyba pri kompilaci Nyní se podíváme na vlastnosti operátoru modulo, který lze použít jak při práci s celočíselnými datovými typy, tak při práci s datovými typy s plovoucí desetinnou čárkou. int i = 7; int j = 3; int k = i % j; // vysledek 1 double i = 8.27; int j = 2; double k = i % j; // vysledek 0.27 KST/IZAPR - Základy programování blok 5, strana 4 (11) Michael Bažant
U operátoru modulo je také zajímavé se podívat na výsledky při použití kladných a záporných hodnot operandů. Pokud je první operand záporný, tak bude i výsledek záporný. Pokud je druhý operand záporný, výsledek bude kladný. V případě záporného znaménka obou operandů bude výsledek záporný. int i = -7; int j = 4; int k = i % j; // vysledek -3 int i = 7; int j = -4; int k = i % j; // vysledek 3 int i = -7; int j = -4; int k = i % j; // vysledek -3 Operátory pro součet a rozdíl (+, -) lze používat také ve spojení pouze s jedním operandem, těmto operátorům se říká operátory unární. Příklad na unární operátory: int a = -5; int b = -a; //zmena znamenka Obrázek 2: Chyba při kompilaci (ztráta přesnosti výsledku) 5.3.2 Operátory inkrementace a dekrementace Operátory inkrementace (++) a dekrementace (--) jsou operátory unární a lze je použít jak před (prefix), tak i za operandem (postfix). Tyto operátory slouží ke zvýšení nebo ke snížení hodnoty operandu o hodnotu jedna viz následující příklad, které si zkuste zapsat sami. KST/IZAPR - Základy programování blok 5, strana 5 (11) Michael Bažant
int pocet = 5; System.out.println("Pocet: " + pocet++); System.out.println("Pocet: " + pocet); System.out.println("Pocet: " + ++pocet); 5.3.3 Operátor spojování řetězců Operátor +, který jsme si představili jako aritmetický a unární operátor lze také použít jako operátor pro spojování textových řetězců viz následující příklady, které si opět zkuste zapsat do metody main(). Pokud je při použití tohoto operátoru jakýkoliv operand datového typu String, operátor + se chová jako operátor pro spojování řetězců. String a = "String"; int b = 3; int c = 7; System.out.println(a + b + c); System.out.println(a + (b + c)); 5.4 Operátory rovnosti a relační operátory Operátory rovnosti a relační operátory určují, zda je jeden operand větší, menší, rovný nebo se nerovná dalšímu operandu. Tyto operátory vždy vrací hodnotu true nebo false. U těchto operátorů platí vždy ta zásada, že se porovnávají jednotlivé bity uložené v proměnných. Relační operátory lze je použít s datovými typy, u kterých to má význam (byte, short, int, long, float, double, char). Syntakticky relační operátory zapisujeme v jazyce Java následovně: < menší než <= menší než nebo rovno > větší než >= větší než nebo rovno Příklady na použití relačních operátorů: boolean b1 = 1 < 2; boolean b2 = 'A' < 'B'; //true //true Operátory rovnosti lze použít se stejnými datovými typy jako relační operátory, navíc je můžeme použít u datového typu boolean a také s referenčními proměnnými. == je rovno KST/IZAPR - Základy programování blok 5, strana 6 (11) Michael Bažant
!= není rovno Příklady na použití operátorů rovnosti u prim. datových typů: boolean b1 = ('a' == 'a'); boolean b2 = ('a' == 'b'); boolean b3 = (5!= 6); boolean b4 = (5.0 == 5L); boolean b5 = (true == false); Příklady na použití operátorů rovnosti u referenčních datových typů: Scanner vstup1 = new Scanner(System.in); Scanner vstup2 = new Scanner(Systém.in); boolean b = (vstup1 == vstup2); Obrázek 3: Použití operátoru rovnosti u referenčních datových typů různé bity Scanner vstup1 = new Scanner(System.in); Scanner vstup2 = vstup1; boolean b = (vstup1 == vstup2); Obrázek 4: Použití operátoru rovnosti u referenčních datových typů stejné bity KST/IZAPR - Základy programování blok 5, strana 7 (11) Michael Bažant
5.5 Logické operátory Logické operátory slouží pro vykonání operace podmínkové AND a podmínkové OR se dvěma logickými výrazy. Tyto operátory nabízejí možnost úplného nebo zkráceného vyhodnocování to znamená, že se druhý operátor vyhodnocuje pouze v případě potřeby. Tyto operátory zapisujeme v jazyce Java následovně: && - logický součin (AND) - logický součet (OR) Příklady použití logických operátorů pro zkrácené vyhodnocování: if ((3 < 2) && (3 < 4)) {...} if ((3 < 2) (3 < 4)) {...} //nebude se overovat //druhy vyraz //bude se overovat i //druhy vyraz Pro úplné vyhodnocování se používá (ze syntaktického hlediska) redukovaný zápis, kdy dochází k vyhodnocení všech operandů (může být v některých případech neefektivní): & - logický součin (AND) - logický součet (OR) Příklad použití logických operátorů pro úplné vyhodnocování: int z = 5; if (++z > 5) ++z > 6) z++; Výsledky pro logický součin a logický součet kdy jsou hodnoty dvou operandů různé jsou uvedeny v následující tabulce. o1 o2 o1 && o2 o1 o2 true true true true true false false true false true false true false false false false Dalším logickým operátorem je operátor XOR (exklusive OR), který vyhodnocuje dva výrazy a pro kladné vyhodnocení musí být přesně jeden true viz tabulka. Tento operátor zapisujeme pomocí znaku ^. KST/IZAPR - Základy programování blok 5, strana 8 (11) Michael Bažant
Příklad použití logického operátoru XOR: boolean b1 = ((2 < 3) ^ (4 > 3)); //false boolean b2 = ((2 < 3) ^ (3 > 4)); //true o1 o2 o1 ^ o2 true true false true false true false true true false false false Posledním logickým operátorem je operátor negace, který zapisujeme symbolem!, kdy dojde u logických hodnot k negaci hodnot původních viz následující tabulka. o!o true false false true 5.6 Ternární operátor Ternární operátor používáme pro vytváření výrazů, jejichž výsledek závisí na vstupní podmínce. Má tři operandy, proto se používá název ternární. Obecný zápis vypadá tak, že v kulaté závorce je výraz, jenž je vyhodnocen. Pokud je vyhodnocen kladně, tak bude vykonána vyrianta true, jinak varianta false. Doporučení k ternárnímu operátoru je takové, že by se neměl používat ve výrazech, neměl by se používat jako náhrada podmíněného příkazu if (viz další blok) a ternární operátory by se neměly vnořovat do sebe (velmi nečitelný kód). x = (pravd. výraz)? varianta_true : varianta_false Příklad: String mnozstvi = (pocetstudentu < 8)? "Malo studentu" : "Hodne studentu"; KST/IZAPR - Základy programování blok 5, strana 9 (11) Michael Bažant
5.7 Operátor instanceof Operátor instanceof používáme pouze ve spojitosti s referenčními proměnnými a slouží pro testování, zda se jedná o objekt určitého typu v hierarchii dědičnosti (více o dědičnosti v dalších blocích). Nyní si uvedeme příklad na použití tohoto operátoru. String s = "Vypis na obrazovku"; boolean b = (s instanceof String); // true 5.8 Bitové operátory V jazyce Java jsou k dispozici také operace, které provádějí bitové operace s celočíselnými datovými typy (tyto operace se nepoužívají příliš často). Jedná se o tyto operátory: & bitový součin AND bitový součet OR ^ bitový XOR ~ bitový NOT, unární operátor. Jedná se o bitový doplněk, mění všechny bity 1 na 0 a opačně. Přehled výstupů pro dané vstupy je uveden v následující tabulce. První Druhý AND OR XOR 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0 Příklady na bitové operátory: 5 & 3 = 1 // (0101 AND 0011 = 0001) 5 3 = 7 // (0101 OR 0011 = 0111) 5 ^ 3 = 6 // (0101 XOR 0011 = 0110) 5.8.1 Bitové posuny Další skupinou bitových operátorů jsou operátory pro posun jednotlivých bitů. K dispozici jsou tyto operátory: << levý posun o určitý počet míst, při posunu se bity vlevo ztrácí a uvolněná místa jsou doplněna nulami KST/IZAPR - Základy programování blok 5, strana 10 (11) Michael Bažant
>> pravý znaménkový posun o určitý počet míst, při posunu se bity vpravo ztrácí a uvolněná místa jsou doplněna nulami (pozice až vlevo záleží na znaménku) >>> pravý neznaménkový posun posune nulu na první pozici vlevo, dále pracuje jako znaménkový posun Příklady použití operátorů bitového posunu: int prom = 17; // prom = 00010001 = 17 prom = prom << 1; // prom = 00100010 = 34 int prom = 17; // prom = 00010001 = 17 prom = prom >> 1; // prom = 00001000 = 8 int prom = 17; // prom = 00010001 = 17 prom = prom >>> 1; // prom = 00010001 = 8 int prom = -8; // prom = -8 = 11...1111000 prom = prom >> 1; // prom = -4 = 11...1111100 prom = prom << 1; // prom = -8 = 11...1111000 prom = prom >>> 1; // prom = 2147483644= // 01...1111100 Otázky na procvičení 1. Co je to operátor? 2. Co je to operand? 3. Napište tabulku pro negaci pro jednoho vstupu. 4. Jaké jsou unární operátory? 5. Co platí pro dělení celých a reálných čísel v jazyce Java? Odkazy a další studijní prameny 1. Java Tutorial - http://docs.oracle.com/javase/tutorial/ KST/IZAPR - Základy programování blok 5, strana 11 (11) Michael Bažant