Гайд по оформлению кода на С++ от Стэнфордского университета

Стэнфордский университет представил гайд по основным стандартам оформления кода на С++. Умение корректно оформить ваш код является ценным навыком, так как это в разы облегчает работу других. Также у нас есть подобная статья, посвящённая написанию самодокументируемого кода.

Пробелы и отступы

Отделяйте пробелами фигурные скобки:

Ставьте пробелы между операторами и операндами:

Когда строка становится длиннее 100 символов, разделите её на две, сделав перевод на новую строку после оператора, и продолжайте писать:

Оставляйте пустые линии между функциями и между группами выражений:

Названия и переменные

Давайте переменным описательные имена, такие как firstName или homeworkScore. Избегайте однобуквенных названий вроде x или c, за исключением итераторов вроде i.

Называйте переменные и функции, используя верблюжийРегистр. Называйте классы ПаскальнымРегистром, а константы — в ВЕРХНЕМ_РЕГИСТРЕ. Узнать подробнее про верблюжий регистр вы можете в этой статье.

Если переменная используется лишь внутри определенного if, то делайте её локальной, объявляя в том же блоке кода, а не глобальной.

Выбирайте подходящий тип данных для ваших переменных. Если переменная содержит лишь целые числа, то определяйте её как int, а не double.

Используйте текстовую строку, стандартную для C++, а не С. С++ путает тем, что имеет два вида текстовых строк: класс string из С++ и старый char* (массив символов) из С:

Если определенная константа часто используется в вашем коде, то обозначьте её как const и всегда ссылайтесь на данную константу, а не на её значение:

Никогда не объявляйте изменяемую глобальную переменную. Глобальными переменными должны быть только константы. Вместо того, чтобы делать значение глобальным, сделайте его параметром и возвращайте значение, когда необходимо:

Базовые выражения С++

С++ основан на С, поэтому всегда есть вариант решить задачу «путем С++» и «путем С». Например, когда вы желаете вывести что-либо на системную консоль, вы можете сделать это «путем С++» , использовав оператор вывода cout, в то время как «путем С» вы бы использовали глобальную функцию вроде printf:

Частенько затрудняетесь с выбором между for и while? Используйте цикл for, когда вы знаете количество повторений, а цикл while, когда количество повторений неизвестно:

Когда используете операторы управления вроде if / else, for, while, всегда используйте {} и соответствующие отступы, даже если тело всего оператора управления состоит лишь из одной строки:

Старайтесь избегать использования выражений break или continue. Используйте их только в том случае, если это абсолютно необходимо.

В C++ есть функция exit, которая немедленно завершает программу. Настоятельно не рекомендуется использовать данную функцию. Программа всегда должна заканчиваться естественно, достигая оператора return функции main.

Используя выражения if / else, подобающе выбирайте между разнообразными if и else шаблонами в зависимости от условий, относящихся к друг другу. Избегайте излишних тестов if:

Если у вас есть выражение if / else, которое возвращает логическое значение, возвращайте результаты теста напрямую:

Никогда не проверяйте значения логического типа, используя == или != с true или false:

Чрезмерность

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

Переместите общий код из выражения if / else, чтобы он не повторялся:

Комментарии

Заглавный комментарий. Размещайте заглавный комментарий, который описывает назначение файла, вверху каждого файла. Предположите, что читатель вашего комментария является продвинутым программистом, но не кем-то, кто уже видел ваш код ранее.

Заголовок функции / конструктора. Разместите заголовочный комментарий на каждом конструкторе и функции вашего файла. Заголовок должен описывать поведение и / или цель функции.

Параметры / возврат. Если ваша функцию принимает параметры, то кратко опишите их цель и смысл. Если ваша функция возвращает значение — кратко опишите, что она возвращает.

Исключения. Если ваша функция намеренно выдает какие-то исключения для определенных ошибочных случаев, то это требует упоминания.

Комментарии на одной строке. Если внутри функции имеется секция кода, которая длинна, сложна или непонятна, то кратко опишите её назначение.

TODO. Следует удалить все // TODO комментарии перед тем, как заканчивать и сдавать программу.

Эффективность

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

Функции и процедурное проектирование

Хорошо спроектированная функция имеет следующие характеристики:

  • Полностью выполняет четко поставленную задачу;
  • Не берет на себя слишком много работы;
  • Не связана с другими функциями бесцельно;
  • Хранит данные максимально сжато;
  • Помогает распознать и разделить структуру программы;
  • Помогает избавиться от излишков, которые иначе присутствовали бы в программе.

Используйте параметры, чтобы отправлять информацию из функции или когда функции нужно возвратить несколько значений. Не используйте параметры без необходимости. Заметьте, что a,b, и с не являются параметрами в нижеприведенной функции, так как это не нужно:

Когда требуется вернуть значение из функции, используйте значение return:

Отправляя объект в функцию как параметр, вы должны передавать его по ссылке, так как если он будет передан как значение, то будет скопирован весь объект. Копирование объектов требует больших затрат памяти.

Используйте ссылочные переменные, а не указатели. Одна из причин — это то, что ссылочные переменные, в отличие от указателей, не могут принимать значение NULL:

Если вы передаете объект в функцию и код не изменит вида объекта — передайте его как const-ссылку:

Избегайте «цепных» вызовов, когда множество функций вызывают друг друга по цепочке, не возвращая значение в main. Убедитесь, что main является кратким описанием всей программы:

Проектирование классов

Инкапсуляция. Отделяйте ваши объекты, делая все поля данных в вашем классе private:

.h vs .cpp. Всегда размещайте объявления классов и их частей в собственные файлы, ClassName.h. Всегда сворачивайте файлы объявления классов .h в блок препроцессоров #ifndef / define / endif, чтобы избежать множественных объявлений одного класса:

class vs struct. Всегда используйте class, только если вы не создаете очень маленький и простой вид данных, для которого нужны лишь несколько публичных переменных и, возможно, конструктор для их инициализации.

Избегайте ненужных полей. Используйте поля, чтобы хранить важные данные о ваших объектах, но не временные значения, которые используются единожды.

По материалам «Stanford C++ Style Guide»