1. Тип int: базовий тип цілих чисел
Коли ви тільки починаєте програмувати, найчастіше потрібно щось порахувати: суму, різницю, кількість, остачу, розмір або індекс. І тут з’являється тип int: він зберігає цілі числа без дробової частини. У Go це базовий і найпопулярніший тип для лічильників і «звичайних» чисел, тож сьогодні ми потренуємося саме на ньому.
Важлива думка: int — це про числа, які можна уявити як «…, -2, -1, 0, 1, 2, …». Від’ємні значення теж допустимі. Наприклад, температура може бути -5, баланс може бути -200, а настрій після трьох годин налагодження — ну, ви й самі знаєте.
Технічна ремарка без заглиблення: розмір int залежить від платформи — зазвичай це 32 або 64 біти. Для навчальних задач вам досить знати, що int підходить для більшості звичайних обчислень.
Мініприклад: оголошуємо int і виводимо
package main
import "fmt"
func main() {
var tasks int = 12
fmt.Println(tasks) // 12
}
Зверніть увагу: ми явно вказали int, але могли б і коротше — через := (ми це вже проходили раніше).
package main
import "fmt"
func main() {
tasks := 12
fmt.Println(tasks) // 12
}
2. Оператори +, -, *: додавання, віднімання, множення
Тепер, коли у нас є числа, хочеться робити з ними саме те, заради чого люди зазвичай терплять математику в школі: рахувати. У Go для int доступні звичні арифметичні оператори: + (додавання), - (віднімання) і * (множення). Вони виглядають саме так, як ви очікуєте, і поводяться теж передбачувано — це одна з приємних рис мови.
Важливий нюанс для новачків: у Go немає прихованої магії на кшталт автоматичних перетворень типів під час арифметики. Якщо у вас числа — ви працюєте з числами. Якщо рядки — це окрема історія, і склеювання рядків через + ми розбиратимемо окремо. Сьогодні тримаємо фокус саме на цілих числах.
Приклад: «мініпланувальник завдань»
Уявімо, що в нас є план на день і вже виконані завдання. Порахуємо, скільки залишилося.
package main
import "fmt"
func main() {
planned := 10
done := 3
remaining := planned - done
fmt.Println(remaining) // 7
}
А тепер додамо «очки продуктивності»: припустімо, за кожну виконану задачу ви отримуєте 5 очок. Порахуємо.
package main
import "fmt"
func main() {
done := 3
pointsPerTask := 5
points := done * pointsPerTask
fmt.Println(points) // 15
}
Так, це трохи схоже на RPG. Певною мірою програмування й справді так працює: прокачуємо рівень, збираємо артефакти, перемагаємо баги.
3. Оператор /: цілочисельне ділення
Ділення — найчастіша пастка для новачка, бо мозок пам’ятає шкільну математику, а комп’ютер — типи даних. Якщо ви ділите два значення типу int, результат теж буде int. А це означає, що дробова частина просто відкидається. Не округлюється, не «зберігається десь поруч», не ховається в темному кутку програми — її просто немає.
Ця поведінка називається цілочисельним діленням. Воно не «погане» і не «хороше» — воно корисне, якщо ви ділите цукерки між дітьми або розподіляєте сторінки між розділами. Але воно може бути несподіваним, якщо ви розраховували на дріб.
Приклад: «порівну» і «без решти»
package main
import "fmt"
func main() {
a := 7
b := 2
fmt.Println(a / b) // 3
}
Чому так? Тому що 7 / 2 у цілих числах — це «скільки разів двійка повністю вміщується в сімці». Три рази. Остача буде окремо, і для неї в нас є оператор % (трохи пізніше).
Практичний приклад: «відсоток виконання» без дробів
Не плутайте цей оператор із відсотками. Символ схожий, але зміст інший. У програмуванні % — це остача.
package main
import "fmt"
func main() {
planned := 10
done := 3
percent := (done * 100) / planned
fmt.Println(percent) // 30
}
Тут важливо, що ми спочатку помножили done на 100, а вже потім поділили на planned. Якби ми обчислювали done / planned напряму, вийшло б 0, і далі все було б сумно та неправдоподібно.
4. Оператор %: остача від ділення
Оператор % у Go — це остача від ділення. Він відповідає на запитання: «Що залишиться, якщо ми поділимо максимально рівно, без дробів?» Якщо / дає нам «цілу частину», то % дає «хвостик». І цей хвостик надзвичайно корисний: для перевірки парності, розкладу хвилин на години, розподілу чогось порівну та розуміння, скільки залишилося.
Не плутайте цей оператор із відсотками. Знак схожий на символ відсотка, але зміст інший. У програмуванні % — це остача.
Приклад: цукерки і діти
package main
import "fmt"
func main() {
candies := 17
kids := 5
each := candies / kids
left := candies % kids
fmt.Println(each) // 3
fmt.Println(left) // 2
}
Читається по-людськи: «кожному по 3, ще 2 залишаться». І так, саме так ви раптово стаєте головним із чесного поділу в компанії.
Приклад: хвилини в години та хвилини
Класична задача: є кількість хвилин, хочемо отримати «скільки годин» і «скільки хвилин залишилося».
package main
import "fmt"
func main() {
totalMinutes := 135
hours := totalMinutes / 60
minutes := totalMinutes % 60
fmt.Println(hours, minutes) // 2 15
}
Зверніть увагу: ми поки не збираємо рядок виду 2:15, бо це вже тема про рядки. Зараз нам важлива математика: / дає «скільки цілих годин», % — «скільки хвилин залишилося».
5. Пріоритет операторів: як читаються вирази
Коли вирази стають довшими, виникає питання: «Що виконається першим?» Оператори мають пріоритет. У Go, як і в звичайній математиці, множення й ділення виконуються раніше, ніж додавання та віднімання. А остача % за пріоритетом стоїть поруч із * і /. Це означає, що вираз 2 + 3*4 обчислиться як 2 + (3*4).
Новачок часто отримує «не ту відповідь» саме через пріоритет, а потім підозрює Go у змові. Насправді змова проста: математика.
Таблиця пріоритету
| Оператори | Приклад | Виконуються першими? |
|---|---|---|
|
|
Так |
|
|
Ні |
Приклад: один вираз — два результати
package main
import "fmt"
func main() {
fmt.Println(2 + 3*4) // 14
fmt.Println((2 + 3) * 4) // 20
}
Дужки — це ваш спосіб сказати: «Я точно знаю, чого хочу, і прошу комп’ютер не здогадуватися замість мене». Навіть якщо ви пам’ятаєте про пріоритет, дужки роблять код читабельнішим. У промисловій розробці це часто важливіше, ніж економія двох символів.
6. Мініпроєкт: ділимо піцу і рахуємо прогрес
Зараз у нас уже достатньо інструментів, щоб написати маленьку програму, яка виглядає як справжній застосунок, а не просто набір розрізнених обчислень. Ми поки не читаємо дані зі вводу; це буде окрема тема, тому значення задамо прямо в коді. Зате потренуємося одразу на + - * / %, у пріоритеті та в цілочисельному діленні.
Ідея така: у нас є піца, нарізана на шматочки, є компанія людей і є план — скільки шматочків можна з’їсти сьогодні, щоб совість не дзвонила мамі. Порахуємо порції, остачу та відсоток виконання плану.
Версія 1: ділимо порівну і рахуємо остачу
package main
import "fmt"
func main() {
slices := 14
people := 5
each := slices / people
left := slices % people
fmt.Println(each, left) // 2 4
}
Результат 2 4 означає: «кожному по 2 шматочки, 4 залишиться».
Версія 2: додаємо «план» і відсоток виконання
Припустімо, наш план — з’їсти не більше 10 шматочків усією компанією (піца в небезпеці, але ми тримаємося).
package main
import "fmt"
func main() {
plan := 10
alreadyEaten := 3
remaining := plan - alreadyEaten
percent := (alreadyEaten * 100) / plan
fmt.Println(remaining) // 7
fmt.Println(percent) // 30
}
Тут ми використали одразу кілька речей: віднімання для остачі за планом, множення й ділення для цілого відсотка, а також дужки. У цьому випадку дужки не обов’язкові, але вони допомагають читати код.
Версія 3: скільки піц потрібно за значенням pizzaSize
Уявімо, що ми заздалегідь знаємо, скільки всього шматочків потрібно на всіх, наприклад по 3 на людину. Тепер хочемо зрозуміти, скільки цілих піц купити та скільки шматочків залишиться «на ранок» (ранок, звісно, настане не в усіх).
package main
import "fmt"
func main() {
people := 5
slicesPerPerson := 3
pizzaSize := 8
totalSlices := people * slicesPerPerson
pizzas := totalSlices / pizzaSize
left := totalSlices % pizzaSize
fmt.Println(pizzas, left) // 1 7
}
Вийшло 1 7: одна ціла піца і ще 7 шматочків зверху. Тобто фактично потрібно 2 піци, але тут ми впираємося в те, що в нас поки немає умов if. Тому зараз ми чесно показуємо результат ділення та остачу. Трохи пізніше, коли з’являться умови, ми навчимося коректно й автоматично округляти вгору в таких задачах.
7. Типові помилки під час роботи з int і арифметикою
Помилка №1: очікувати дробовий результат від int / int.
Дуже легко за звичкою думати, що 7 / 2 має дати 3.5. Але якщо обидва числа — int, результат теж int, а дробова частина відкидається. Якщо вам потрібні «справжні дроби», це окрема тема, і там будуть інші типи чисел та інші звички.
Помилка №2: забувати про пріоритет операторів і отримувати «дивні» відповіді.
Вираз a + b*c рахується як a + (b*c), а не як (a+b)*c. Якщо порядок важливий, дужки — ваш найкращий друг. Навіть коли дужки не обов’язкові, вони часто роблять намір коду очевидним і рятують від помилок під час читання.
Помилка №3: плутати % з відсотками.
Символ схожий на знак відсотка, але це остача. 17 % 5 — це не 17 відсотків від 5 і не 5 відсотків від 17. Це те, що залишилося, коли ми поділили 17 на 5 порівну. Дуже корисна операція, особливо в задачах на парність, час і поділ.
Помилка №4: випадково ділити на нуль (/ 0 або % 0).
Ділення на нуль для int — це не «помилка компіляції», а помилка виконання: програма впаде. Зараз у нас ще немає умовних операторів, щоб акуратно перевіряти дільник, тому запам’ятайте просте правило: дільник має бути ненульовим, і про це треба подбати заздалегідь.
Помилка №5: обчислювати відсоток як done / total * 100.
За цілочисельного ділення done / total часто перетворюється на 0, і далі все теж стає 0. У цілочисельній арифметиці зазвичай роблять навпаки: (done * 100) / total. Це не «хак», а нормальний прийом роботи з int, коли вам потрібен цілий відсоток без дробів.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ