В настоящата глава ще разгледаме условните конструкции в езика C#, чрез които нашата програма може да има различно действие, в зависимост от дадено условие. Ще обясним синтаксиса на условните оператори за проверки (if
и if-else
) с подходящи примери и ще видим в какъв диапазон живее една променлива (нейният обхват). Накрая ще разгледаме техники за дебъгване, чрез които постъпково да проследяваме пътя, който извървява нашата програма по време на своето изпълнение.
В програмирането можем да сравняваме стойности чрез следните оператори:
- Оператор
<
(по-малко) - Оператор
>
(по-голямо) - Оператор
<=
(по-малко или равно) - Оператор
>=
(по-голямо или равно) - Оператор
==
(равно) - Оператор
!=
(различно)
При сравнение резултатът е булева стойност – true
или false
, в зависимост от това дали резултатът от сравнението е истина или лъжа.
Обърнете внимание, че при отпечатване на стойностите true
и false
в езика C#, те се отпечатват с главна буква, съответно True
и False
.
В езика C# можем да използваме следните оператори за сравнение на данни:
Оператор | Означение | Работи за |
---|---|---|
Проверка за равенство | == | числа, стрингове, дати |
Проверка за различие | != | |
По-голямо | > | числа, дати, други сравними типове |
По-голямо или равно | >= | |
По-малко | < | |
По-малко или равно | <= |
Ето един пример:
В програмирането често проверяваме дадени условия и извършваме различни действия, според резултата от проверката. Това става чрез проверката if
, която има следната конструкция:
if (булев израз)
{
// тяло на условната конструкция;
}
Въвеждаме оценка в конзолата и проверяваме дали тя е отлична (≥ 5.50
).
Тествайте кода от примера локално. Опитайте да въведете различни оценки, например 4.75, 5.49, 5.50 и 6.00. При оценки по-малки от 5.50 програмата няма да изведе нищо, а при оценка 5.50 или по-голяма, ще изведе “Excellent!”.
Тествайте програмата от примера в judge системата на СофтУни: https://judge.softuni.org/Contests/Practice/Index/506#0.
Конструкцията if
може да съдържа и else
клауза, с която да окажем конкретно действие в случай, че булевият израз (който е зададен в началото if (булев израз)
) върне отрицателен резултат (false
). Така построена, условната конструкция наричаме if-else
и поведението ѝ е следното: ако резултатът от условието е позитивен (true
) - извършваме едни действия, a когато е негативен (false
) - други. Форматът на конструкцията е:
if (булево условие)
{
// тяло на условната конструкция;
}
else
{
// тяло на else-конструкция;
}
Подобно на горния пример, въвеждаме оценка, проверяваме дали е отлична, но изписваме резултат и в двата случая.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#1.
Когато имаме само една команда в тялото на if
конструкцията, можем да пропуснем къдравите скоби, обозначаващи тялото на условния оператор. Когато искаме да изпълним блок от код (група команди), къдравите скоби са задължителни. В случай че ги изпуснем, ще се изпълни само първият ред след if
клаузата.
Добра практика е, винаги да слагаме къдрави скоби, понеже това прави кода ни по-четим и по-подреден. |
Ето един пример, в който изпускането на къдравите скоби води до объркване:
Изпълнението на горния код ще изведе следния резултат на конзолата:
С къдрави скоби:
На конзолата ще бъде отпечатано следното:
Да се напише програма, която проверява, дали дадено цяло число е четно (even) или нечетно (odd).
Задачата можем да решим с помощта на една if-else
конструкция и оператора %
, който връща остатък при деление на две числа.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#2.
Да се напише програма, която чете две цели числа и извежда по-голямото от тях.
Първата ни задача е да прочетем двете числа. След което, чрез проста if-else
конструкция, в съчетание с оператора за по-голямо (>
), да направим проверка. Част от кода е замъглена умишлено, за да изпробваме наученото до момента.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#3.
Всяка една променлива си има обхват, в който съществува, наречен variable scope. Този обхват уточнява къде една променлива може да бъде използвана. В езика C# областта, в която една променлива съществува, започва от реда, на който сме я дефинирали и завършва до първата затваряща къдрава скоба } (на метода, на if
конструкцията и т.н.). За това е важно да знаем, че всяка променлива, дефинирана вътре в тялото на if
, няма да бъде достъпна извън него, освен ако не сме я дефинирали по-нагоре в кода.
В примера по-долу, на последния ред, на който се опитваме да отпечатаме променливата salary
, която е дефинирана в if
конструкцията, ще получим грешка, защото нямаме достъп до нея.
Понякога се налага да извършим серия от проверки, преди да решим какви действия ще изпълнява нашата програма. В такива случаи, можем да приложим конструкцията if-else if…-else
в серия. За целта използваме следния формат:
if (условие)
{
// тяло на условната конструкция;
}
else if (условие2)
{
// тяло на условната конструкция;
}
else if (условие3)
{
// тяло на условната конструкция;
}
…
else
{
// тяло на else-конструкция;
}
Да се изпише число в интервала от 1 до 9 с текст на английски език (числото се чете от конзолата). Можем да прочетем числото и след това чрез серия от проверки отпечатваме съответстващата му английска дума:
int num = int.Parse(Console.ReadLine());
if (num == 1)
{
Console.WriteLine("one");
}
else if (num == 2)
{
Console.WriteLine("two");
}
else if (…)
{
…
}
else if (num == 9)
{
Console.WriteLine("nine");
}
else
{
Console.WriteLine("number too big");
}
Програмната логика от примера по-горе последователно сравнява входното число от конзолата с цифрите от 1 до 9, като всяко следващо сравнение се извършва, само в случай че предходното сравнение не е било истина. В крайна сметка, ако никое от if
условията не е изпълнено, се изпълнява последната else
клаузa.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#4.
За да затвърдим знанията си за условните конструкции if
и if-else
, ще решим няколко практически задачи.
Дадено е цяло число – брой точки. Върху него се начисляват бонус точки по правилата, описани по-долу. Да се напише програма, която пресмята бонус точките за това число и общия брой точки с бонусите.
- Ако числото е до 100 включително, бонус точките са 5.
- Ако числото е по-голямо от 100, бонус точките са 20% от числото.
- Ако числото е по-голямо от 1000, бонус точките са 10% от числото.
- Допълнителни бонус точки (начисляват се отделно от предходните):
- За четно число -> + 1 т.
- За число, което завършва на 5 -> + 2 т.
Вход | Изход |
---|---|
20 | 6 26 |
175 | 37 212 |
2703 | 270.3 2973.3 |
15875 | 1589.5 17464.5 |
Основните и допълнителните бонус точки можем да изчислим с поредица от няколко if-else-if-else
проверки. Като за основните бонус точки имаме 3 случая (когато въведеното число е до 100, между 100 и 1000 и по-голямо от 1000), а за допълнителните бонус точки - още 2 случая (когато числото е четно и нечетно).
Ето как би могло да изглежда решението на задачата в действие:
Обърнете внимание, че за тази задача judge е настроен да игнорира всичко, което не е число, така че можем да печатаме не само числата, но и уточняващ текст.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#5.
Трима спортни състезатели финишират за някакъв брой секунди (между 1 и 50). Да се напише програма, която въвежда времената на състезателите и пресмята сумарното им време във формат "минути:секунди". Секундите да се изведат с водеща нула (2 -> "02", 7 -> "07", 35 -> "35").
Вход | Изход |
---|---|
35 45 44 |
2:04 |
22 7 34 |
1:03 |
50 50 49 |
2:29 |
14 12 10 |
0:36 |
Първо сумираме трите числа, за да получим общия резултат в секунди. Понеже 1 минута = 60 секунди, ще трябва да изчислим броя минути и броя секунди в диапазона от 0 до 59:
- Ако резултатът е между 0 и 59, отпечатваме 0 минути + изчислените секунди.
- Ако резултатът е между 60 и 119, отпечатваме 1 минута + изчислените секунди минус 60.
- Ако резултатът е между 120 и 179, отпечатваме 2 минути + изчислените секунди минус 120.
- Ако секундите са по-малко от 10, извеждаме водеща нула преди тях.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#6.
Да се напише програма, която преобразува разстояние между следните 8 мерни единици: m
, mm
, cm
, mi
, in
, km
, ft
, yd
. Използвайте съответствията от таблицата по-долу:
Входна единица | Изходна единица |
---|---|
1 meter (m) | 1000 millimeters (mm) |
1 meter (m) | 100 centimeters (cm) |
1 meter (m) | 0.000621371192 miles (mi) |
1 meter (m) | 39.3700787 inches (in) |
1 meter (m) | 0.001 kilometers (km) |
1 meter (m) | 3.2808399 feet (ft) |
1 meter (m) | 1.0936133 yards (yd) |
Входните данни се състоят от три реда:
- Първи ред: число за преобразуване.
- Втори ред: входна мерна единица.
- Трети ред: изходна мерна единица (за резултата).
Вход | Изход |
---|---|
12 km ft |
39370.0788 |
150 mi in |
9503999.99393599 |
450 yd km |
0.41147999937455 |
Прочитаме си входните данни, като към прочитането на мерните единици можем да добавим функцията ToLower()
, която ще направи всички букви малки. Както виждаме от таблицата в условието, можем да конвертираме само между метри и някаква друга мерна единица. Следователно трябва първо да изчислим числото за преобразуване в метри. Затова трябва да направим набор от проверки, за да определим каква е входната мерна единица, а след това и за изходната мерна единица.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#7.
До момента писахме доста код и често пъти в него имаше грешки, нали? Сега ще покажем един инструмент, с който можем да намираме грешките по-лесно.
Дебъгване е процесът на „закачане“ към изпълнението на програмата, който ни позволява да проследим поетапно процеса на изпълнение. Можем да следим ред по ред какво се случва с нашата програма, какъв път следва, какви стойности имат дефинираните променливи на всяка стъпка от дебъгването и много други неща, които ни позволяват да откриваме грешки (бъгове).
Чрез натискане на бутона [F10], стартираме програмата в debug режим. Преминаваме към следващия ред отново с [F10].
Чрез [F9] създаваме стопери – така наречените breakpoints, до които можем да стигнем директно използвайки [F5] при стартирането на програмата.
Нека затвърдим наученото в тази глава с няколко задачи.
Създаваме празно решение (Blank Solution) във Visual Studio, за да организираме по-добре решенията на задачите от упражненията – всяка задача ще бъде в отделен проект и всички проекти ще бъдат в общ solution.
Стартираме Visual Studio. Създаваме нов Blank Solution: [File] -> [New] -> [Project].
Избираме от диалоговия прозорец [Templates] -> [Other Project Types] -> [Visual Studio Solutions] -> [Blank Solution] и даваме подходящо име на проекта, например “Simple-Conditions”:
Сега имаме създаден празен Visual Studio Solution (без проекти в него):
Първата задача от упражненията за тази тема е да се напише конзолна програма, която въвежда оценка (десетично число) и отпечатва “Excellent!”, ако оценката е 5.50 или по-висока.
Вход | Изход |
---|---|
6 | Excellent! |
5 | (няма изход) |
5.5 | Excellent! |
5.49 | (няма изход) |
Създаваме нов проект в съществуващото Visual Studio решение. В Solution Explorer кликваме с десен бутон на мишката върху Solution 'Simple-Conditions'. Избираме [Add] -> [New Project]:
Ще се отвори диалогов прозорец за избор на тип проект за създаване. Избираме C# конзолно приложение и задаваме име, например “Excellent-Result
”:
Вече имаме solution с едно конзолно приложение в него. Остава да напишем кода за решаване на задачата.
За целта отиваме в тялото на метода Main(string[] args)
и пишем следния код:
Стартираме програмата с [Ctrl+F5], за да я тестваме с различни входни стойности:
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#0.
Следващата задача от тази тема е да се напише конзолна програма, която въвежда оценка (десетично число) и отпечатва “Excellent!”, ако оценката е 5.50 или по-висока, или “Not excellent.” в противен случай.
Вход | Изход |
---|---|
6 | Excellent! |
5 | Not excellent. |
5.5 | Excellent! |
5.49 | Not excellent. |
Първо създаваме нов C# конзолен проект в решението “Simple-Conditions”.
-
Кликаме с мишката върху решението в Solution Explorer и избираме [Add] -> [New Project].
-
Избираме [Visual C#] -> [Windows] -> [Console Application] и задаваме име “Excellent-or-Not”.
Следва да напишем кода на програмата. Може да си помогнем с примерния код от картинката:
Включваме режим на автоматично превключване към текущия проект като кликнем върху главния Solution с десния бутон на мишката и изберем [Set StartUp Projects…]:
Ще се появи диалогов прозорец, от който трябва да се избере [Startup Project] -> [Current selection]:
Сега стартираме програмата, както обикновено с [Ctrl+F5] и я тестваме дали работи коректно:
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#1.
Да се напише програма, която въвежда цяло число и печата дали е четно или нечетно.
Вход | Изход |
---|---|
2 | even |
3 | odd |
25 | odd |
1024 | even |
Отново, първо добавяме нов C# конзолен проект в съществуващия solution. В метода static void Main()
трябва да напишем, кода на програмата. Проверката дали дадено число е четно, може да се реализира с оператора %
, който ще ни върне остатъка при целочислено деление на 2 по следния начин: var isEven = (num % 2 == 0)
.
Остава да стартираме програмата с [Ctrl+F5] и да я тестваме:
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#2.
Да се напише програма, която въвежда две цели числа и отпечатва по-голямото от двете.
Вход | Изход |
---|---|
5 3 |
5 |
3 5 |
5 |
10 10 |
10 |
-5 5 |
5 |
Както обикновено, първо трябва да добавим нов C# конзолен проект в съществуващия solution. За кода на програмата ни е необходима единична if-else
конструкция. Може да си помогнете частично с кода от картинката, който е умишлено замъглен, за да помислите как да го допишете сами:
След като сме готови с имплементацията на решението, стартираме програмата с [Ctrl+F5] и я тестваме:
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#3.
Да се напише програма, която въвежда цяло число в диапазона [0 … 9] и го изписва с думи на английски език. Ако числото е извън диапазона, изписва “number too big”.
Вход | Изход |
---|---|
5 | five |
1 | one |
9 | nine |
10 | number too big |
Може да използваме поредица if-else
конструкции, с които да разгледаме възможните 11 случая.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#4.
Да се напише програма, която въвежда парола (един ред с произволен текст) и проверява дали въведеното съвпада с фразата “s3cr3t!P@ssw0rd”. При съответствие да се изведе “Welcome”, а при несъответствие да се изведе “Wrong password!”.
Вход | Изход |
---|---|
qwerty | Wrong password! |
s3cr3t!P@ssw0rd | Welcome |
s3cr3t!p@ss | Wrong password! |
Използвайте if-else
конструкцията.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#8.
Да се напише програма, която въвежда цяло число и проверява дали е под 100, между 100 и 200 или над 200. Да се отпечатат съответно съобщения, като в примерите по-долу.
Вход | Изход |
---|---|
95 | Less than 100 |
120 | Between 100 and 200 |
210 | Greater than 200 |
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#9.
Да се напише програма, която въвежда две думи и проверява дали са еднакви. Да не се прави разлика между главни и малки букви. Да се изведе “yes” или “no”.
Вход | Изход |
---|---|
Hello Hello |
yes |
SoftUni softuni |
yes |
Soft Uni |
no |
beer vodka |
no |
HeLlO hELLo |
yes |
Преди сравняване на думите, ги обърнете в долен регистър, за да не оказва влияние размера на буквите (главни/малки): word = word.ToLower()
.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#10.
Да се напише програма, която въвежда скорост (десетично число) и отпечатва информация за скоростта. При скорост до 10 (включително), отпечатайте “slow”. При скорост над 10 и до 50, отпечатайте “average”. При скорост над 50 и до 150, отпечатайте “fast”. При скорост над 150 и до 1000, отпечатайте “ultra fast”. При по-висока скорост, отпечатайте “extremely fast”.
Вход | Изход |
---|---|
8 | slow |
49.5 | average |
126 | fast |
160 | ultra fast |
3500 | extremely fast |
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#11.
Да се напише програма, която въвежда размерите на геометрична фигура и пресмята лицето й. Фигурите са четири вида: квадрат (square), правоъгълник (rectangle), кръг (circle) и триъгълник (triangle).
На първия ред на входа се чете вида на фигурата (square
, rectangle
, circle
, triangle
).
- Ако фигурата е квадрат, на следващия ред се чете едно число – дължина на страната му.
- Ако фигурата е правоъгълник, на следващите два реда се четат две числа – дължините на страните му.
- Ако фигурата е кръг, на следващия ред се чете едно число – радиусa на кръга.
- Ако фигурата е триъгълник, на следващите два реда се четат две числа – дължината на страната му и дължината на височината към нея.
Резултатът да се закръгли до 3 цифри след десетичния знак.
Вход | Изход |
---|---|
square 5 |
25 |
rectangle 7 2.5 |
17.5 |
circle 6 |
113.097 |
triangle 4.5 20 |
45 |
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#12.
Да се напише програма, която въвежда час и минути от 24-часово денонощие и изчислява колко ще е часът след 15 минути. Резултатът да се отпечата във формат hh:mm
. Часовете винаги са между 0 и 23, а минутите винаги са между 0 и 59. Часовете се изписват с една или две цифри. Минутите се изписват винаги с по две цифри и с водеща нула, когато е необходимо.
Вход | Изход |
---|---|
1 46 |
2:01 |
0 01 |
0:16 |
23 59 |
0:14 |
11 08 |
11:23 |
12 49 |
13:04 |
Добавете 15 минути и направете няколко проверки. Ако минутите надвишат 59, увеличете часовете с 1 и намалете минутите с 60. По аналогичен начин разгледайте случая, когато часовете надвишат 23. При печатането на минутите, проверете за водеща нула.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#13.
Да се напише програма, в която се въвеждат 3 числа и се отпечатва дали те са еднакви (yes / no).
Вход | Изход |
---|---|
5 5 5 |
yes |
5 4 5 |
no |
1 2 3 |
no |
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#14.
Да се напише програма, която превръща число в диапазона [0 … 100] в текст.
Вход | Изход |
---|---|
25 | twenty five |
42 | forty two |
6 | six |
Проверете първо за едноцифрени числа и ако числото е едноцифрено, отпечатайте съответната дума за него. След това проверете за двуцифрени числа. Тях отпечатвайте на две части: лява част (десетици = числото / 10) и дясна част (единици = числото % 10). Ако числото има 3 цифри, трябва да е 100 и може да се разгледа като специален случай.
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/506#15.
След като направихме няколко упражнения върху условни конструкции (проверки), сега нека направим нещо по-интересно: приложение с графичен потребителски интерфейс за конвертиране на валути. Ще използваме знанията от тази глава, за да избираме измежду няколко налични валути и съответно да извършваме пресмятания по различен курс спрямо избраната валута.
Нека разгледаме как да създадем графично (GUI) приложение за конвертиране на валути. Приложението ще изглежда приблизително като на картинката по-долу:
Този път създаваме нов Windows Forms Application с име “Currency-Converter”:
Нареждаме следните контроли във формата:
- Една кутийка за въвеждане на число (
NumericUpDown
) - Един падащ списък с валути (
ComboBox
) - Текстов блок за резултата (
Label
) - Няколко надписа (
Label
)
Нагласяме размерите и свойствата им, за да изглеждат долу-горе като на картинката:
Задаваме следните настройки на контролите:
- За главната форма (
Form
), която съдържа всички контроли:(name)
=FormConverter
Text
= "Currency Converter
"Font.Size
=12
MaximizeBox
=False
MinimizeBox
=False
FormBorderStyle
=FixedSingle
- За полето за въвеждане на число (
NumericUpDown
):(name)
=numericUpDownAmount
Value
=1
Minimum
=0
Maximum
=1000000
TextAlign
=Right
DecimalPlaces
=2
- За падащия списък с валутите (
ComboBox
):(name)
=comboBoxCurrency
DropDownStyle
=DropDownList
Items
=- EUR
- USD
- GBP
- За текстовия блок за резултата (
Label
):(name)
=labelResult
AutoSize
=False
BackColor
=PaleGreen
TextAlign
=MiddleCenter
Font.Size
=14
Font.Bold
=True
Трябва да хванем следните събития, за да напишем C# кода, който ще се изпълни при настъпването им:
- Събитието
ValueChanged
на контролата за въвеждане на числоnumericUpDownAmount
:
- Събитието
Load
на форматаFormConverter
- Събитието
SelectedIndexChanged
на падащия списък за избор на валутаcomboBoxCurrency
Ще използваме следния C# код за обработка на събитията:
private void FormConverter_Load(object sender, EventArgs e)
{
this.comboBoxCurrency.SelectedItem = "EUR";
}
private void numericUpDownAmount_ValueChanged(object sender, EventArgs e)
{
ConvertCurrency();
}
private void comboBoxCurrency_SelectedIndexChanged(object sender, EventArgs e)
{
ConvertCurrency();
}
Задачата на горния код е да избере при стартиране на програмата валута “EUR” и при промяна на стойностите в полето за сума или при смяна на валутата, да изчисли резултата, извиквайки ConvertCurrency()
метода.
Следва да напишем действието ConvertCurrency()
за конвертиране на въведената сума от лева в избраната валута:
private void ConvertCurrency()
{
var originalAmount = this.numericUpDownAmount.Value;
var convertedAmount = originalAmount;
if (this.comboBoxCurrency.SelectedItem.ToString() == "EUR")
{
convertedAmount = originalAmount / 1.95583m;
}
else if (this.comboBoxCurrency.SelectedItem.ToString() == "USD")
{
convertedAmount = originalAmount / 1.80810m;
}
else if (this.comboBoxCurrency.SelectedItem.ToString() == "GBP")
{
convertedAmount = originalAmount / 2.54990m;
}
this.labelResult.Text = originalAmount + " лв. = " +
Math.Round(convertedAmount, 2) + " " + this.comboBoxCurrency.SelectedItem;
}
Горният код взима сумата за конвертиране от полето numericUpDownAmount
и избраната валута за резултата от полето comboBoxCurrency
. След това с условна конструкция, според избраната валута, сумата се дели на валутния курс (който е фиксиран твърдо в сорс кода). Накрая се генерира текстово съобщение с резултата (закръглен до 2 цифри след десетичния знак) и се записва в зелената кутийка labelResult
. Опитайте!
Ако имате проблеми с примера по-горе, гледайте видеото в началото на тази глава или питайте във форума на СофтУни: https://softuni.bg/forum.