• logické operátory. Aritmetické operace

    Poslední aktualizace: 30.10.2018

    Většina operací v Javě je podobná těm, které se používají v jiných jazycích podobných C. Existují unární operace (prováděné na jednom operandu), binární operace na dvou operandech a ternární operace na třech operandech. Operand je proměnná nebo hodnota (například číslo), která se účastní operace. Zvažte všechny typy operací.

    Aritmetické operace zahrnují čísla. Java má binární aritmetické operace (prováděné na dvou operandech) a unární aritmetické operace (prováděné na jednom operandu). Binární operace zahrnují následující:

      operace sčítání dvou čísel:

      int a = 10; int b = 7; int c = a + b; // 17 int d = 4 + b; // jedenáct

      operace odečtení dvou čísel:

      int a = 10; int b = 7; int c = a - b; // 3 int d = 4 - a; // -6

      operace násobení dvou čísel

      int a = 10; int b = 7; int c = a*b; // 70 int d = b * 5; // 35

      operace dělení dvou čísel:

      int a = 20; int b = 5; int c = a/b; // 4 double d = 22,5 / 4,5; // 5.0

      Při dělení stojí za zvážení, protože pokud se operace účastní dvě celá čísla, bude výsledek dělení zaokrouhlen nahoru na celé číslo, i když je výsledek přiřazen k proměnné s plovoucí nebo dvojitou čárkou:

      Dvojité k = 10/4; // 2 System.out.println(k);

      Aby výsledkem bylo číslo s plovoucí desetinnou čárkou, jeden z operandů musí být také číslo s plovoucí desetinnou čárkou:

      Dvojité k = 10,0/4; // 2.5 System.out.println(k);

      získání zbytku po dělení dvou čísel:

      int a = 33; int b = 5; int c = a % b; // 3 int d = 22 % 4; // 2 (22 – 4*5 = 2)

    Existují také dvě unární aritmetické operace, které se provádějí s jedním číslem: ++ (přírůstek) a -- (snížení). Každá z operací má dvě varianty: prefix a postfix:

      ++ (přírůstek předpony)

      Předpokládá, že proměnná je zvýšena o jedničku, např. z=++y (nejprve se hodnota proměnné y zvýší o 1 a pak se její hodnota přiřadí proměnné z)

      Int a = 8; intb = ++a; System.out.println(a); // 9 System.out.println(b); // 9

      ++ (přírůstek postfixu)

      Také představuje zvýšení proměnné o jednu, například z=y++ (nejprve je hodnota y přiřazena k z a poté je hodnota y zvýšena o 1)

      Int a = 8; intb = a++; System.out.println(a); // 9 System.out.println(b); // 8

      -- (snížení předpony)

      snížit proměnnou o jedničku, například z=--y (nejprve se hodnota proměnné y sníží o 1 a pak se její hodnota přiřadí proměnné z)

      Int a = 8; int b = --a; System.out.println(a); // 7 System.out.println(b); // 7

      -- (postfixové snížení)

      z=y-- (nejprve je y přiřazeno k z, poté je y sníženo o 1)

      Int a = 8; int b = a--; System.out.println(a); // 7 System.out.println(b); // 8

    Priorita aritmetických operací

    Některé operace mají vyšší prioritu než jiné, a proto se provádějí jako první. Operace v sestupném pořadí priority:

    ++ (přírůstek), -- (snížení)

    * (násobení), / (dělení), % (zbytek po dělení)

    + (sčítání), - (odčítání)

    Při provádění sady aritmetických výrazů je třeba vzít v úvahu prioritu operací:

    Int a = 8; int b = 7; int c = a + 5 * ++b; System.out.println(c); // 48

    Nejprve se provede operace inkrementace ++b, která má vyšší prioritu - zvýší hodnotu proměnné b a vrátí ji jako svůj výsledek. Poté se provede násobení 5 * ++b a teprve poslední je sčítání a + 5 * ++b

    Závorky umožňují předefinovat pořadí hodnocení:

    Int a = 8; int b = 7; int c = (a + 5) * ++b; System.out.println(c); // 104

    Navzdory skutečnosti, že operace sčítání má nižší prioritu, bude to sčítání, které se provede jako první, a nikoli násobení, protože operace sčítání je uzavřena v závorkách.

    Asociativita operací

    Kromě priority se operace liší v takovém pojetí, jako je asociativnost. Když mají operace stejnou prioritu, pořadí vyhodnocení je určeno asociativitou operátorů. V závislosti na asociativitě existují dva typy operátorů:

      Levé asociativní operátory, které se provádějí zleva doprava

      Pravé asociativní operátory, které se provádějí zprava doleva

    Například některé operace, jako je násobení a dělení, mají stejnou přednost. Jaký pak bude výsledek ve výrazu:

    int x = 10/5 * 2;

    Měli bychom tento výraz interpretovat jako (10 / 5) * 2 nebo jako 10 / (5 * 2)? Ostatně v závislosti na interpretaci dostaneme různé výsledky.

    Protože všechny aritmetické operátory (kromě předponového přírůstku a dekrementu) jsou vlevo asociativní, to znamená, že se provádějí zleva doprava. Proto výraz 10 / 5 * 2 musí být interpretován jako (10 / 5) * 2, to znamená, že výsledek bude 4.

    Operace s čísly s pohyblivou řádovou čárkou

    Je třeba poznamenat, že čísla s pohyblivou řádovou čárkou nejsou vhodná pro finanční a jiné výpočty, kde mohou být kritické chyby zaokrouhlení. Například:

    Dvojité d = 2,0 - 1,1; System.out.println(d);

    V tento případ proměnná d se nebude rovnat 0,9, jak by se dalo zpočátku předpokládat, ale 0,8999999999999999. K těmto chybám přesnosti dochází, protože čísla s plovoucí desetinnou čárkou jsou binárně reprezentována na nízké úrovni, ale neexistuje žádná binární reprezentace pro 0,1, stejně jako pro jiné zlomkové hodnoty. Pokud se tedy v takových případech obvykle používá třída BigDecimal, která umožňuje takové situace obejít.

    Většina operací na primitivní typy se nedělá metodami, ale pomocí speciální znaky volal znamení operace.

    operace přiřazení

    Úkol hodnotová proměnná konstanta, je volána další proměnná nebo výraz (proměnné a/nebo konstanty oddělené znaménkem operátora). operace přiřazení a je označeno " = ", například: x = 3 ; y = x; z = x; V Javě je možné v jednom výrazu použít operátor přiřazení vícekrát, například: x1 = x2 = x3 = 0 ; Tato operace se provádí od zprava doleva, tj. nejprve je proměnné x3 přiřazena hodnota 0 , poté je x2 přiřazena hodnota x3 (0) a nakonec x1 je přiřazena hodnota x2 (0) Značky operací, jejichž argumenty jsou čísla, spadají do dvou kategorií : unární(unární) operační znaky s jedním argumentem a binární(binární) se dvěma argumenty.

    Unární operace

    Java definuje následující unární operace:
    • unární mínus "-" - změní znaménko čísla nebo výrazu na opačné;
    • unární plus " + " - neprovádí žádné operace s číslem nebo výrazem;
    • bitový doplněk "~" (pouze pro celá čísla) - invertuje všechny bity číselného pole (změní 0 na 1 a 1 na 0);
    • increment " ++ " (pouze pro celá čísla) – zvýší hodnotu proměnné o 1;
    • dekrementovat " -- " (pouze pro celá čísla) - snižuje hodnotu proměnné o 1.
    Příklady unárních operací "+" a "-": int i = 3 , j, k; j=-i; // j = -3 k = + i; // k = 3 Příklad operace bitového doplňku: int a = 15 ; intb; b=~a; // b = -16 Čísla a a b jsou int , tzn. jsou interně reprezentovány počítačem jako binární celá čísla se znaménkem o délce 32 bitů, takže binární reprezentace aab by vypadala takto: na 1 bit v b a 1 bit v a se změní na nulový bit. Desetinná reprezentace čísla b by byla -16. Značky operátoru zvýšení a snížení lze umístit před nebo za proměnnou. Tyto možnosti se nazývají resp předpona A postfix zaznamenávání těchto transakcí. Notace předpony přihlášení operátora vrací hodnotu svého operandu po hodnocení výrazu. S postfixovou notací znak operace nejprve vrátí hodnotu svého operandu a teprve poté vypočítá přírůstek nebo úbytek, například: int x = 1 , y, z; y=++x; z= x++; Proměnné y bude přiřazena hodnota 2, protože x bude nejprve zvýšeno o 1 a poté bude výsledek přiřazen k proměnné y. Proměnné z bude přiřazena hodnota 1, protože z bude nejprve přiřazena hodnota a poté bude x zvýšeno o 1 . V obou případech bude nová hodnota x 2 . Je třeba poznamenat, že v Javě lze na rozdíl od jazyka C operace dekrementace a inkrementace aplikovat i na reálné proměnné (typu float a double). Binární znaky operací se dělí na operace s číselným výsledkem a porovnávací operace, jejichž výsledkem je booleovská hodnota.

    Aritmetické binární operace

    Java definuje následující aritmetické binární operace:
    • přidání "+";
    • odčítání "-";
    • násobení " * ";
    • dělení "/";
    • výpočet zbytku dělení celých čísel " % " (vrátí zbytek dělení prvního čísla druhým a výsledek bude mít stejné znaménko jako dividenda), například výsledek operace 5% 3 bude 2 a výsledek operace (-7) %(-4) bude roven -3. V Javě lze operaci použít i pro reálné proměnné (typu float nebo double).
    binární příklady aritmetické operace: int x = 7, x1, x2, x3, x4, x5; x1 = x + 10; // x1 = 17 x2 = x - 8; // x2 = -1 x3 = x2 * x; // x3 = -7 x4 = x/4; // x4 = 1 (při dělení celých čísel // zlomková část je zahozena) x5 = x%4 // x5 = 3 (zbytek z dělení// 7 krát 4)

    Bitové operace

    • Bitové operace považují původní číselné hodnoty za pole bitů a provádějí s nimi následující operace:
    • nastavení rytmu na i-tá pozice výsledného pole je 1, pokud jsou oba bity uvnitř i-té pozice operandů jsou rovny 1 nebo 0, jinak bitově AND (" & ");
    • nastavení rytmu na i-tá pozice výsledného pole je 1, pokud je uvnitř alespoň jeden bit i-tá pozice operandů je 1 nebo 0 jinak - bitově OR (" | ");
    • nastavení rytmu na i-tá pozice výsledného pole je 1, pokud jsou bity v i-té pozice operandů se navzájem nerovnají, nebo jinak 0 - bitové exkluzivní OR (" ^ ");
    • posun doleva od bitů pole prvního operandu o počet bitů určený druhým operandem (znakový bit čísla se v tomto případě nemění) - bitový posun doleva s přihlédnutím ke znaménku "<< ";
    • posun vpravo od bitů pole prvního operandu o počet bitů určený druhým operandem (znaménkový bit čísla se v tomto případě nemění) – bitový posun vpravo s přihlédnutím ke znaménku " >>";
    • posun vpravo od bitů pole prvního operandu o počet bitů určený druhým operandem (v tomto případě je posunut znaménkový bit čísla) - bitový posun doprava bez zohlednění ">> > znak.
    Příklady bitových operací:
    1. Bitové AND

      int x = 112; int y = 94; intz; z=x & y; // z=80: 00000000 00000000 00000000 01010000
    2. Bitově NEBO

      int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 intz; z=x | y; // z = 126: 00000000 00000000 00000000 01111110
    3. Bitový XOR

      int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 intz; z=x^y; // z = 46: 00000000 00000000 00000000 00101110
    4. Levá směna se znakem

      int x = 31, z; // x: 00000000 00000000 00000000 00011111 z=x<< 2 ; // z = 124: 00000000 00000000 00000000 01111100
    5. Pravý posun se znaménkem

      int x = -17, z; z = x >> 2; // z = -5: 11111111 11111111 11111111 11111011
    6. Posun doprava bez znaménka

      int x = -17, z; // x: 11111111 11111111 11111111 11101111 z = x >>> 2; // z = 1073741819 // z: 00111111 11111111 11111111 11111011

    Kombinované operace

    V Javě můžete pro binární aritmetické operace použít kombinovaný(složené) znaky operace: identifikátor operace = výraz Toto je ekvivalentní následující operaci: identifikátor = výraz identifikátor operace Příklady:
    1. Výraz x += b znamená x = x + b .
    2. Výraz x -= b znamená x = x - b .
    3. Výraz x *= b znamená x = x * b .
    4. Výraz x /= b znamená x = x / b.
    5. Výraz x %= b znamená x = x % b .
    6. Výraz x &= b znamená x = x & b .
    7. Výraz x |= b znamená x = x | b.
    8. Výraz x ^= b znamená x = x ^ b .
    9. Výraz x<<= b означает x = x << b .
    10. Výraz x >>= b znamená x = x >> b .
    11. Výraz x >>>= b znamená x = x >>> b .

    Srovnávací operace

    Java definuje následující operátory porovnání:
    • " == " (rovná se), " !=" (není rovno),
    • " > " (větší než), " >= " (větší než nebo rovno),
    • " < " (меньше) " <= " (меньше или равно)
    mají dva operandy a vrátí booleovskou hodnotu odpovídající výsledku porovnání ( Nepravdivé nebo skutečný). Všimněte si, že při porovnávání dvou hodnot pro rovnost v Javě, jako v C a C++, symboly " == " (dvě po sobě jdoucí rovnítka bez mezery), na rozdíl od operátoru přiřazení, který používá znak " = ". Použití symbolu "=" při porovnávání dvou hodnot buď způsobí chybu při kompilaci, nebo vytvoří nesprávný výsledek. Příklady srovnávacích operací: boolean isEqual, isNonEqual, isGreater, isGreaterOrEqual, isLess, isLessOrEqual; int x1 = 5, x2 = 5, x3 = 3, x4 = 7; isEqual = x1 == x2; // isEqual = true isNonEqual = x1 != x2; // isNonEqual = false isGreater = x1 > x3; // jeVětší = true // jeVětšíNeboRovná = true jeVětšíNeboRovná = x2 >= x3; isLess = x3< x1; // isLess = true isLessOrEqual = x1 <= x3; // isLessOrEqual = false

    booleovské operace

    booleovské operace se provádějí na booleovských proměnných a jejich výsledkem je také hodnota typu booleovský. Java definuje následující booleovské operace:
    • negace "!" – nahrazení false za true nebo naopak;
    • operátor AND "&" – výsledek je pravdivý, pouze pokud jsou oba operandy pravdivé , jinak je výsledek nepravdivý ;
    • Operace OR " | " - výsledek je pravdivý pouze tehdy , je - li alespoň jeden z operandů pravdivý , jinak je výsledek nepravdivý .
    • Operátor XOR "^" - výsledek je pravdivý pouze v případě, že se operandy navzájem nerovnají, jinak je výsledek nepravdivý .
    Operátory "&", "|" a "^" a také odpovídající bitové operátory lze použít v operátorech složeného přiřazení: " &= ", " |= " a " ^= " Kromě toho operace " =" jsou použitelné pro booleovské operandy = " (rovná se) a " != " (není se rovná). Jak můžete vidět z definice operátorů OR a AND, operace OR se vyhodnotí jako true, když je první operand pravdivý, bez ohledu na hodnotu druhého operandu, a operace AND se vyhodnotí jako nepravda, když je první operand nepravdivý. bez ohledu na hodnotu druhého operandu. Java definuje další dva booleovské operátory: druhé verze booleovských operátorů AND a OR, známé jako zkratkové booleovské operátory: zkratovací AND " && " a zkratové OR " || ". Při použití těchto operací nebude druhý operand vůbec vyhodnocen, což je užitečné v případech, kdy správná funkce pravého operandu závisí na tom, zda je levý operand pravdivý nebo nepravdivý . Příklady booleovských operací: boolean isInRange, isValid, isNotValid, isEqual, isNotEqual; int x = 8; isInRange = x > 0 && x< 5 ; // isInRange = false isValid = x >0 || x > 5; // isValid = true isNotValid = ! je platná; // isNotValid = false isEqual = isInRange == isValid; // isEqual = false // isNotEqual = true isNotEqual = isInRange != isValid

    Podmíněný provoz

    Podmínkový operátor se zapisuje ve tvaru výraz-1?výraz-2:výraz-3 . To nejprve vyhodnotí výraz-1 , který by měl poskytnout booleovskou hodnotu, a poté, pokud je výraz-1 pravdivý , vyhodnotí a vrátí výraz-2 jako výsledek operace, nebo (pokud se výraz-1 vyhodnotí jako nepravda), vyhodnotí a , je vrácen výraz-3 jako výsledek operace. Příklad podmíněné operace: x= n> 1? 0:1; Proměnné x bude přiřazena hodnota 0, pokud n>1 (výraz n>1 se vyhodnotí jako pravda) nebo 1, pokud n≤1 (výraz n>1 se vyhodnotí jako nepravda).

    Přednost operace

    Operace ve výrazech se však provádějí zleva doprava, podle jejich priority. Takže operace násobení ve výrazu y = x + z* 5 ; se provede před operací sčítání, protože operace násobení má vyšší prioritu než operace sčítání. Priority operací (v pořadí klesající priority) v Javě jsou uvedeny v tabulce. 1.
    Závorky zvyšují prioritu operací, které jsou uvnitř nich. Pokud tedy do výše uvedeného výrazu vložíte závorky: y = (x + z) * 5 ; pak se nejprve provede operace sčítání a poté operace násobení. Někdy se závorky používají jednoduše, aby byl výraz čitelnější, například: (x > 1 ) && (x<= 5 ) ;

    Konverze typu a odlévání při provádění operací

    Operace přiřazení a aritmetické výrazy mohou používat literály, proměnné a výrazy různých typů, například: double y; bytex; y = x + 5; Tento příklad přidá bajtovou proměnnou x a literál 5 (typ int) a přiřadí výsledek dvojité proměnné y. V Javě, stejně jako v jazyce C, lze typové konverze při vyhodnocování výrazů provádět automaticky, nebo s pomocí operátoru přetypování. Pravidla pro přetypování se však poněkud liší od pravidel v jazyce C a obecně jsou přísnější než v jazyce C. Při provádění operace přiřazení dojde automaticky ke konverzi typu, pokud rozšiřující se transformace(rozšiřující konverze) a dva typy jsou kompatibilní. Rozšiřující se transformace jsou transformace byte® krátký® int® dlouho® plovák® dvojnásobek. Pro rozšiřující převody jsou číselné typy, včetně celého čísla a pohyblivé řádové čárky, vzájemně kompatibilní. Číselné typy však nejsou kompatibilní s typy char a boolean. Typy char a boolean také nejsou vzájemně kompatibilní. Jazyk Java také provádí automatickou konverzi typu při ukládání konstanty literálového celého čísla (která má ve výchozím nastavení typ int) do proměnných typu byte , short nebo long (pokud však literál má hodnotu mimo rozsah platných hodnot pro tohoto typu se zobrazí chybová zpráva: možná ztráta přesnosti). Pokud je převod zužující se (zužující převod), to znamená, že převod je byte ¬ krátký ¬ znak ¬ int ¬ dlouhý ¬ plovoucí ¬ double , může takový převod vést ke ztrátě přesnosti čísla nebo k jeho zkreslení. Zužující převody proto generují diagnostiku nekompatibility typů při kompilaci programu a soubory tříd se negenerují. Taková zpráva bude také vydána při pokusu o převod výrazů typu byte nebo short na proměnnou typu char . Pokud stále potřebujete provést takové převody, použijte operaci cast, která má následující formát: ( typ konverze) význam, Kde typ konverze definuje typ, na který se má daný údaj převést význam, například v důsledku provádění příkazů: byte x = 71 ; char symbol = (char ) x; proměnná symbol bude nastavena na " G ". Pokud je hodnota s plovoucí desetinnou čárkou přiřazena k typu celého čísla, pak (pokud má hodnota s plovoucí desetinnou čárkou zlomkovou část) dojde také k explicitní konverzi typu zkrácení(zkrácená) čísla. Takže jako výsledek provedení operátoru int x = (int ) 77,85 ; proměnná x získá hodnotu 77 . Pokud je přiřazená hodnota mimo rozsah typová konverze , pak výsledkem převodu bude zbytek vydělení hodnoty modulem rozsahu přiřazeného typu (pro čísla typového bajtu bude modul rozsahu 256 , zkráceně - 65536 , pro int - 4294967296 a na dlouho - 18446744073709551616). Například v důsledku provedení příkazu byte x = (byte) 514 ; proměnná x získá hodnotu 2 . Při převodu celých čísel nebo čísel s plovoucí desetinnou čárkou na char dojde k převodu na znak, pokud je původní číslo mezi 0 a 127, jinak je znak nastaven na "?". Při provádění aritmetických a bitových převodů jsou všechny bajtové a krátké hodnoty, stejně jako char , rozšířeny na int , (zatímco číselná hodnota znakového kódu se používá ve výpočtech pro char), pokud je alespoň jeden operand typu long , je typ celočíselného výrazu rozšířen na long . Pokud je jeden z operandů typu float, pak je typ úplného výrazu rozšířen na float, a pokud je jeden z operandů typu double, pak je typ výsledku double. Pokud tedy proměnné byte a, c; krátké b; pak ve výrazu a + b * c - 15 L + 1,5F + 1,08 - 10; nejprve se před vyhodnocením a + b*c hodnoty proměnných rozšíří na int, poté, protože konstanta 15 je typu long, bude výsledek výpočtu rozšířen na long before odečtením. Poté, protože literál 1.5 je typu float , bude výsledek vyhodnocení a + b*c - 15L před přidáním do tohoto literálu rozšířen na float. Před provedením sčítání s číslem 1,08 se výsledek předchozích výpočtů rozšíří na dvojnásobek (protože reálné konstanty jsou ve výchozím nastavení dvojnásobné) a nakonec před provedením posledního sčítání bude doslovný 10 (ve výchozím nastavení int). rozšířena na dvojnásobek. Výsledek vyhodnocení výrazu tedy bude typu double . Automatická rozšíření typu (zejména rozšíření short a byte to int) mohou způsobit špatně rozpoznatelné chyby při kompilaci. Například v příkazech: byte x = 30 , y = 5 ; x = x + y; hodnota x a y bude před provedením sčítání rozšířena na int a poté bude při pokusu o přiřazení výsledku výpočtu int bajtové proměnné vyvolána chyba. Aby se tomu zabránilo, musí být ve druhém operátoru použita explicitní konverze typu: x = (byte ) (x + y) ; Výraz x + y musí být v závorkách, protože priorita operace přetypování v závorkách je vyšší než priorita operátoru sčítání. Mimochodem, zapíšeme-li druhý operátor jako: x += y; pak nebude žádná chybová zpráva. Odkaz na první

    Logické operátory pracují pouze s operandy typu booleovský. Všechny logické operátory se dvěma operandy kombinují dvě logické hodnoty, aby vytvořily výslednou logickou hodnotu. Nezaměňujte s .

    Tabulka logických operátorů v Javě

    Logické operátory & , | , ^ pracovat s hodnotami typu booleovský stejným způsobem jako s ohledem na bity celočíselných hodnot. Booleovský operátor ! invertuje (obrátí) booleovský stav: !pravda == nepravda A !false == pravda.

    Stůl. Výsledky provádění logických operátorů

    ABA | BA&BA^B!A
    NepravdivéNepravdivéNepravdivéNepravdivéNepravdivéskutečný
    skutečnýNepravdivéskutečnýNepravdivéskutečnýNepravdivé
    NepravdivéskutečnýskutečnýNepravdivéskutečnýskutečný
    skutečnýskutečnýskutečnýskutečnýNepravdivéNepravdivé

    Zkratka Booleovské operátory

    Kromě standardních operátorů A (&) A NEBO (|) existují zkratky && A || .

    Pokud se podíváte na tabulku, můžete vidět, že výsledek provedení operátoru NEBO rovná se skutečný skutečný, bez ohledu na hodnotu operandu B. Podobně výsledek provedení operátoru A rovná se Nepravdivé když je hodnota operandu A Nepravdivé, bez ohledu na hodnotu operandu B. Ukazuje se, že hodnotu druhého operandu nemusíme počítat, pokud lze výsledek určit již z prvního operandu. To je výhodné v případech, kdy hodnota pravého operandu závisí na hodnotě levého.

    Zvažte následující příklad. Předpokládejme, že jsme zavedli pravidlo – krmit či nekrmit kočku, v závislosti na počtu ulovených myší za týden. Navíc počet myší závisí na váze kočky. Čím větší kočka, tím více myší musí chytit.

    Kocour, který si přečetl stav problému, se mnou urazil. Říkal, že jsem pozadu a na dvoře 21. století se myši dají chytat pastičkami na myši. Musel jsem mu vysvětlit, že je to jen problém, a ne příklad z jeho osobního života.

    intmouse; // počet myší int váha; // hmotnost kočky v gramech myš = 5; hmotnost = 4500; if (myš != 0 & váha / myš< 1000) { mInfoTextView.setText("Можно кормить кота"); }

    Pokud program spustíte, příklad bude fungovat bez problémů – pět myší týdně stačí k tomu, aby kočce dopřála chutnou snídani. Pokud chytí čtyři myši, začnou problémy s krmením kočky, ale ne s programem - bude fungovat, prostě nezobrazí zprávu o povolení krmit parazita.

    Nyní si vezměme extrémní případ. Kočka zlenivěla a nechytila ​​jedinou myš. Proměnná hodnota myš se bude rovnat 0 a ve výrazu je operátor dělení. Ale nemůžete dělit 0 a náš program se uzavře s chybou. Zdálo by se, že jsme zadali možnost s 0, ale Java vyhodnocuje oba výrazy myš !=0 A hmotnost / myš< 1000 , přesto, že již v prvním výrazu vrací Nepravdivé.

    Přepišme podmínku následovně (přidejte pouze jeden znak):

    If (myš != 0 && váha / myš< 1000) { mInfoTextView.setText("Можно кормить кота"); }

    Nyní program běží bez pádu. Jakmile Java viděla, že se vrátil první výraz Nepravdivé, pak je výraz druhého dělení jednoduše ignorován.

    Zkrácené operátory A A NEBO běžně používané v situacích, kdy jsou vyžadovány logické logické operátory a jejich jednoznakové příbuzné se používají pro bitové operace.

    Ternární operátor

    Jazyk Java má také speciální ternární podmíněný operátor, který lze použít k nahrazení určitých typů operátorů. Jestliže pak jinak je operátor ?:

    Ternární operátor používá tři operandy. Výraz je napsán v následujícím tvaru:

    Booleovská podmínka? výraz1: výraz2

    Li booleanCondition rovná se skutečný, pak se počítá výraz1 a jeho výsledek se stane výsledkem provedení celého příkazu. Li booleanCondition rovná se Nepravdivé, pak se počítá výraz2 a jeho hodnota se stane výsledkem operátora. Oba operandy výraz1 A výraz2 musí vrátit hodnotu stejného (nebo kompatibilního) typu.

    Zvažte příklad, ve kterém proměnná absval přiřazení absolutní hodnoty proměnné val.

    int absval, val; val = 5; absval = val< 0 ? -val: val; // выводим число mInfoTextView.setText("" + absval); val = -5; absval = val < 0 ? -val: val; mInfoTextView.setText("" + absval);

    variabilní absval bude přiřazena hodnota proměnné val pokud je hodnota větší nebo rovna nule (druhá část výrazu). Pokud je hodnota proměnné val je záporná, pak proměnná absval hodnota proměnné se přiřadí, vezme se se znaménkem mínus, v důsledku toho mínus krát mínus dá plus, tedy kladnou hodnotu. Přepišme kód pomocí pokud-jinak:

    If(val< 0) absval = -val; else absval = val;

    Můžete vidět další příklad s ternárním operátorem.

    Zkratujte logické operátory && a || určeno pro logické operace AND (AND) a OR (OR) na výrazech typu boolean . Všimněte si, že neexistuje žádný zkrácený logický operátor pro operaci XOR (exclusive OR).

    Logické operátory zkratek jsou podobné operátorům & a |, ale na rozdíl od nich se používají pouze na výrazy typu boolean a nikdy se nepoužívají na integrální typy. Nicméně, && a || mají pozoruhodnou vlastnost, že zkracují hodnocení výrazu, pokud lze výsledek odvodit z části výrazu (vysvětlím to na příkladech o něco později). Kvůli této vlastnosti jsou && a || široce používaný ke zpracování nulových výrazů. Pomáhají také zvýšit efektivitu celého programu.

    Vlastnost zkracování vyplývá přímo z rozdílu mezi &&/|| a &/|: poslední dvojice operátorů musí obdržet jako vstup hodnoty levého a pravého operátoru, zatímco u první dvojice operátorů někdy stačí znát hodnotu pouze levého operandu, aby se vrátil hodnotu celého výrazu. Toto chování zkrácených logických operátorů je založeno na dvou matematických pravidlech logické pravdivostní tabulky:

    • výraz s operátorem AND je nepravdivý, pokud je hodnota alespoň jednoho z jeho operandů nepravdivá;
    • výraz s operátorem OR je pravdivý, pokud je pravdivý alespoň jeden z jeho operandů.
    Jinými slovy:
    • nepravda A X = nepravda
    • pravda NEBO X = pravda
    To znamená, že pokud je levý operand výrazu AND nepravdivý, pak je nepravdivý celý výraz, bez ohledu na hodnotu pravého operandu. To znamená, že s falešným levým operandem není potřeba počítat hodnotu pravého operandu. Podobně, je-li levý operand výrazu OR pravdivý, pak jsou pravdivé všechny výrazy bez ohledu na hodnotu pravého operandu, kterou proto nemusíme vyhodnocovat.

    Zvažte příklad kódu, který vytiskne zprávu String, pokud řetězec nemá hodnotu null a je delší než 20 znaků:

    1. if ((s != null) && (s.length() > 20)) (
    2. System.out.println(s);
    3. }

    Stejný úkol může být kódován odlišně:

    1. if (s != null) (
    2. if (s.length() > 20) (
    3. System.out.println(s);
    4. }
    5. }

    Pokud by byl řetězec s null , pak když bychom zavolali metodu s.length(), dostali bychom výjimku NullPointerException . V žádném ze dvou příkladů kódu by však taková situace nenastala. Konkrétně ve druhém příkladu není s.length() voláno, když s = null , díky zkrácenému operátoru &&. Pokud test (s!=null) vrátil hodnotu false (false ), tedy s je neexistující řetězec, pak je zaručeno, že celý výraz bude nepravdivý. To znamená, že není potřeba počítat hodnotu druhého operandu, tedy výrazu (s.length()>20) .

    Tito operátoři však mají vedlejší účinky. Pokud je například pravý operand výraz, který provádí operaci, pak při použití zkrácených operátorů může tato operace selhat, pokud je levý operand nepravdivý.

    Zvažte příklad:
    // první příklad 1. int val = (int)(2 * Math.random()); 2. booleovský test = (val == 0) || (++val == 2); 3. System.out.println("test = " + test + "\nval = " + val); // druhý příklad 1. int val = (int)(2 * Math.random()); 2. booleovský test = (val == 0)|(++val == 2); 3. System.out.println("test = " + test + "\nval = " + val);
    První příklad někdy vytiskne něco takového:
    test=pravda
    val = 0

    A někdy toto:
    test=pravda
    val = 2

    Druhý příklad někdy vytiskne něco takového:
    test=pravda
    val = 1

    A někdy toto:
    test=pravda
    val = 2

    A tady je ta věc. Pokud je val 0, pak druhý operand (++val) nebude nikdy vyhodnocen, tj. val zůstane nula. Je-li na počátku hodnota rovna jedné, pak bude tato proměnná inkrementována a uvidíme val = 2 . Ve druhém příkladu pomocí Ne zkrácené příkazy, přírůstek se vždy provede a výsledek bude vždy buď 1 nebo 2, v závislosti na náhodné hodnotě zvolené v prvním kroku. V obou příkladech je test nastaven na hodnotu true, protože buď val = 0, nebo val = 1 a zvýší se na 2.

    Shrňme si informace o těsnopisných operátorech && a ||:

    • Platí pro operandy typu boolean ;
    • Hodnotu pravého operandu vyhodnotí pouze v případě, že výsledek nelze vypočítat z hodnoty levého operandu:
      • nepravda A X = nepravda
      • pravda NEBO X = pravda

    Většina operací na primitivních typech se neprovádí pomocí metod, ale pomocí speciálních volaných symbolů znamení operace.

    operace přiřazení

    Přiřazení hodnoty konstanty, jiné proměnné nebo výrazu (proměnné a/nebo konstanty oddělené znaménkem operátoru) se nazývá operace přiřazení a je označeno " = ", například: x = 3 ; y = x; z = x; V Javě je možné v jednom výrazu použít operátor přiřazení vícekrát, například: x1 = x2 = x3 = 0 ; Tato operace se provádí od zprava doleva, tj. nejprve je proměnné x3 přiřazena hodnota 0 , poté je x2 přiřazena hodnota x3 (0) a nakonec x1 je přiřazena hodnota x2 (0) Značky operací, jejichž argumenty jsou čísla, spadají do dvou kategorií : unární(unární) operační znaky s jedním argumentem a binární(binární) se dvěma argumenty.

    Unární operace

    Java definuje následující unární operace:
    • unární mínus "-" - změní znaménko čísla nebo výrazu na opačné;
    • unární plus " + " - neprovádí žádné operace s číslem nebo výrazem;
    • bitový doplněk "~" (pouze pro celá čísla) - invertuje všechny bity číselného pole (změní 0 na 1 a 1 na 0);
    • increment " ++ " (pouze pro celá čísla) – zvýší hodnotu proměnné o 1;
    • dekrementovat " -- " (pouze pro celá čísla) - snižuje hodnotu proměnné o 1.
    Příklady unárních operací "+" a "-": int i = 3 , j, k; j=-i; // j = -3 k = + i; // k = 3 Příklad operace bitového doplňku: int a = 15 ; intb; b=~a; // b = -16 Čísla a a b jsou int , tzn. jsou interně reprezentovány počítačem jako binární celá čísla se znaménkem o délce 32 bitů, takže binární reprezentace aab by vypadala takto: na 1 bit v b a 1 bit v a se změní na nulový bit. Desetinná reprezentace čísla b by byla -16. Značky operátoru zvýšení a snížení lze umístit před nebo za proměnnou. Tyto možnosti se nazývají resp předpona A postfix zaznamenávání těchto transakcí. Notace předpony přihlášení operátora vrací hodnotu svého operandu po hodnocení výrazu. S postfixovou notací znak operace nejprve vrátí hodnotu svého operandu a teprve poté vypočítá přírůstek nebo úbytek, například: int x = 1 , y, z; y=++x; z= x++; Proměnné y bude přiřazena hodnota 2, protože x bude nejprve zvýšeno o 1 a poté bude výsledek přiřazen k proměnné y. Proměnné z bude přiřazena hodnota 1, protože z bude nejprve přiřazena hodnota a poté bude x zvýšeno o 1 . V obou případech bude nová hodnota x 2 . Je třeba poznamenat, že v Javě lze na rozdíl od jazyka C operace dekrementace a inkrementace aplikovat i na reálné proměnné (typu float a double). Binární znaky operací se dělí na operace s číselným výsledkem a porovnávací operace, jejichž výsledkem je booleovská hodnota.

    Aritmetické binární operace

    Java definuje následující aritmetické binární operace:
    • přidání "+";
    • odčítání "-";
    • násobení " * ";
    • dělení "/";
    • výpočet zbytku dělení celých čísel " % " (vrátí zbytek dělení prvního čísla druhým a výsledek bude mít stejné znaménko jako dividenda), například výsledek operace 5% 3 bude 2 a výsledek operace (-7) %(-4) bude roven -3. V Javě lze operaci použít i pro reálné proměnné (typu float nebo double).
    Příklady binárních aritmetických operací: int x = 7, x1, x2, x3, x4, x5; x1 = x + 10; // x1 = 17 x2 = x - 8; // x2 = -1 x3 = x2 * x; // x3 = -7 x4 = x/4; // x4 = 1 (při dělení celých čísel // zlomková část je zahozena) x5 = x%4 // x5 = 3 (zbytek z dělení// 7 krát 4)

    Bitové operace

    • Bitové operace považují původní číselné hodnoty za pole bitů a provádějí s nimi následující operace:
    • nastavení rytmu na i-tá pozice výsledného pole je 1, pokud jsou oba bity uvnitř i-té pozice operandů jsou rovny 1 nebo 0, jinak bitově AND (" & ");
    • nastavení rytmu na i-tá pozice výsledného pole je 1, pokud je uvnitř alespoň jeden bit i-tá pozice operandů je 1 nebo 0 jinak - bitově OR (" | ");
    • nastavení rytmu na i-tá pozice výsledného pole je 1, pokud jsou bity v i-té pozice operandů se navzájem nerovnají, nebo jinak 0 - bitové exkluzivní OR (" ^ ");
    • posun doleva od bitů pole prvního operandu o počet bitů určený druhým operandem (znakový bit čísla se v tomto případě nemění) - bitový posun doleva s přihlédnutím ke znaménku "<< ";
    • posun vpravo od bitů pole prvního operandu o počet bitů určený druhým operandem (znaménkový bit čísla se v tomto případě nemění) – bitový posun vpravo s přihlédnutím ke znaménku " >>";
    • posun vpravo od bitů pole prvního operandu o počet bitů určený druhým operandem (v tomto případě je posunut znaménkový bit čísla) - bitový posun doprava bez zohlednění ">> > znak.
    Příklady bitových operací:
    1. Bitové AND

      int x = 112; int y = 94; intz; z=x & y; // z=80: 00000000 00000000 00000000 01010000
    2. Bitově NEBO

      int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 intz; z=x | y; // z = 126: 00000000 00000000 00000000 01111110
    3. Bitový XOR

      int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 intz; z=x^y; // z = 46: 00000000 00000000 00000000 00101110
    4. Levá směna se znakem

      int x = 31, z; // x: 00000000 00000000 00000000 00011111 z=x<< 2 ; // z = 124: 00000000 00000000 00000000 01111100
    5. Pravý posun se znaménkem

      int x = -17, z; z = x >> 2; // z = -5: 11111111 11111111 11111111 11111011
    6. Posun doprava bez znaménka

      int x = -17, z; // x: 11111111 11111111 11111111 11101111 z = x >>> 2; // z = 1073741819 // z: 00111111 11111111 11111111 11111011

    Kombinované operace

    V Javě můžete pro binární aritmetické operace použít kombinovaný(složené) znaky operace: identifikátor operace = výraz Toto je ekvivalentní následující operaci: identifikátor = výraz identifikátor operace Příklady:
    1. Výraz x += b znamená x = x + b .
    2. Výraz x -= b znamená x = x - b .
    3. Výraz x *= b znamená x = x * b .
    4. Výraz x /= b znamená x = x / b.
    5. Výraz x %= b znamená x = x % b .
    6. Výraz x &= b znamená x = x & b .
    7. Výraz x |= b znamená x = x | b.
    8. Výraz x ^= b znamená x = x ^ b .
    9. Výraz x<<= b означает x = x << b .
    10. Výraz x >>= b znamená x = x >> b .
    11. Výraz x >>>= b znamená x = x >>> b .

    Srovnávací operace

    Java definuje následující operátory porovnání:
    • " == " (rovná se), " !=" (není rovno),
    • " > " (větší než), " >= " (větší než nebo rovno),
    • " < " (меньше) " <= " (меньше или равно)
    mají dva operandy a vrátí booleovskou hodnotu odpovídající výsledku porovnání ( Nepravdivé nebo skutečný). Všimněte si, že při porovnávání dvou hodnot pro rovnost v Javě, jako v C a C++, symboly " == " (dvě po sobě jdoucí rovnítka bez mezery), na rozdíl od operátoru přiřazení, který používá znak " = ". Použití symbolu "=" při porovnávání dvou hodnot buď způsobí chybu při kompilaci, nebo vytvoří nesprávný výsledek. Příklady srovnávacích operací: boolean isEqual, isNonEqual, isGreater, isGreaterOrEqual, isLess, isLessOrEqual; int x1 = 5, x2 = 5, x3 = 3, x4 = 7; isEqual = x1 == x2; // isEqual = true isNonEqual = x1 != x2; // isNonEqual = false isGreater = x1 > x3; // jeVětší = true // jeVětšíNeboRovná = true jeVětšíNeboRovná = x2 >= x3; isLess = x3< x1; // isLess = true isLessOrEqual = x1 <= x3; // isLessOrEqual = false

    booleovské operace

    booleovské operace se provádějí na booleovských proměnných a jejich výsledkem je také hodnota typu booleovský. Java definuje následující booleovské operace:
    • negace "!" – nahrazení false za true nebo naopak;
    • operátor AND "&" – výsledek je pravdivý, pouze pokud jsou oba operandy pravdivé , jinak je výsledek nepravdivý ;
    • Operace OR " | " - výsledek je pravdivý pouze tehdy , je - li alespoň jeden z operandů pravdivý , jinak je výsledek nepravdivý .
    • Operátor XOR "^" - výsledek je pravdivý pouze v případě, že se operandy navzájem nerovnají, jinak je výsledek nepravdivý .
    Operátory "&", "|" a "^" a také odpovídající bitové operátory lze použít v operátorech složeného přiřazení: " &= ", " |= " a " ^= " Kromě toho operace " =" jsou použitelné pro booleovské operandy = " (rovná se) a " != " (není se rovná). Jak můžete vidět z definice operátorů OR a AND, operace OR se vyhodnotí jako true, když je první operand pravdivý, bez ohledu na hodnotu druhého operandu, a operace AND se vyhodnotí jako nepravda, když je první operand nepravdivý. bez ohledu na hodnotu druhého operandu. Java definuje další dva booleovské operátory: druhé verze booleovských operátorů AND a OR, známé jako zkratkové booleovské operátory: zkratovací AND " && " a zkratové OR " || ". Při použití těchto operací nebude druhý operand vůbec vyhodnocen, což je užitečné v případech, kdy správná funkce pravého operandu závisí na tom, zda je levý operand pravdivý nebo nepravdivý . Příklady booleovských operací: boolean isInRange, isValid, isNotValid, isEqual, isNotEqual; int x = 8; isInRange = x > 0 && x< 5 ; // isInRange = false isValid = x >0 || x > 5; // isValid = true isNotValid = ! je platná; // isNotValid = false isEqual = isInRange == isValid; // isEqual = false // isNotEqual = true isNotEqual = isInRange != isValid

    Podmíněný provoz

    Podmínkový operátor se zapisuje ve tvaru výraz-1?výraz-2:výraz-3 . To nejprve vyhodnotí výraz-1 , který by měl poskytnout booleovskou hodnotu, a poté, pokud je výraz-1 pravdivý , vyhodnotí a vrátí výraz-2 jako výsledek operace, nebo (pokud se výraz-1 vyhodnotí jako nepravda), vyhodnotí a , je vrácen výraz-3 jako výsledek operace. Příklad podmíněné operace: x= n> 1? 0:1; Proměnné x bude přiřazena hodnota 0, pokud n>1 (výraz n>1 se vyhodnotí jako pravda) nebo 1, pokud n≤1 (výraz n>1 se vyhodnotí jako nepravda).

    Přednost operace

    Operace ve výrazech se však provádějí zleva doprava, podle jejich priority. Takže operace násobení ve výrazu y = x + z* 5 ; se provede před operací sčítání, protože operace násobení má vyšší prioritu než operace sčítání. Priority operací (v pořadí klesající priority) v Javě jsou uvedeny v tabulce. 1.
    Závorky zvyšují prioritu operací, které jsou uvnitř nich. Pokud tedy do výše uvedeného výrazu vložíte závorky: y = (x + z) * 5 ; pak se nejprve provede operace sčítání a poté operace násobení. Někdy se závorky používají jednoduše, aby byl výraz čitelnější, například: (x > 1 ) && (x<= 5 ) ;

    Konverze typu a odlévání při provádění operací

    Operace přiřazení a aritmetické výrazy mohou používat literály, proměnné a výrazy různých typů, například: double y; bytex; y = x + 5; Tento příklad přidá bajtovou proměnnou x a literál 5 (typ int) a přiřadí výsledek dvojité proměnné y. V Javě, stejně jako v jazyce C, lze typové konverze při vyhodnocování výrazů provádět automaticky, nebo s pomocí operátoru přetypování. Pravidla pro přetypování se však poněkud liší od pravidel v jazyce C a obecně jsou přísnější než v jazyce C. Při provádění operace přiřazení dojde automaticky ke konverzi typu, pokud rozšiřující se transformace(rozšiřující konverze) a dva typy jsou kompatibilní. Rozšiřující se transformace jsou transformace byte® krátký® int® dlouho® plovák® dvojnásobek. Pro rozšiřující převody jsou číselné typy, včetně celého čísla a pohyblivé řádové čárky, vzájemně kompatibilní. Číselné typy však nejsou kompatibilní s typy char a boolean. Typy char a boolean také nejsou vzájemně kompatibilní. Jazyk Java také provádí automatickou konverzi typu při ukládání konstanty literálového celého čísla (která má ve výchozím nastavení typ int) do proměnných typu byte , short nebo long (pokud však literál má hodnotu mimo rozsah platných hodnot pro tohoto typu se zobrazí chybová zpráva: možná ztráta přesnosti). Pokud je převod zužující se (zužující převod), to znamená, že převod je byte ¬ krátký ¬ znak ¬ int ¬ dlouhý ¬ plovoucí ¬ double , může takový převod vést ke ztrátě přesnosti čísla nebo k jeho zkreslení. Zužující převody proto generují diagnostiku nekompatibility typů při kompilaci programu a soubory tříd se negenerují. Taková zpráva bude také vydána při pokusu o převod výrazů typu byte nebo short na proměnnou typu char . Pokud stále potřebujete provést takové převody, použijte operaci cast, která má následující formát: ( typ konverze) význam, Kde typ konverze definuje typ, na který se má daný údaj převést význam, například v důsledku provádění příkazů: byte x = 71 ; char symbol = (char ) x; proměnná symbol bude nastavena na " G ". Pokud je hodnota s plovoucí desetinnou čárkou přiřazena k typu celého čísla, pak (pokud má hodnota s plovoucí desetinnou čárkou zlomkovou část) dojde také k explicitní konverzi typu zkrácení(zkrácená) čísla. Takže jako výsledek provedení operátoru int x = (int ) 77,85 ; proměnná x získá hodnotu 77 . Pokud je přiřazená hodnota mimo rozsah typová konverze , pak výsledkem převodu bude zbytek vydělení hodnoty modulem rozsahu přiřazeného typu (pro čísla typového bajtu bude modul rozsahu 256 , zkráceně - 65536 , pro int - 4294967296 a na dlouho - 18446744073709551616). Například v důsledku provedení příkazu byte x = (byte) 514 ; proměnná x získá hodnotu 2 . Při převodu celých čísel nebo čísel s plovoucí desetinnou čárkou na char dojde k převodu na znak, pokud je původní číslo mezi 0 a 127, jinak je znak nastaven na "?". Při provádění aritmetických a bitových převodů jsou všechny bajtové a krátké hodnoty, stejně jako char , rozšířeny na int , (zatímco číselná hodnota znakového kódu se používá ve výpočtech pro char), pokud je alespoň jeden operand typu long , je typ celočíselného výrazu rozšířen na long . Pokud je jeden z operandů typu float, pak je typ úplného výrazu rozšířen na float, a pokud je jeden z operandů typu double, pak je typ výsledku double. Pokud tedy proměnné byte a, c; krátké b; pak ve výrazu a + b * c - 15 L + 1,5F + 1,08 - 10; nejprve se před vyhodnocením a + b*c hodnoty proměnných rozšíří na int, poté, protože konstanta 15 je typu long, bude výsledek výpočtu rozšířen na long before odečtením. Poté, protože literál 1.5 je typu float , bude výsledek vyhodnocení a + b*c - 15L před přidáním do tohoto literálu rozšířen na float. Před provedením sčítání s číslem 1,08 se výsledek předchozích výpočtů rozšíří na dvojnásobek (protože reálné konstanty jsou ve výchozím nastavení dvojnásobné) a nakonec před provedením posledního sčítání bude doslovný 10 (ve výchozím nastavení int). rozšířena na dvojnásobek. Výsledek vyhodnocení výrazu tedy bude typu double . Automatická rozšíření typu (zejména rozšíření short a byte to int) mohou způsobit špatně rozpoznatelné chyby při kompilaci. Například v příkazech: byte x = 30 , y = 5 ; x = x + y; hodnota x a y bude před provedením sčítání rozšířena na int a poté bude při pokusu o přiřazení výsledku výpočtu int bajtové proměnné vyvolána chyba. Aby se tomu zabránilo, musí být ve druhém operátoru použita explicitní konverze typu: x = (byte ) (x + y) ; Výraz x + y musí být v závorkách, protože priorita operace přetypování v závorkách je vyšší než priorita operátoru sčítání. Mimochodem, zapíšeme-li druhý operátor jako: x += y; pak nebude žádná chybová zpráva. Odkaz na první