if…else, switch, do…while, for
Тести з програмування
Тести з програмування – це серія статей із тестовими завданнями для перевірки знань з різних тем. Пройшовши тест, ви отримуєте сертифікат, який можете обміняти в адміністратора нашої школи на коїни. Коїни – валюта школи GoMother, яку учні школи заробляють на заняттях і потім можуть придбати за ці гроші собі різні подарунки.
Для управління процесом виконання програми C# надає умовні оператори if і switch, а для запуску повторюваних дій цикли: for, while (do/while) і foreach. Ці конструкції ми розберемо у цьому уроці.
Умовні оператори
Умовні оператори – це конструкції, що дозволяють керувати ходом реалізації програми залежно від певних умов. У мові C# присутні два типи таких конструкцій: if…else і switch…case.
Оператор if
Конструкція if…else дозволяє перевірити деяку умову на істинність і, залежно від результату, виконати той або інший блок коду. Синтаксис умовного оператора if…else:
if (Умова_1)
{
// Блок виконається, якщо Умова 1 має значення true
}
else if (Умова_2) // Необов’язкова частина
{
// Блок виконається, якщо Умова 2 має значення true
}
else // Необов’язкова частина
{
// Блок виконається, якщо Умова 1 та Умова 2 мають значення false
}
Місце умови може бути змінна типу bool, або вираз, значення якого має тип bool.
Приклад роботи з оператором if:
int n1 = 9;
int n2 = 12;
if (n1 < n2)
{
Console.WriteLine($”Число {n1} менше числа {n2}”);
}
У наведеному вище прикладі вираз 9 < 12 має значення true, тому виконується блок коду після оператора if. Додамо конструкцію else і задамо значення змінним n3 і n4, за яких вираз, що визначає умова, матиме значення false:
intn 3 = 15;
intn 4 = 12;
if (n3 < n4)
{
Console.WriteLine($”Число {n3} менше числа {n4}”);
}
else
{
Console.WriteLine($”Число {n3} більше числа {n4}”);
}
Для окремого контролю варіанта, коли порівнювані числа дорівнюють, можна скористатися конструкцією if else:
intn 5 = 13;
intn 6 = 12;
if (n5 < n6)
{
Console.WriteLine($”Число {n5} менше числа {n6}”);
}
else if (n5 >n6)
{
Console.WriteLine($”Число {n5} більше числа {n6}”);
}
else
{
Console.WriteLine($”Число {n5} рівно числу {n6}”);
}
Мова C# не обмежує нас у допустимому числі використовуваних блоків else if. Але в більшості випадків завдання такого розгалуження зводиться до найпростішого зіставлення з прикладом, яке можна виконати з підтримкою конструкції switch … case. Оператор | switch |
Синтаксис конструкції має подальший вигляд:
switch (Вираз)
{
case Шаблон_1:
// Блок коду виконується, якщо Виразу відповідає Шаблон_1
break;
case Шаблон_2:
// Блок коду виконується, якщо Виразу відповідає Шаблон_2
break;
// …
default:
// Блок коду виконується, якщо серед перерахованих у case шаблонах
// немає відповідного
break;
}
Залежно від версії мови C# допустимі різні шаблони, які можна використовувати в блоках case. У C# 6 і ранніх версіях допустимі лише константи наступних типів:
- char;
- string;
- bool;
- ціле значення;
- enum.
З# 7 і пізніші версії підтримують вищезгаданий шаблон констант та інші види шаблонів.
Подивимося на приклад роботи з switch:
int n7 = 1;
switch (n7)
{
case 1:
Console.WriteLine(“Case 1”);
break;
case 2:
Console.WriteLine(“Case 2”);
break;
default:
Console.WriteLine(“Default case”);
break;
}
Оператор switch шукає збіг значення змінної n7 зі значеннями, зазначеними після case. Якщо збіг знайдено, то виконується код усередині блоку case. Блок case може закінчиться оператором:
- break – переривання коду в конструкції switch;
- goto case – використовується якщо необхідно перейти в інший case;
- return – завершує виконання методу і повертає зазначене значення;
- throw – використовується для викиду виключення.
Якщо серед шаблонів в case не було знайдено відповідного, то буде виконано код у блоці default.
Як шаблони в case можуть виступати:
- шаблони констант;
- шаблони типів;
- вираз із ключовим словом when.
Розглянемо їх докладніше.
Шаблон константи
Зразок константи думає, що ми порівняємо значення вираз із switch з константами, які розташовуються в блоках case. Як вже було сказано вище, в такому варіанті роботи switch … case можливі константи наступних типів: char, string, bool, цілісне значення у enum. У 1-му прикладі, що демонструє роботу оператора switch, вже був наведений варіант зі зразком константи, наведемо ще один, на цей раз, це буде робота з рядками:
string s1 = “Three”;
switch (s1.ToLower())
{
case “one”: Console.WriteLine(“Case one”); break;
case “two”: Console.WriteLine(“Case two”); break;
case “three”: Console.WriteLine(“Case three”); break;
case “four”: Console.WriteLine(“Case four”); break;
case “five”: Console.WriteLine(“Case five”); break;
default: Console.WriteLine(“Default case”); break;
}
Шаблон типу
Шаблон типу передбачає зіставлення результату обчислення виразу, яке передається у switch, з типом, зазначеним у case:
case type var_name
У разі якщо результат виразу можна привести до зазначеного типу, то отримане значення присвоюється змінною із зазначеним ім’ям – var_name.
Для завдання альтернативи зі значенням null використовуйте наступний формат:
case null
У документації Microsoft наводиться список умов, за яких результат виразу буде успішно приведений до вказаного в case типу, перерахуємо деякі з них:
- вираз має зазначений тип type;
- результат виразу реалізує інтерфейс type;
- результат виразу має тип похідний від type.
Для демонстрації створимо кілька допоміжних класів:
class Transport { public string Name { get; set; } }
class Bicycle : Transport { }
class Moto : Transport { }
class Car : Transport { }
Оператор switch…case, що працює з цими класами, може виглядати так:
object trans = new Moto() { Name = “Suzuki” };
switch (trans)
{
case Bicycle bicycle: Console.WriteLine($“Bicycle: {bicycle.Name}“); break;
case Moto moto: Console.WriteLine($“Moto: {moto.Name}“); break;
case Car car: Console.WriteLine($“Car {car.Name}“); break;
case Transport transport: Console.WriteLine($“Transport {transport.Name}“); break;
case null: Console.WriteLine(“Transport is null!”); break;
}
Вираз із ключовим словом when
Мова C#, починаючи з версії 7.0, дозволяє використовувати у switch…case пропозиція when для реалізації можливості використання додаткової умови. У цьому випадку типи після ключового слова case можуть збігатися і додаткова фільтрація буде проводитися за умовою після when. Тести з програмування – це серія безплатних тестів, спрямованих на перевірку знань учнів.
Доповнимо клас Transport, який ми створили в розділі “Шаблон типу”, властивістю WheelsCount:
class Transport
{
public string Name { get; set; }
public int WheelsCount { get; set; }
}
Реалізуємо можливість роздільної роботи з трьома варіантами велосипедів:
object bc = new Bicycle() { Name = “Trec”, WheelsCount = 1 };
switch (bc)
{
case Bicycle bicycle when bicycle.WheelsCount == 1: Console.WriteLine($“Bicycle: {bicycle.Name}, type – monocycle”); break;
case Bicycle bicycle when bicycle.WheelsCount == 2: Console.WriteLine($“Bicycle: {bicycle.Name}, type – classic”); break;
case Bicycle bicycle when bicycle.WheelsCount == 3: Console.WriteLine($“Bicycle: {bicycle.Name}, type – tricycle”); break;
case Moto moto: Console.WriteLine($“Moto: {moto.Name}“); break;
case Car car: Console.WriteLine($“Car {car.Name}“); break;
case Transport transport: Console.WriteLine($“Transport {transport.Name}“); break;
case null: Console.WriteLine(“Transport is null!”); break;
}
Тернарний оператор
Підсумком обчислення тернарного оператора є одна з 2-х альтернатив, яка вибирається в залежності від істинності обґрунтування, що перевіряється.
Синтаксис оператора має подальший вид:
condition ? if_true:: if_else
Залежно від значення логічного вираження condition повертається результат обчислення виразу if_true або if_else. Нижче наведено приклад, що демонструє роботу цього оператора:
int n8 = 5;
int n9 = 8;
int largerNumber = n8 > n9 ? n8 : n9;
У прикладі, за допомогою оператора? визначається, яке з двох чисел більше, і відповідне значення, надається змінної largerNumber. Після прочитання статті рекомендуємо вам пройти тести з програмування та виявити прогалини у знаннях.
Цикли
Цикли в мовах програмування призначені для побудови конструкції, що виконує заданий блок коду кілька разів, яке визначається тією чи іншою умовою. C# надає чотири різні варіанти побудови циклів.
Цикл for
Цикл for має наступний синтаксис:
for(ініціалізація лічильника; умова; ітератор)
{
// Оператор (набір операторів)
}
Ініціалізатор – це вираз, який обчислюється перед виконанням тіла циклу. Зазвичай тут ініціалізується локальна змінна, яка буде застосовуватися як лічильник.
Умова – це вираз, який перевіряється перед будь-якою новою ітерацією циклу. Якщо значення виразу дорівнює true, то буде виконано тіло циклу, якщо false відбудеться вихід з циклу і виконається подальша за ним інструкція.
Ітератор – це вираз, який обчислюється після будь-якої ітерації. Зазвичай тут відбувається зміна локальної змінної, оголошеної в ініціалізаторі.
Перераховані вирази: ініціалізатор, умова та ітератор поділяються символом “точка з комою”. Цикл for комфортно застосовувати, коли відомо число повторень.
Приклад роботи з циклом for:
for (int i = 0; i < 3;
i++) {
console.writeline(“Квадрат числа I” + i * i);
}
У ньому ми ініціалізуємо локальну змінну значенням нуль, після цього перевіряємо, що змінна менш як 3, виконуємо тіло циклу – виводимо в консоль значення числа і у квадраті. На всякій ітерації додаємо до змінної та значення один, знову перевіряємо умову і виконуємо тіло циклу, і так, доки умова (і <три) буде правдивою.
Цикли while і do/while
У C# цикл while має наступну конструкцію:
while (умова)
{
// Тіло циклу
}
У цьому циклі перевіряється умова, і якщо воно є істинним, то виконується набір операторів усередині тіла циклу. Обов’язково переконайтеся, що змінюєте змінну, від якої залежить умова, інакше цикл стане нескінченним, якщо це не є метою. Приклад роботи з циклом:
int i = 0;
int number = 3;
while(i <= number) {
Console.WriteLine(“Ітерація циклу номер ” + i);
i++;
}
Console.ReadKey();
Цикл do/while має наступний синтаксис:
do {
//Тіло циклу
} while (умова);
Відмінність do/while полягає в тому, що перевірка умови відбувається після тіла циклу, що призводить до того, що незалежно від умови цикл виконається хоча б один раз.
Тести з програмування швидкий метод перевірити свої знання!
Приклад роботи з циклом do/while:
int j = 0;
int number2 = 3;
do
{
Console.WriteLine(“Ітерація циклу номер” + j);
j++;
} while (j > number2);
Console.ReadKey();
Цикл foreach
Останній варіант циклу, який ми розглянемо в цьому уроці – це foreach. Синтаксис оператора foreach має такий вигляд:
foreach (тип ім’я_змінної_циклу in колекція)
{
// Тіло циклу
}
Оператор foreach використовується для обходу колекцій, послідовно переходячи від елемента до елемента в циклі. В такому випадку, під колекцією розуміється тип, який:
- реалізує інтерфейс System.Collections.IEnumerable або System.Collections.Generic.IEnumerable<T>;
- реалізує відкритий метод GetEnumerator, що повертає інтерфейс, клас або структуру, що мають відкриту властивість Current і метод MoveNext.
Приклад роботи з оператором foreach:
int[]nums=={6,3,6,8,9,12,4,5,88,54,3,66,78,10,12,5,7,9,3;
int result = 0;
foreach (int n in nums)
{
if (n > 10)
{
result++;
}
}
Console.WriteLine($”Кількість чисел у масиві понад 10: {result}”);
У ньому ми визначаємо кількість чисел, що понад десяти, у вихідному масиві.
Тип змінної циклу в операторі foreach можна задавати явно, як це було зроблено в прикладі вище, так і не явно за допомогою ключового слова var:
result==0;
foreach (var n in nums)
{
if (n < 10)
{
result++;
}
}
Console.WriteLine($”Кількість чисел у масиві менш як 10: {result}”);
Тести з програмування – проходь та отримуй призи!
Оператори переходу
Мова C# надає спеціальні оператори для переривання виконання всього циклу та для примусового завершення поточної ітерації з переходом до наступної. Перше завдання вирішує оператор break. Якщо в програмі використовується кілька вкладених циклів, то при використанні break, вихід буде виконаний тільки з того циклу, де цей оператор був викликаний. Оператор continue примусово завершує поточну ітерацію циклу і переходить до наступної. При цьому для циклу while і do/while відбувається перехід до умовного вираження, а в циклі for спочатку обчислюється ітераційний вираз, а потім перевіряється умова:
Console.WriteLine(“### Оператори переходу”);
for (int i = 0; i < nums.Length; i++)
{
if (nums[i] > 10)
{
Console.WriteLine($“{nums[i]} > 10″);
continue;
}
if (i > 7)
{
Console.WriteLine(“Break cycle”);
break;
}
}
LINQ як інструмент обходу колекцій
Існує більш комфортний інструмент для роботи з колекціями – це мова запитів LINQ. У цій статті ми розберемо деяку кількість прикладів роботи з LINQ для того, щоб показати які з його перспектив і зацікавити вас на наступне освоєння цього інструменту. Спочатку нами будуть розглянуті деякі з способів розширення послідовностей, які надає простір імен System.Linq, після цього буде наведено приклад, що демонструє роботу з мовою LINQ. Нижче представлені два приклади, 1-й – це варіант реалізації деякого алгоритму з застосуванням циклів, 2-й – даний алгоритм, але рішення побудоване з підтримкою LINQ. Тести з програмування з основ C#.
Приклад без LINQ
Звернемося до раніше створеного масиву nums, витягнемо з нього тільки парні елементи і зведемо їх у квадрат, отримані значення помістимо в новий масив evenSq:
var evenSq = new List<int>();
foreach (var n in nums)
{
if (n % 2 == 0)
{
evenSq.Add(n * n);
}
}
Приклад з LINQ
Виконаємо ту ж операцію за допомогою LINQ:
evenSq = nums
.Where(v => v % 2 == 0)
.Select(v => v * v)
. ToList ();
З підтримкою способів розширення з System.Linq можна виконувати над колекціями операції фільтрації, перетворення, групування, агрегування, формування колекцій і т.д.
д. Розглянемо яке з цих перспектив.
Тести з програмування: Фільтрування
Для фільтрації елементів в колекції використовуйте спосіб, якому в якості доводу передається предикат, якщо його значення правдиво для елемента колекції, то він (елемент) залишається, у зворотному випадку відкидається.
Витягнемо з масиву nums числа, значення яких понад 10:
var arr1 =?nums.Where(v => v > 10).ToList(); // Take elements thats higher then 10
Перетворення
Метод Select застосовує передану їй функцію до елементів колекції та формує на базі отриманих значень нову колекцію. Віднімемо з елементів nums константу 7:
var arr2 = nums.Select(v => v – 7).ToList(); // Sub 7 from every elements
Побудуємо на базі nums новий масив, елементами якого будуть bool значення: true, якщо відповідний елемент у nums парний, false – в іншому випадку.
var arr3 = nums.Select(v => v % 2 == 0).ToList();
Розглянемо ще один приклад роботи з LINQ.
Створимо клас FootballTeams для представлення футбольної команди:
public class FootballTeam
{
public string Name { get; set; }
public string Country { get; set; }
public int Group { get; set; }
public int PlaceGroup { get; set; }
}
Створимо метод для створення даних про результати футбольних матчів:
private static List<FootballTeam> CreateList()
{
return new List<FootballTeam>
{
{ new FootballTeam() { Name=”Zenit”, Country=”Russia”, Group= 1, PlaceGroup= 3, NumberpointsScored = 3}},
{ new FootballTeam() { Name=”Ajax”, Country=”Holand”, Group= 1, PlaceGroup= 2, NumberpointsScored = 4}},
{ new FootballTeam() { Name=”Manchester United”, Country=”England”, Group= 1, PlaceGroup= 1, NumberpointsScored = 6}},
{ new FootballTeam() { Name=”Bavaria”, Country=”Germany”, Group= 2, PlaceGroup= 1, NumberpointsScored = 8}},
{ new FootballTeam() { Name=”Spartak”, Country=”Russia”, Group= 2, PlaceGroup= 2, NumberpointsScored= 6}},
{ new FootballTeam() { Name=”Real”, Country=”Italy”, Group= 2, PlaceGroup= 3, NumberpointsScored = 3}},
{ new FootballTeam() { Name=”Arsenal”, Country=”England”, Group= 3, PlaceGroup= 2, NumberpointsScored = 9}},
{ new FootballTeam() { Name=”Shakter”, Country=”Ukrane”, Group=3, PlaceGroup= 3, NumberpointsScored = 6}},
{ new FootballTeam() { Name=”Barselona”, Country=”Espane”, Group= 3, PlaceGroup= 1, NumberpointsScored = 12}}
};
}
Створимо змінну для зберігання результатів матчів:
var teams = CreateList();
Скористаємося LINQ запитом та виберемо з нашої колекції всі команди, які займають перше місце в групах та виведемо на екран назву команди та кількість зароблених очок.
var teams = CreateList();
var selectedTeams = from team in teams
where team.PlaceGroup == 1 // фільтрація
orderby team.Name // впорядкування на ім’я
select team; // Вибір об’єкта
foreach (var team in selectedTeams)
{
Console.WriteLine(team.Name + ” ” + team.NumberpointsScored);
}
Завдяки LINQ можна використати один і той же запит до різних джерел даних, крім цього, такі запити економлять ресурси та виконуються значно швидше, ніж звичайний обхід колекцій засобами, тому що робота йде з вже відфільтрованими даними, і колекцію. Тести з програмування, що допоможуть згадати основи програмування та перевірити свої знання.