Към съдържанието
wannacode

Променливи и типове

Проблем

Цената е на три места

В онлайн магазина една цена се появява на няколко места: в каталога, в количката и при плащането. Ако е написана навсякъде с числа, ето какво става:

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 бр.
Намаление: true
  • int: цяло число, например брой.
  • 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 seats = 40;
int seatsAtStart = seats;
seats = 37;
System.out.println("В началото: " + seatsAtStart);
System.out.println("Сега: " + seats);
Изход
В началото: 40
Сега: 37

seatsAtStart получава 40. После seats става 37, но копието в seatsAtStart си остава 40.

Пробвай

Коя стойност остава?

Какво ще отпечата програмата?

int roomA = 12;
int roomB = 20;
roomA = roomB;
roomB = 25;
System.out.println(roomA + " и " + roomB);
Отговор

Проблем

Размерите са разменени

Програма за печат на снимки получава размерите разменени: ширина 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
Стъпка по стъпка, с думи
  1. Ширината и височината са въведени разменени: 120 и 80.
  2. temp = width: копие на 120 отива в temp. В width си остава 120.
  3. width = height: копие на 80 влиза в width. Старото 120 оттам изчезва, но е запазено в temp.
  4. height = temp: 120 се връща от temp в height.
  5. Разменени са: 80 x 120.

В наивния вариант width = height записва 80 в width, а старото 120 изчезва. Когато после height = width, в width вече има 80 и то се копира обратно.

Поправката е трета, помощна променлива temp. Тя пази 120, преди width да бъде презаписана. После 120 отива от temp в height и размерите излизат 80 x 120.

Пробвай

Подреди размяната

В магазина двама колеги си разменят смените. morning е „Иван“, а evening е „Мария“. Подреди редовете така, че да се разменят.

  1. System.out.println("Сутрин: " + morning + ", вечер: " + evening);
  2. evening = temp;
  3. morning = evening;
  4. 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, долу 15

2. Възраст. Запиши име и възраст в две променливи и ги отпечатай в изречение.

Изход
Мария е на 19 години.

3. Карта на хотел. Запиши в променливи името на хотела (текст), звездите (цяло число), оценката (дробно), дали има закуска (да или не) и категорията (един символ). Отпечатай ги.

Изход
Хотел „Морска звезда“
Звезди: 4
Оценка: 8.7
Закуска: true
Категория: B

Още задачи

  • Три в кръг. Три каси имат съответно 120, 85 и 240 € в началото на деня. Премести сумите в кръг: първата отива във втората, втората в третата, третата в първата. Ползвай една помощна променлива. Отпечатай 240 120 85.
  • Същото с var. Препиши задача 3 с var навсякъде. Изходът не трябва да се промени.
  • Нарочна грешка. Запиши текст в int и дробно число в int. Прочети какво казва компилаторът.

Тест

Провери се

1. Какво прави редът int count = 5;?
2. Кой тип е за цена като 12.99?
3. int a = 5; int b = a; a = 9; Колко е b?
4. Защо размяната на две стойности иска трета променлива?
5. След var nights = 3; какво е вярно?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·