Променливи и типове
Проблем
Цената е на три места
В онлайн магазина една цена се появява на няколко места: в каталога, в количката и при плащането. Ако е написана навсякъде с числа, ето какво става:
Console.WriteLine("Слушалки: 49.90 €");Console.WriteLine("В количката: слушалки, 49.90 €");Console.WriteLine("За плащане: 49.90 €");Утре слушалките са в намаление. Трябва да намериш и поправиш всяко 49.90. Пропуснеш ли едно, клиентът вижда две различни цени.
Идеята
Променлива: име за стойност
Запиши цената веднъж и ѝ дай име. После навсякъде пиши името.
double price = 49.90;Console.WriteLine("Слушалки: " + price + " €");Console.WriteLine("В количката: слушалки, " + price + " €");Console.WriteLine("За плащане: " + price + " €");Слушалки: 49.9 €В количката: слушалки, 49.9 €За плащане: 49.9 €double price = 49.90; създава променлива: място в паметта с име (price), тип (double, дробно число) и стойност (49.90). Където в кода пише price, програмата взима стойността оттам.
+ между текст и стойност ги слепва в един текст. Затова интервалите са вътре в кавичките.
Нулата накрая изчезна: 49.90 излезе като 49.9. За числото това е едно и също. Как да покажеш цената с два знака след запетаята, ще видим в урока за вход и изход.
По-точно, за любопитните
- Името започва с буква, без интервали. Пиши го с малка буква, а всяка следваща дума с главна:
price,pricePerNight. Главните и малките букви имат значение:priceиPriceса две различни имена.
- Езикът позволява и имена на кирилица (
цена), но не го прави. Целият код по света е с латински имена и така ще пишат и колегите ти.
- Променлива, на която още не си дал стойност, не може да се ползва. Компилаторът спира с грешка.
- Ако на твоя компютър излиза
49,9със запетая, това са българските регионални настройки. C# ги следва, когато превръща число в текст. Примерите в курса са с точка.
Идеята
Видове стойности
Типът казва какво може да пази променливата. Ето основните:
string name = "Раница";double price = 39.90;int stock = 12;bool onSale = true;char size = 'M';Console.WriteLine(name + ", размер " + size);Console.WriteLine("Цена: " + price + " €");Console.WriteLine("Наличност: " + stock + " бр.");Console.WriteLine("Намаление: " + onSale);Раница, размер MЦена: 39.9 €Наличност: 12 бр.Намаление: Trueint: цяло число, например брой.double: дробно число, например цена или тегло. В кода десетичният знак е точка:39.90.bool: да или не,trueилиfalse.char: един символ, в единични кавички:'M'.string: текст, в двойни кавички:"Раница". Това е низ (string), поредица от символи.
true в кода се отпечатва като True. Така C# превръща логическите стойности в текст.
По-точно, за любопитните
string е друго име за System.String. Простите типове (int, double, bool, char и т.н.) пазят самата стойност. string е референтен тип: променливата пази връзка към текста. Разликата ще има значение в модул „Класове и обекти“.
Числовите и другите прости типове в C#:
| Тип | Размер | Стойности |
|---|---|---|
byte |
1 байт | от 0 до 255 (без знак) |
sbyte |
1 байт | от -128 до 127 |
short |
2 байта | от -32 768 до 32 767 |
ushort |
2 байта | от 0 до 65 535 (без знак) |
int |
4 байта | от -2 147 483 648 до 2 147 483 647 |
uint |
4 байта | от 0 до 4 294 967 295 (без знак) |
long |
8 байта | от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 |
ulong |
8 байта | от 0 до 18 446 744 073 709 551 615 (без знак) |
float |
4 байта | дробно, до около ±3,4 · 10³⁸, около 6–9 значещи цифри |
double |
8 байта | дробно, до около ±1,8 · 10³⁰⁸, около 15–17 значещи цифри |
decimal |
16 байта | дробно, до около ±7,9 · 10²⁸, 28–29 значещи цифри, точно в десетична бройна система |
char |
2 байта | един символ от Unicode, кодове от 0 до 65 535 |
bool |
1 байт | true или false |
u в името значи unsigned, без знак: само нула и положителни числа. byte е без знак и без u, а неговият вариант със знак е sbyte. decimal е типът за пари. double пази числата в двоична система и някои дробни стойности като 0.1 не стават точно. При сума от хиляди плащания тези малки разлики се трупат.
Числото в кода е int или double, освен ако не кажеш друго. L накрая прави число long, f прави число float, m прави число decimal. Без m редът decimal balance = 1250.75; не се компилира. Долна черта между цифрите само помага да се четат:
long population = 8_100_000_000L;float weight = 1.5f;decimal balance = 1250.75m;Console.WriteLine(population + " " + weight + " " + balance);8100000000 1.5 1250.75Пробвай
Намери грешката
Програмата трябва да отпечата една покупка. Тя не се компилира. На кой ред е грешката?
Избери реда с грешката.
int пази само цели числа, а 2.40 е дробно. Компилаторът не изрязва дробната част тихомълком, а спира: „CS0266: Cannot implicitly convert type 'double' to 'int'“. Цената трябва да е double price = 2.40;.Идеята
= записва копие
Знакът = не е „равно“ като в математиката. Той значи: вземи стойността отдясно и я запиши в променливата отляво. Това се казва присвояване. Старата стойност на променливата изчезва.
Когато отдясно е друга променлива, записва се копие на стойността ѝ в този момент. Двете променливи не остават свързани:
int seats = 40;int seatsAtStart = seats;seats = 37;Console.WriteLine("В началото: " + seatsAtStart);Console.WriteLine("Сега: " + seats);В началото: 40Сега: 37seatsAtStart получава 40. После seats става 37, но копието в seatsAtStart си остава 40.
Пробвай
Коя стойност остава?
Какво ще отпечата програмата?
int roomA = 12;int roomB = 20;roomA = roomB;roomB = 25;Console.WriteLine(roomA + " и " + roomB);roomA = roomB записва в roomA копие на 20. Когато после roomB става 25, roomA не се променя.
Проблем
Размерите са разменени
Програма за печат на снимки получава размерите разменени: ширина 120 и височина 80, а трябва да са 80 x 120. Изглежда, че стига да запишеш едното в другото и обратно:
int width = 120;int height = 80;width = height;height = width;Console.WriteLine(width + " x " + height);80 x 80Излезе 80 x 80. Къде отиде 120?
Виж го
Размяна с помощна променлива
int width = 120;int height = 80;int temp = width;width = height;height = temp;Console.WriteLine(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 е „Мария“. Подреди редовете така, че да се разменят.
string temp = morning;Console.WriteLine("Сутрин: " + morning + ", вечер: " + evening);morning = evening;evening = temp;
Идеята
var: типът се подразбира
Когато типът личи от стойността, можеш вместо него да напишеш var:
var city = "Пловдив";var nights = 3;var pricePerNight = 65.0;Console.WriteLine(city + ": " + nights + " нощувки по " + pricePerNight + " €");Пловдив: 3 нощувки по 65 €Компилаторът сам вижда, че "Пловдив" е текст, 3 е int, а 65.0 е double. Това се казва извеждане на типа (type inference).
var не значи „без тип“. Типът е решен от първата стойност и после не се сменя:
var nights = 3;nights = "три";error CS0029: Cannot implicitly convert type 'string' to 'int'В курса най-често ще пишем типа изрично, за да го виждаш.
По-точно, за любопитните
varиска стойност веднага:var nights;не се компилира, защото няма откъде да се разбере типът.varе само за променливи вътре в Main (и в другите методи, които идват в модул „Методи“).
- В C# има и
dynamic: при него типът се проверява чак докато програмата работи, а не при компилиране. Ползва се рядко, при данни от други системи. В курса няма да ни трябва.
Упражнение
Твоите променливи
Реши задачите в редактора си. Стойностите са записани в кода, без четене от клавиатурата. Четенето е в следващия урок.
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. Прочети какво казва компилаторът.
Тест