C++

Code Style: угоди про оформлення коду

Угоди про іменування, відступи, дужки та коментарі в C++. Java-подібний стиль, прийнятий у курсі. Чому читабельний код важливіший за «просто працюючий».

Чому форматування — це не косметика

Більшість новачків думають, що головне — щоб програма працювала. Все інше (відступи, пробіли, регістр літер) — це «прикраси для естетів». Насправді це глибока помилка.

Дослідження індустрії показують: розробники витрачають на читання коду у 5–10 разів більше часу, ніж на написання. Код, якому важко читати, стає джерелом помилок, ускладнює налагодження, сповільнює командну роботу. У великих компаніях — Google, Microsoft, JetBrains — existed цілі документи, що регламентують кожен аспект оформлення коду. Такі документи називаються code style або coding conventions (угоди про стиль).

У цьому курсі ми дотримуємося стилю, наближеного до Java-конвенцій — одного з найбільш поширених і читабельних стандартів у світі. C++ не має єдиного «офіційного» стандарту (на відміну від Java чи Go), тому різні проєкти використовують різні підходи. Обраний нами стиль — добре знайомий Java-розробникам і чітко читається.

Консистентність важливіша за «правильність». Немає єдиного «правильного» стилю — є стиль вашої команди або проєкту. Найгірше — писати в одному проєкті по-різному в кожному файлі.

Іменування (Naming Conventions)

Іменування — найважливіший аспект стилю. Правильно підібрані імена роблять код самодокументованим: читачу не потрібні коментарі, щоб зрозуміти, що зберігає змінна studentAge, а не x34.

Змінні та функції — camelCase

camelCase (верблюжий регістр): перше слово — з малої літери, кожне наступне — з великої. Пробіли відсутні.

// ✅ Правильно — camelCase
int studentAge = 20;
double accountBalance = 1500.75;
bool isLoggedIn = false;
int numberOfAttempts = 3;
// ❌ Неправильно
int student_age = 20;      // snake_case — стиль Python/C-системний
int StudentAge = 20;       // PascalCase — стиль для класів
int studentage = 20;       // lowercase без роздільника — нечитабельний
int sa = 20;               // Надто скорочено
Назви мають бути змістовними іменниками або прикметниками. Типові шаблони:
  • Стан / ознака: isActive, hasError, canEdit (для bool)
  • Кількість: count, numberOfStudents, totalAmount
  • Сутність: firstName, emailAddress, itemPrice

Константи — SCREAMING_SNAKE_CASE

Константи (оголошені через const) пишуться великими літерами з підкресленнями між словами. Це одразу виділяє їх серед змінних у коді.

// ✅ Правильно
const int DAYS_IN_WEEK = 7;
const double PI = 3.14159265;
const int MAX_STUDENTS = 30;
const double TAX_RATE = 0.2;
// ❌ Неправильно
const int daysInWeek = 7;  // Виглядає як звичайна змінна
const int Days_In_Week = 7;  // Непослідовний регістр

Ця конвенція — одна з небагатьох, де C++ та Java повністю збігаються. Побачивши MAX_BUFFER_SIZE у коді, будь-який досвідчений розробник одразу розуміє: це константа.

Файли — PascalCase

Імена файлів .cpp та .h пишуться у стилі PascalCase (кожне слово з великої літери), без пробілів і спеціальних символів:

// ✅ Правильно
Triangle.cpp
StudentRecord.cpp
DataConverter.cpp

// ❌ Неправильно
triangle.cpp
student_record.cpp
data-converter.cpp
my program.cpp

Зведена таблиця конвенцій іменування

Що іменуємоСтильПриклад
ЗміннаcamelCasestudentAge, isValid
ФункціяcamelCasecalculateTotal(), printResult()
КонстантаSCREAMING_SNAKE_CASEMAX_SIZE, PI
Клас / СтруктураPascalCaseStudentRecord, BankAccount
ФайлPascalCaseTriangle.cpp, Main.cpp

Відступи (Indentation)

Відступ (indentation) — це пробіли на початку рядка, що візуально показують вкладеність блоків коду. Без відступів навіть проста програма перетворюється на нечитабельну стіну тексту.

У нашому курсі використовуються 4 пробіли на кожен рівень вкладеності (Java-конвенція).

// ✅ Правильно — 4 пробіли
int main()
{
    int age = 20;
    if (age >= 18) {
        cout << "Adult\n";
        if (age >= 65) {
            cout << "Senior\n";
        }
    }
    return 0;
}
// ❌ Неправильно — відступи відсутні або непослідовні
int main()
{
int age = 20;
  if (age >= 18) {
    cout << "Adult\n";
        if (age >= 65) {
cout << "Senior\n";
        }
  }
return 0;
}
У Visual Studio та більшості IDE клавіша Tab автоматично вставляє відступ потрібного розміру. Не потрібно натискати пробіл чотири рази вручну.

Розміщення фігурних дужок (Brace Style)

Стиль розміщення фігурних дужок { і } — одне з найвідоміших «релігійних питань» серед програмістів. У C++ є два основні стилі:

Відкриваюча дужка — на новому рядку, вирівняна з оголошенням. Відповідає Java/C# стилю для функцій та класів і є стандартом у Microsoft-орієнтованому C++.

int main()
{
    if (condition)
    {
        // тіло
    }
}

Перевага: дужки легко знайти та зіставити пару.

У цьому курсі ми використовуємо стиль Allman для функцій і main(). Це відповідає налаштуванням за замовчуванням у Visual Studio та добре читається при навчанні, бо чітко виділяє межі кожного блоку.

Пробіли навколо операторів

Пробіли навколо операторів — це «дихання» коду. Вони не впливають на роботу програми, але радикально впливають на читабельність.

Арифметичні та логічні оператори

// ✅ Правильно — пробіли навколо операторів
int result = a + b * c;
bool isValid = (age >= 18) && !isBanned;
double percent = (double)correct / total * 100;
// ❌ Неправильно — оператори «злиплися»
int result=a+b*c;
bool isValid=(age>=18)&&!isBanned;

Оператор присвоєння

// ✅ Правильно
int age = 25;
double height = 1.75;
// ❌ Неправильно
int age=25;
double height =1.75;

Виклики та визначення функцій

Пробіл між іменем функції та дужкою — відсутній. Після коми в списку аргументів — є:

// ✅ Правильно
int main()
cout << max(a, b, c);
// ❌ Неправильно
int main ()          // Пробіл між іменем та дужкою
cout << max(a,b,c);  // Відсутні пробіли після ком

Пробіли у ключових словах

Після ключових слів if, for, while, switchзавжди пробіл перед дужкою, щоб відрізнити їх від виклику функції:

// ✅ Правильно
if (x > 0)
while (flag)
for (int i = 0; i < 10; i++)
// ❌ Неправильно (виглядає як виклик функції)
if(x > 0)
while(flag)
for(int i = 0; i < 10; i++)

Порожні рядки (Blank Lines)

Порожні рядки в коді — як абзаци в тексті: вони структурують і групують логічно пов'язані частини.

ShoppingCart.cpp
#include <iostream>

using namespace std;

int main()
{
    // --- Вхідні дані ---
    float itemPrice;
    int quantity;
    float discountRate = 0.1;

    cout << "Enter price: ";
    cin >> itemPrice;

    cout << "Enter quantity: ";
    cin >> quantity;

    // --- Обчислення ---
    float subtotal = itemPrice * quantity;
    float discount = subtotal * discountRate;
    float total = subtotal - discount;

    // --- Вивід результату ---
    cout << "Subtotal: " << subtotal << "\n";
    cout << "Discount: " << discount << "\n";
    cout << "Total:    " << total << "\n";

    return 0;
}

Зверніть увагу: логічні групи (ввід, обчислення, вивід) відокремлені порожніми рядками і коментарями-заголовками. Програма зразу ж читається як структурований документ.

Правила використання порожніх рядків:

  • Між #include та using namespace std; — порожній рядок
  • Між групами логічно пов'язаних оголошень
  • Між основними «фазами» алгоритму (ввід / обробка / вивід)
  • Не більше одного порожнього рядка підряд

Коментарі (Comments)

Коментарі — це пояснення для людей; компілятор їх ігнорує. Хороші коментарі пояснюють «навіщо», а не «що» — код сам показує що, а коментар має пояснювати чому саме так.

Однорядкові коментарі //

// Конвертація дюймів у сантиметри (1 дюйм = 2.54 см)
double centimeters = inches * 2.54;

int score = base + bonus;  // Загальний рахунок із бонусом

Блокові коментарі /* */

Використовуються для заголовків файлів або великих пояснень:

/*
 * Програма: Конвертер температур
 * Мета: перетворення Цельсія у Фаренгейт і Кельвін
 * Автор: Ivan Petrenko
 * Дата: 2025-09-01
 */

Що коментувати, а що — ні

// Формула відхилення снаряда з урахуванням опору повітря
double deviation = velocity * sin(angle) - 0.5 * G * time * time;

// ASCII: різниця між кодами великої та малої літери завжди 32
char upper = (char)(lower - 32);

// Перевірка високосного року за правилом Григоріанського календаря
bool isLeap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);

Ці коментарі пояснюють неочевидні речі: математичну формулу, особливість ASCII, бізнес-правило.

Правило «коментар тухне»: якщо ви змінюєте код, але забуваєте оновити коментар — коментар стає хибним і вводить в оману. Краще писати менше коментарів, але актуальних.

Розміщення змінних

У Java-стилі змінні оголошуються на початку відповідного блоку, перед першим використанням. Не рекомендується розкидати оголошення по всьому тілу функції.

// ✅ Правильно — усі змінні на початку
int main()
{
    int a, b, result;
    double ratio;

    cin >> a >> b;
    result = a + b;
    ratio = (double)a / b;

    cout << result << " " << ratio << "\n";
    return 0;
}
// ❌ Небажано — змінні «розкидані»
int main()
{
    int a;
    cin >> a;
    int b;         // Оголошення посеред коду — важче знайти
    cin >> b;
    int result = a + b;
    double ratio = (double)a / b;
    cout << result << " " << ratio << "\n";
    return 0;
}
У сучасному C++ (стандарт C++11 і новіше) прийнятим є оголошення змінної якомога ближче до місця першого використання. Цей підхід (характерний для C++) теж логічний. Але для навчання в курсі ми дотримуємося Java-підходу: усі змінні на початку — це полегшує розуміння структури програми.

Один рядок — одна інструкція

Ніколи не розміщуйте кілька інструкцій на одному рядку. Навіть якщо компілятор це дозволяє.

// ✅ Правильно — по одній інструкції
int a = 5;
int b = 10;
cout << a + b << "\n";
// ❌ Неправильно — кілька інструкцій в одному рядку
int a = 5; int b = 10; cout << a + b << "\n";

Виняток — оголошення кількох змінних одного типу в одному рядку дозволене, якщо вони логічно пов'язані:

int width, height, area;   // ✅ Допустимо — одна логічна група
double x, y, z;            // ✅ Координати — мають сенс разом

Зведення правил стилю

🏷️ Іменування

  • Змінні та функції: camelCase
  • Константи: UPPER_SNAKE_CASE
  • Класи та файли: PascalCase
  • Імена — змістовні, мінімум 3 символи (крім лічильників i, j)

📐 Форматування

  • Відступи: 4 пробіли (не Tab)
  • Дужки: стиль Allman (на новому рядку)
  • Пробіли навколо операторів присвоєння та арифметичних
  • Після ключових слів (if, while) — пробіл

💬 Коментарі

  • Пояснюйте «навіщо», а не «що»
  • Коментар-заголовок для логічних секцій
  • Оновлюйте коментарі при зміні коду
  • Уникайте очевидних коментарів

📦 Структура

  • Змінні — на початку блоку
  • Одна інструкція — один рядок
  • Порожні рядки між логічними групами
  • Максимальна довжина рядку — ~100 символів

Візуальне порівняння: до і після

Нижче — та сама програма, написана двома способами. Логіка ідентична; відрізняється лише оформлення.

#include<iostream>
using namespace std;
int main(){
int a,b,c;float d;
cin>>a>>b;
c=a+b;d=(float)a/b;
cout<<"sum="<<c<<"ratio="<<d;
return 0;}

Обидва варіанти компілюються та дають однаковий результат. Але перший — це код, який важко читати, налагоджувати і розуміти. Другий — це код, який пояснює сам себе.

Автоматичне форматування у Visual Studio

Запам'ятати всі правила одразу складно — і не потрібно. Visual Studio допомагає дотримуватися стилю автоматично:

ДіяКомбінація клавіш
Форматувати весь файлCtrl + K, потім Ctrl + D
Форматувати виділений фрагментCtrl + K, потім Ctrl + F
АвтодоповненняCtrl + Space
Перейти до визначенняF12
Виробіть звичку форматувати файл перед кожним збереженням: Ctrl + KCtrl + D, а потім Ctrl + S. Через кілька тижнів правильне форматування стане автоматичним рефлексом.
Copyright © 2026