Променливи и типове
Проблем
Цената е на три места
В онлайн магазина една цена се появява на няколко места: в каталога, в количката и при плащането. Ако е написана навсякъде с числа, ето какво става:
System.out.println("Слушалки: 49.90 €");System.out.println("В количката: слушалки, 49.90 €");System.out.println("За плащане: 49.90 €");Утре слушалките са в намаление. Трябва да намериш и поправиш всяко 49.90. Пропуснеш ли едно, клиентът вижда две различни цени.
Идеята
Променлива: име за стойност
Запиши цената веднъж и ѝ дай име. После навсякъде пиши името.
double price = 49.90;System.out.println("Слушалки: " + price + " €");System.out.println("В количката: слушалки, " + price + " €");System.out.println("За плащане: " + price + " €");Слушалки: 49.9 €В количката: слушалки, 49.9 €За плащане: 49.9 €double price = 49.90; създава променлива: място в паметта с име (price), тип (double, дробно число) и стойност (49.90). Където в кода пише price, програмата взима стойността оттам.
+ между текст и стойност ги слепва в един текст. Затова интервалите са вътре в кавичките.
Нулата накрая изчезна: 49.90 излезе като 49.9. За числото това е едно и също. Как да покажеш цената с два знака след запетаята, ще видим в урока за вход и изход.
По-точно, за любопитните
- Името започва с буква, без интервали. Пиши го с малка буква, а всяка следваща дума с главна:
price,pricePerNight. Главните и малките букви имат значение:priceиPriceса две различни имена.
- Езикът позволява и имена на кирилица (
цена), но не го прави. Целият код по света е с латински имена и така ще пишат и колегите ти.
- Променлива, на която още не си дал стойност, не може да се ползва. Компилаторът спира с грешка.
Идеята
Видове стойности
Типът казва какво може да пази променливата. Ето основните:
String name = "Раница";double price = 39.90;int stock = 12;boolean onSale = true;char size = 'M';System.out.println(name + ", размер " + size);System.out.println("Цена: " + price + " €");System.out.println("Наличност: " + stock + " бр.");System.out.println("Намаление: " + onSale);Раница, размер MЦена: 39.9 €Наличност: 12 бр.Намаление: trueint: цяло число, например брой.double: дробно число, например цена или тегло. В кода десетичният знак е точка:39.90.boolean: да или не,trueилиfalse.char: един символ, в единични кавички:'M'.String: текст, в двойни кавички:"Раница". Това е низ (string), поредица от символи.
По-точно, за любопитните
String е с главна буква, защото не е прост тип като int, а клас. Простите типове (int, double, boolean, char и т.н.) пазят самата стойност. String е референтен тип: променливата пази връзка към текста. Разликата ще има значение в модул „Класове и обекти“.
Всички прости типове в Java:
| Тип | Размер | Стойности |
|---|---|---|
byte |
1 байт | от -128 до 127 |
short |
2 байта | от -32 768 до 32 767 |
int |
4 байта | от -2 147 483 648 до 2 147 483 647 |
long |
8 байта | от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 |
float |
4 байта | дробно, до около ±3,4 · 10³⁸, около 7 значещи цифри |
double |
8 байта | дробно, до около ±1,8 · 10³⁰⁸, около 15–16 значещи цифри |
char |
2 байта | един символ от Unicode, кодове от 0 до 65 535 |
boolean |
не е определен | true или false |
Числото в кода е int или double, освен ако не кажеш друго. L накрая прави число long, f прави число float. Долна черта между цифрите само помага да се четат:
long population = 8_100_000_000L;float weight = 1.5f;byte level = 120;System.out.println(population + " " + weight + " " + level);8100000000 1.5 120В Java няма decimal. За пари истинските програми ползват класа BigDecimal. В курса за кратко пишем цените като double.
Пробвай
Намери грешката
Програмата трябва да отпечата една покупка. Тя не се компилира. На кой ред е грешката?
Избери реда с грешката.
int пази само цели числа, а 2.40 е дробно. Компилаторът не изрязва дробната част тихомълком, а спира: „incompatible types: possible lossy conversion from double to int“. Цената трябва да е double price = 2.40;.Идеята
= записва копие
Знакът = не е „равно“ като в математиката. Той значи: вземи стойността отдясно и я запиши в променливата отляво. Това се казва присвояване. Старата стойност на променливата изчезва.
Когато отдясно е друга променлива, записва се копие на стойността ѝ в този момент. Двете променливи не остават свързани:
int seats = 40;int seatsAtStart = seats;seats = 37;System.out.println("В началото: " + seatsAtStart);System.out.println("Сега: " + seats);В началото: 40Сега: 37seatsAtStart получава 40. После seats става 37, но копието в seatsAtStart си остава 40.
Пробвай
Коя стойност остава?
Какво ще отпечата програмата?
int roomA = 12;int roomB = 20;roomA = roomB;roomB = 25;System.out.println(roomA + " и " + roomB);roomA = roomB записва в roomA копие на 20. Когато после roomB става 25, roomA не се променя.
Проблем
Размерите са разменени
Програма за печат на снимки получава размерите разменени: ширина 120 и височина 80, а трябва да са 80 x 120. Изглежда, че стига да запишеш едното в другото и обратно:
int width = 120;int height = 80;width = height;height = width;System.out.println(width + " x " + height);80 x 80Излезе 80 x 80. Къде отиде 120?
Виж го
Размяна с помощна променлива
int width = 120;int height = 80;int temp = width;width = height;height = temp;System.out.println(width + " x " + height); // 80 x 120Стъпка по стъпка, с думи
- Ширината и височината са въведени разменени: 120 и 80.
- temp = width: копие на 120 отива в temp. В width си остава 120.
- width = height: копие на 80 влиза в width. Старото 120 оттам изчезва, но е запазено в temp.
- height = temp: 120 се връща от temp в height.
- Разменени са: 80 x 120.
В наивния вариант width = height записва 80 в width, а старото 120 изчезва. Когато после height = width, в width вече има 80 и то се копира обратно.
Поправката е трета, помощна променлива temp. Тя пази 120, преди width да бъде презаписана. После 120 отива от temp в height и размерите излизат 80 x 120.
Пробвай
Подреди размяната
В магазина двама колеги си разменят смените. morning е „Иван“, а evening е „Мария“. Подреди редовете така, че да се разменят.
System.out.println("Сутрин: " + morning + ", вечер: " + evening);evening = temp;morning = evening;String temp = morning;
Идеята
var: типът се подразбира
Когато типът личи от стойността, можеш вместо него да напишеш var:
var city = "Пловдив";var nights = 3;var pricePerNight = 65.0;System.out.println(city + ": " + nights + " нощувки по " + pricePerNight + " €");Пловдив: 3 нощувки по 65.0 €Компилаторът сам вижда, че "Пловдив" е текст, 3 е int, а 65.0 е double. Това се казва извеждане на типа (type inference).
var не значи „без тип“. Типът е решен от първата стойност и после не се сменя:
var nights = 3;nights = "три";error: incompatible types: String cannot be converted to intВ курса най-често ще пишем типа изрично, за да го виждаш.
По-точно, за любопитните
varиска стойност веднага:var nights;не се компилира, защото няма откъде да се разбере типът.varе само за променливи вътре в main (и в другите методи, които идват в модул „Методи“).
varе в Java от версия 10.
Упражнение
Твоите променливи
Реши задачите в редактора си. Стойностите са записани в кода, без четене от клавиатурата. Четенето е в следващия урок.
1. Размяна. На горния рафт има 15 книги, на долния 27. Запиши ги в две променливи, размени стойностите им и отпечатай преди и след.
Преди: горе 15, долу 27След: горе 27, долу 152. Възраст. Запиши име и възраст в две променливи и ги отпечатай в изречение.
Мария е на 19 години.3. Карта на хотел. Запиши в променливи името на хотела (текст), звездите (цяло число), оценката (дробно), дали има закуска (да или не) и категорията (един символ). Отпечатай ги.
Хотел „Морска звезда“Звезди: 4Оценка: 8.7Закуска: trueКатегория: BОще задачи
- Три в кръг. Три каси имат съответно 120, 85 и 240 € в началото на деня. Премести сумите в кръг: първата отива във втората, втората в третата, третата в първата. Ползвай една помощна променлива. Отпечатай 240 120 85.
- Същото с
var. Препиши задача 3 сvarнавсякъде. Изходът не трябва да се промени. - Нарочна грешка. Запиши текст в
intи дробно число вint. Прочети какво казва компилаторът.
Тест