В математиці ми звикли до того, що значенням змінної завжди є деяке число: ціле, дробове, від’ємне чи додатне. Під час написання програм часто потрібно обробляти не лише числові дані, а й інші, наприклад, текстові. Скажімо, програма для продажу квитків на потяг повинна працювати з числовими величинами: вартістю квитка, часом відправлення, номером потягу, вагону, місця. Але, разом з тим, потрібно опрацьовувати і текстові величини: місце відправлення, призначення. Отже, в програмуванні, поруч із звичними виразами x=5 або y=7,2 існують вирази a=”Житомир” або b=”Львів”.
Числові величини, на відміну від текстових, можна віднімати, множити чи ділити. В свою чергу, в текстових величинах можна здійснювати пошук чи заміну символів.
Змінна — це величина, значення якої може змінюватися в процесі виконання програми. В мові програмування C# існує поняття типу змінної. Тип змінної вказує:
Таблиця типів змінних:
Тип C# | Опис | Діапазон значень | Обсяг оперативної пам’яті, байт |
---|---|---|---|
sbyte | Ціле знакове число | -128...127 | 1 |
byte | Ціле беззнакове число | 0...255 | 1 |
short | Ціле знакове число | -32768...32767 | 2 |
ushort | Ціле беззнакове число | 0...65535 | 2 |
int | Ціле знакове число | -2147483648... 2147483647 | 4 |
uint | Ціле беззнакове число | 0...4294967295 | 4 |
long | Ціле знакове число | -9223372036854775808... 9223372036854775807 |
8 |
ulong | Ціле беззнакове число | 0...18446744073709551615 | 8 |
float | Дробове число | точність до 7 знаків | 4 |
double | Дробове число | точність до 16 знаків | 8 |
decimal | Дробове число | точність до 28 знаків | 16 |
bool | Логічний (булевський) тип | false, true | 1 |
char | Символ Unicode | один символ Unicode | 2 |
string | Рядок символів Unicode |
Надалі домовимося для числових величин використовувати такі типи: byte, int і long – якщо числа цілі; double – якщо дробові.
Як видно з таблиці, різні типи змінних займають різні обсяги оперативної пам’яті.
Розглянемо такий приклад: в задачі відомо бали випускника з трьох предметів ЗНО. Програма повинна знаходити суму всіх балів. Як відомо, максимальний бал за ЗНО дорівнює 200, а, отже, для трьох змінних доцільно обрати тип byte. Проте, для змінної, яка позначає суму набраних балів тип byte не підходить — сума балів в задачі може бути рівною 600, а, отже, знадобиться тип int. Програма буде правильно працювати і у випадку, якщо для всіх чотирьох змінних обрати тип int, але буде вимагати більше оперативної пам’яті для свого виконання. Порівняємо перший і другий варіанти вибору типів змінних для даної задачі. Перший варіант: 3 змінних х 1 байт + 1 змінна * 4 байти = 7 байт; другий варіант: 4 змінних х 4 байт = 16 байт. Нераціональне використання типів змінних, особливо в великих проектах, призводить до невиправдано великих вимог програм до оперативної пам’яті комп’ютера.
В математиці ми звикли позначати змінні однією латинською літерою, наприклад: x, y, a, b, c. При написанні великих програм може знадобитися значна кількість змінних, і, позначаючи їх одною літерою, буде важко пам’ятати, що позначає та чи інша змінна. Тому в програмуванні прийнято називати змінні словами або навіть словосполученнями, що полегшує розуміння програмного коду. Наприклад, якщо в задачі потрібно визначити швидкість руху велосипеда та автомобіля, то доречно буде дати змінним імена SpeedBike та SpeedCar відповідно.
При виборі імен для змінних потрібно дотримуватися вимог мови С#:
Оператор | Опис | Приклади |
---|---|---|
+ | Додавання | 2 + 3 = 5; 3.6 + 7.3 = 10.9 |
- | Віднімання | 7 - 9 = -1; 6 - 1.25 = 4.75 |
* | Множення | 7 * 2 = 14; |
/ | Ділення | 5 / 2 = 2; 15 / 4 = 3 5.0 / 2 = 2.5; 15 / 4.0 = 3.75 |
% | Остача від ділення | 5 % 2 = 1; 27 % 4 = 3; 8 % 4 = 0 |
++ | Інкремент (збільшення значення змінної на 1) | x++ |
-- | Декремент (зменшення значення змінної на 1) | a-- |
Примітка 1. Якщо ділене і дільник є цілими числами, то результатом операції ділення буде лише ціла частина частки.
Примітка 2. Знак множення ставиться обов’язково.
Перед першим використанням змінну потрібно оголосити — вказати її ім’я та тип, до якого вона належить. Спроба використати змінну, яка не була оголошена, призведе до помилки компіляції.
Приклади оголошення змінних:
byte a; int s, t; double v;
Надання змінній початкового значення називається ініціалізацією. Оголошення змінної та її ініціалізацію можна об’єднувати в один запис, наприклад:
byte a=7; int s=130, t=2;
Знак “=” в мові C# називають оператором присвоювання. В загальному, операція присвоювання має такий вигляд:
ім’я змінної = значення або вираз;
Якщо справа від знаку “=” записано вираз, то він спочатку обчислюється, а потім результат присвоюється змінній, ім’я якої записано ліворуч.
Перейдемо до практики. Напишемо програму (задача №1) для знаходження периметра і площі квадрату, якщо відомо його сторону (ціле число, не більше 100).
Створимо нове рішення lesson_4, проект task_1.
В переважній більшості програм на обчислення можна виділити три етапи:
Для реалізації першого етапу потрібно передбачити елемент програми, в який користувач зможе ввести число (сторону квадрату). Таким елементом в Visual C# є текстове поле TextBox. Розглянемо деякі властивості елемента TextBox.
Властивість | Пояснення |
---|---|
Text | Текст в полі |
Size
|
Розмір компонента (ширина; висота) |
BackColor | Колір фону поля |
BackgroundImage | Фоновий малюнок поля |
ReadOnly |
|
Font | Параметри шрифту напису (гарнітура шрифту, накреслення, розмір) |
ForeColor | Колір тексту |
Visible | Видимість:
|
TextAlign | Вирівнювання тексту в компоненті. |
Домовимося в текстове поле записувати за замовчуванням число 0. Окрім текстового поля вікно програми повинно містити кнопку, яка запускає обчислювальний процес, а також, написи для виведення відповідей. Перейдемо у конструктор форм і створимо інтерфейс майбутньої програми згідно зразка (рис. 31).
Тепер потрібно написати обробник події “натиснута кнопка”. Для цього знайдемо в списку подій об’єкта кнопки подію Click та виконаємо подвійний клік напроти неї. Ми перейшли в програмний код із заготовленим шаблоном обробника події button1_Click. Цього самого можна досягти, виконавши подвійний клік на кнопці в конструкторі форм.
Розпочнемо реалізацію першого етапу — зчитування вхідних даних. Оголосимо змінні, яка знадобляться в даній програмі:
byte Side; int p, s;
Тепер потрібно зчитати число з текстового поля textBox1 і присвоїти це число змінній Side. Для цього потрібно записати такий рядок:
Side = byte.Parse(textBox1.Text);
Даний рядок виконується справа наліво в такий послідовності:
Другий етап – проведення обчислень – реалізується двома наступними рядками:
p = 4 * Side; s = Side * Side;
Третій етап – Виведення результатів на екран. В елемент Напис можна виводити лише дані текстового типу. Тому, при потребі вивести в Напис числове значення, його потрібно попередньо перетворити в текст:
label1.Text = p.ToString(); label2.Text = s.ToString();
Виконавши всі три етапи отримаємо метод button1_Click – обробник події “натиснута кнопка”:
private void button1_Click(object sender, EventArgs e) { byte Side; int p, s; Side = byte.Parse(textBox1.Text); p = 4 * Side; s = Side * Side; label1.Text = p.ToString(); label2.Text = s.ToString(); }
Оголошення змінних зручно поєднувати з їх ініціалізацією. Тоді програмний код буде мати такий вигляд:
private void button1_Click(object sender, EventArgs e) { byte Side = byte.Parse(textBox1.Text); int p = 4 * Side; int s = Side * Side; label1.Text = p.ToString(); label2.Text = s.ToString(); }
Запустимо та протестуємо програму (рис. 4.2):
В інтерфейсі створеної програми є три недоліки: після запуску у вікні програми відображаються написи label1 та label2; не зрозуміло, що потрібно вводити в текстове поле; отримані результати відображаються без пояснень: що означають числа 28 і 49?
Перейдемо в конструктор форм та змінимо властивість Text елементів label1 та label2 на порожній рядок – після запуску їх не буде видно.
Додамо і розташуємо поруч із текстовим полем напис з текстом «Сторона:».
Для пояснення відповідей додамо на форму ще два написи з текстом «Периметр = » та «Площа = » відповідно.
Провівши дані зміни отримаємо завершений проект (рис. 4.3):
Розглянемо ще один приклад (задача №2): в рішення lesson_4 додамо проект task_2 для розв’язання задачі: відомо два цілих числа, які за модулем не перевищують 1000. Потрібно написати програму, яка знаходить їх середнє арифметичне.
Інтерфейс створеної програми зображено на рис. 4.4
Програмний код для розв’язання даної задачі наведено нижче:
private void button1_Click(object sender, EventArgs e) { int a = int.Parse(textBox1.Text); int b = int.Parse(textBox2.Text); double x = (a + b) / 2.0; label3.Text = x.ToString(); }
Задача №3. Відомо сторони прямокутника (цілі числа не більші за 1000). Скласти програму для обчислення периметра та площі прямокутника (lesson_4, проект task_3). Орієнтовний інтерфейс програми зображено на рис. 4.5.
Задача №4. Відомо координати кінців відрізка (цілі числа). Скласти програму для знаходження координат його середини (lesson_4, проект task_4) (рис. 4.6).
Задача №4б. Відомо початкові та кінцеві показники лічильника холодної води (цілі числа). Скласти програму для визначення кількості спожитої води та її вартість, якщо 1 м3 коштує 14,25 грн. (lesson_4, проект task_5) (рис. 4.7).
Особливості зчитування вхідних даних та виведення результатів в консольних додатках розглянемо на прикладі задачі №5. Відома сторона квадрата (ціле число, не більше 100). Скласти програму для знаходження його периметра та площі (lesson_4, проект task_5_Console).
Проаналізуємо наступний програмний код:
static void Main(string[] args) { Console.Write("Введiть сторону квадрата: "); byte Side = byte.Parse(Console.ReadLine()); int p = 4 * Side; int s = Side * Side; Console.WriteLine("Периметр квадрата = " + p); Console.WriteLine("Площа квадрата = " + s); Console.ReadLine(); }
Перший рядок: виводиться повідомлення – запрошення ввести сторону квадрату. Команда Write не переводить курсор на новий рядок – користувач буде вводити число в тому ж рядку.
Другий рядок виконується з кінця в такій послідовності: зчитується введений рядок, перетворюється в ціле число і присвоюється оголошеній змінній Side.
Рядки 3, 4 – оголошення змінних p і s та обчислення їх значень за формулами.
В двох наступних рядках виводяться текстові повідомлення (пояснення до відповідей) та результати обчислень.
Останній рядок затримує закриття консольного вікна до натиснення будь-якої клавіші.
Зразок виконання програми зображено на рис. 4.8.
Розглянемо задачу №6 (lesson_4, проект task_6_Console). Відомо два цілих числа, які за модулем не перевищують 1000. Потрібно написати програму, яка знаходить їх середнє арифметичне.
Нижче наведено програмний код для розв’язання даної задачі та зразок виконання проекту (рис. 4.9).
static void Main(string[] args) { Console.Write("Введіть перше число: "); int a = int.Parse(Console.ReadLine()); Console.Write("Введіть друге число: "); int b = int.Parse(Console.ReadLine()); double x = (a + b) / 2.0; Console.WriteLine("Середнє арифметичне = " + x); Console.ReadLine(); }
Додайте до рішення «Lesson_4» два проекти «Task_7_Console» та «Task_8_Console» для розв’язання наступних задач.
Задача №7. Відомо сторони прямокутника (цілі числа, не більші за 1000). Скласти програму для обчислення периметра та площі прямокутника (рис. 4.10).
Задача №8. Відомо координати кінців відрізка (цілі числа). Скласти програму для знаходження координат його середини (рис. 4.11).
В розділах «Олімпіадна сторінка» ми будемо розглядати деякі приклади розв’язування задач з олімпіадного (спортивного) програмування. Як правило, олімпіада з програмування проводиться з використанням спеціальних систем on-line перевірки розв’язків. Однією з таких систем є Інтернет-портал E-Olymp. На цьому сайті можна тренуватися розв’язувати задачі з програмування, брати участь в різноманітних змаганнях, готуватися до олімпіади з програмування. Перед початком роботи з E-Olymp потрібно зареєструватися та ознайомитися з правилами on-line перевірки.
Задача №1 - Проста задача? - https://www.e-olymp.com/uk/problems/1
Програма зчитує двоцифрове число і виводить через пропуск кожну цифру окремо.
Вхідні дані: Натуральне число на проміжку від 10 до 99 включно.
Вихідні дані: Спочатку першу цифру числа і через пропуск другу.
Вхідні дані #1: 23
Вихідні дані #1: 2 3
Розв’язок:
static void Main(string[] args) { byte x = byte.Parse(Console.ReadLine()); int a = x / 10; int b = x % 10; Console.WriteLine(a + " " + b); }
Задача №7336 – Пиріжки - https://www.e-olymp.com/uk/problems/7336
Пиріжок у шкільній їдальні коштує a гривень та b копійок. Знайдіть скільки гривень та копійок заплатить Петрик за n пиріжків.
Вхідні дані: Три натуральних числа a, b, n (0 ≤ a,b, n ≤ 100).
Вихідні дані: Через пропуск два числа: вартість покупки у гривнях та копійках.
Вхідні дані: 1 25 2
Вихідні дані: 2 50
Розв’язок:
static void Main(string[] args) { string[] s = Console.ReadLine().Split(' '); byte a = byte.Parse(s[0]); byte b = byte.Parse(s[1]); byte n = byte.Parse(s[2]); int cost = (a * 100 + b) * n; int grn = cost / 100; int kop = cost % 100; Console.WriteLine(grn + " " + kop); }
В даній задачі вхідні дані (три числа) вводяться в один рядок через пробіл. Зчитати такі вхідні дані звичним способом не вдасться. Тому спочатку потрібно введений рядок поділити на частини (підрядки), вказавши розділювач ’пробіл ’ – утвориться множина (послідовність) текстових величин s[0], s[1], s[2] (нумерація таких підрядків починається з 0). Потім кожен із підрядків потрібно конвертувати в число і записати у відповідні змінні.
Задача №67 – Сир для Анфіси-2 - https://www.e-olymp.com/uk/problems/67
Розрізаючи сир в задачі «Сир для Анфіси» у господаря залишалися куски сиру у вигляді прямокутного паралелепіпеда з різними цілими довжинами сторін. Готуючи нову страву із сиру для Анфіси господарю прийшлося розрізати дані куски сиру на кубики зі стороною 1. Яку найменшу кількість розрізів приходилось йому робити, щоб розрізати дані куски сиру, якщо він кожного разу розрізав один кусок сиру на дві частини.
Вхідні дані: У єдиному рядку записано три числа А, B, C - довжини ребер куска сиру. 1 ≤ А, B, C ≤ 2000000000.
Вихідні дані: Єдине число найменша кількість розрізів.
Вхідні дані #1: 2 3 4
Вихідні дані #1: 23