Skip to content

Latest commit

 

History

History
283 lines (242 loc) · 9.45 KB

styleguide.md

File metadata and controls

283 lines (242 loc) · 9.45 KB

Оформление

  • Пробелы после открывающей скобки и перед закрывающей скобкой не ставятся: f(1, (2 + 3)). Закрывающая скобка должна идти на той же строке, что и последнее выражение.
  • Максимальная длина строки - 100 символов.
  • Перед ; пробел не ставится. После ; в for ставится пробел.
  • Пустые блоки записываются как {} (а не ;).
  • Однострочные комментарии отделяются от кода двумя пробелами и начинаются с пробела.
  • Пробелы в конце строки запрещены.
  • Файл должен заканчиваться переводом строки.
  • В range-base for двоеточие обрамляется пробелами.
  • В начале/конце блока, после public/private/protected пустые строки не ставятся.
  • Перед объявлением функции/структуры/класса - пустая строка обязательна.
  • Секции include-ов и using-ов были упорядочены по алфавиту.

Плохо:

#include <vector>
#include <iostream>

Хорошо:

#include <iostream>
#include <vector>

Плохо:

using std::vector;
using std::cin;
using std::cout;

Хорошо:

using std::cin;
using std::cout;
using std::vector;
  • Имя шаблона и параметр шаблона НЕ должны разделяться пробелом.

Плохо:

vector <int> v;

Хорошо:

vector<int> v;

Именование

  • Имена переменных должны начинаться со строчной буквы.

Плохо

int Distance;

Хорошо

int distance;
  • Не используйте однобуквенных переменных (за исключением счётчиков циклов). Из названия переменной должно быть понятно что в ней хранится.

Плохо

// количество строк и столбцов
size_t a, b;

Хорошо

// количество строк и столбцов
size_t rowCount, columnCount;
  • Не используйте транслит в именах.

Плохо

size_t dlina_massiva;

Хорошо

size_t length;
  • Давайте переменным осмысленные имена. В частности, не используйте однобуквенных имён за исключением имён итераторов (i, j, k, ...), координат (x, y, z).

Плохо

char alf(int j) { 
    ...
}
// или
char alphabet(int j) { 
    ...
}
int ln; // длина

Хорошо

char get_char(int j) {
    ...
}
int length; // длина
  • Для переменных-счётчиков не следует использовать имена DocNum, NumDoc, DocsCount, DocsNum, CountDoc из-за неграмотности и неоднозначности. Для числа элементов (скажем документов) можно использовать NumDocs или DocCount. Для функции, долго и явно подсчитывающей это число, подойдет CountDocs().

  • Функциям, которые возвращают bool, лучше давать имена, начинающиеся на is или has.

Плохо

bool graph_connected() { ... }
bool element(int n) { ... }

Хорошо

bool is_connected_graph() { ... }
bool has_element(int n) { ... }

std::vector

  • Если требуется создать вектор размера n, воспользуйтесь специальным конструктором.

Плохо

vector<int> v;
v.resize(n);

Хорошо

vector<int> v(n);

Циклы

  • Если требуется перебрать элементы коллекции, предпочитайте range-base for. Он лаконичней и легче читается.

Плохо

for (size_t i = 0; i < neighbors_list[vertex].size(); ++i) {
    if (!(visited[neighbors_list[vertex][i]])) {
        dfs(neighbors_list[vertex][i], visited);
    }
}

Хорошо

for (const int& neighbor_vertex : neighbors_list[vertex]) {
    if (!(visited[neighbor_vertex])) {
        dfs(neighbor_vertex, visited);
    }
}

Функции

Функции нужны:

  1. для избежания дублирования кода;
  2. для того, чтобы можно было их переиспользовать много раз в различных проектах.
  • Порядок аргументов функции: сначала входные параметры (по значению либо константой ссылке), затем выходные.

  • Передавайте аргументы в функции по константной ссылке везде, где это уместно.

Плохо

void print_vector(vector<int> v) {
    ...
}

Хорошо

void print_vector(const vector<int>& v) {
    ...
}
  • Не создавайте функции с избыточным числом аргументов. Например, в функцию, печатающую вектор, не нужно передавать размер вектора.

Плохо

void print_vector(const vector<int>& v, int n) {
    for (size_t i = 0; i < n; ++i) {
        cout << v[i] << " ";
    }
}

Хорошо

void print_vector(const vector<int>& v) {
    // Используйте v.size(), чтобы получить длину вектора
    for (size_t i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
}
  • В проекте есть вектор, хранящий путь
vector<int> way

и требуется написать функцию, которая печатает этот путь.

Плохо

void print_way(const vector<int>& way) {
    for (int i : way) {
        cout << i << " ";
    }
}

Хорошо

void print_vector(const vector<int>& v) {
    for (int i : v) {
        cout << i << " ";
    }
}

Тоже хорошо

void print_vector(const vector<int>& v) {
    for (int i : v) {
        cout << i << " ";
    }
}

void print_way(const vector<int>& way) {
    print_vector(way);
}

Плохой вариант плох тем, что теряется свойство переиспользования у функции: вы не сможете использовать её в другом проекте, где, скажем, нужно будет распечатать вектор оценок.

Прочее

  • Необходимо явно подключать заголовочные файлы, в которых объявляются используемые функции/классы/... Запрещено явно подключать один и тот же заголовочный файл дважды.
  • В качестве логических операторов следует использовать &&, ||, ... Их аналоги and, or, ... запрещены.
  • Запрещено использовать приведение типов в стиле СИ - следует использовать *_cast.
  • Конструктор от одного аргумента должен быть объявлен explicit.
  • При объявлении виртуальной функции следует использовать один и только один из спецификаторов virtual, final, override.
  • При объявлении переменной спецификаторы static/extern/... идут перед именем типа.
  • Везде, где это возможно, используйте префиксный инкремент и декремент.

Плохо

i++;
it--;

Хорошо

++i;
--it;
  • Пишите код так, чтобы не было предупреждений (warnings) компилятора. Это нужно по двум причинам:
    1. Обычно компилятор выдаёт предупреждения по делу, на те места, где скрыта потенциальная ошибка.
    2. Если игнорировать "неважные" предупреждения, их может много накопиться и вы не заметите действительно важных.
  • В частности, избегайте сравнений знаковых (int) и беззнаковых (size_t) переменных.

Плохо

for (int i = 0; i < v.size(); ++i) {
    ...
}

Хорошо

for (size_t i = 0; i < v.size(); ++i) {
    ...
}

Спасибо

Инструкция взята по ссылке