Для чего нужен стандарт оформления кода

Обновлено: 16.06.2024

Автор курса по С++ в Яндекс.Практикуме Маша Гутовская рассказала, что такое красивый код, и объяснила, почему начинающим разработчикам важно сразу учиться писать код красиво. В конце текста вас ждет чеклист с советами и полезными материалами.

Зачем писать красивый код

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

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

Три уровня красоты кода

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

Уровень восприятия
Код должен быть красиво организован. Важны названия переменных, размеры классов, функций и методов, а также частота использования условных выражений. Обилие if, else и switch case создаёт нагромождение условий и частных случаев. И это не только визуальная проблема: такой код сложнее понимать, дорабатывать и поддерживать.

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

Code smells и рефакторинг

Допустим, вы написали код. Прошло полгода, вы успели поучаствовать в разных проектах и написать не одну сотню строк. Стоит ли возвращаться к нему и делать рефакторинг? Обязательно. Во-первых, это повысит качество самого кода, а вы научитесь замечать детали, которые надо исправлять и которых стоит избегать в будущем. Во-вторых, вероятно, вам будет нужно время от времени рефакторить и чужой код — сможете набить руку на своём же старом. В блоке полезных ссылок в конце статьи вы найдете ссылку на отличный ресурс о том, как делать правильный рефакторинг.

Разберём код, в котором можно найти много проблем:

Этот код вполне соответствует правилам оформления. Но что мешает понять его легко и быстро?

Запутанные наименования, которые только усложняют понимание

Визуальный мусор

  • Мёртвый код (закомментированный вызов ProcceedElementsCheck). Довольно сложно, на мой взгляд, понять, какой логики придерживался автор на этом участке. Причина — закомментированный код.

Проблемы с документированием

  • Комментарий над функцией явно устарел и сбивает с толку.

Как написать красивый код

1. Следуйте правилам оформления кода (или coding conventions). Даже если вы фрилансите или учитесь, приобретите привычку всегда писать красиво.

2. Используйте специальные инструменты. Для корректировки кода под конкретный стайлгайд существует множество различных плагинов, скриптов и шаблонов для разных сред программирования. IDE (Integrated Development Environment) успешно автоматизирует этот процесс, а вы сможете и время сэкономить, и новый навык освоить.

Вот несколько полезных инструментов для автоматизации.

Plug-in Beautifier для вашей IDE — плагин, который сделает код единообразным, отформатирует, уберёт всё лишнее.

Clang-format — инструмент для автоматического форматирования кода без запуска IDE.

Google C++ Style Guide — руководство по стилю Google, которое можно взять за основу и использовать для создания собственного стайлгайда.

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

4. Освойте принципы SOLID. Нужно, чтобы ваш код не рассыпался при попытках коллег внести в него изменения.

5. Не забывайте про ревью. Код-ревью — это процесс, во время которого ваш код просматривают и комментируют члены команды. Хороший ревьюер укажет не только на баги в коде, но и на архитектурные недочёты и плохой стиль написания. Кроме этого, он объяснит, как можно было бы сделать работу быстрее и проще. Чтобы писать красивый и правильный код, внимательно относитесь к комментариям ревьюера, и тогда с каждой итерацией недочётов будет всё меньше.

6. Оставляйте время для рефакторинга. После рефакторинга ещё раз протестируйте код. Будет лучше, если ошибки заметите вы, а не ребята из вашей команды или пользователи.

7. Изучайте код новых проектов в open source. Это поможет вам быть в курсе новых практик и подходов. Следите за проектами, которые вам нравятся, смотрите, как и на чём они написаны, задавайте вопросы разработчикам.

Перед тем как начнём, хочу сказать что эта статья подойдёт для программиста любой квалификации. Если вы начинающий, то статья поможет избежать ряда потенциально вредных привычек. Для продвинутых - избавиться от уже приобретённых, можно хорошо писать код, но непонятно для остальных.
Научиться хорошему стилю в программировании полезно. Автор сам в начале карьеры писал, плохо оформляя код, в итоге ему пришлось со временем избавляться от вредных привычек, что было непросто. Некоторые из рекомендаций 100% верны, другие субъективны и могут быть оспорены. В таких случаях будет даваться несколько вариантов оформления.


Лучше всего в начале плагина написать комментарии, объясняющие что этот плагин делает. Туда же поместить пояснения к настройкам, авторство, благодарности и.т.п.
Типичный блок примерно таков:

  • Чётко описаны функционал и тематика
  • Указано для какой игры
  • Расписаны команды. Опционально, можно описать и в теле плагина, но здесь гораздо удобнее для пользователя.
  • Благодарности. Указывайте не только в теме, где постите плагин, но и в исходнике.
  • Информативный лог изменений дабы пользователи знали чего ждать от какой версии

Подобный стиль позволяет нам избежать ошибки принятия макросов за переменные и является общепризнанным. Исключение только одно:

Подобное приемлемо, потому что макрос по существу действует как функция, а не просто хранит данные в памяти.
Не стоит подключать лишнее. Например, если не используете функции модуля FakeMeta , то не надо добавлять fakemeta.inc .

Код в теле условия следует табулировать(проставлять отступы). Будет видно где что находится.

  • при взятии параметра в скобки
  • сразу после условия и ключевого слова
  • до и после каждого оператора с 2 параметрами
  • После запятой

Это не является стандартом и вполне обсуждаемо, но логично для читабельности кода. Также имеет смысл добавление 2 переводов каретки вместо одного между функциями.


Важно для переменных и функций. Эта глава неоднозначна и может быть оспорена, однако автор верит что стиль написания "camel case" наиболее предпочтителен.("camel case" - дословно "верблюжий регистр". Здесь автор имеет в виду двугорбых верблюдов в качестве примера перемежающихся букв верхнего и нижнего регистров. Например, сокращение "СортСемОвощ", - прим.переводчика)
Ниже представлен упрощённый вариант "camel case", называемый "mixed case"("смешанный регистр"), автору такой стиль нравится больше.
В именах функций первую буква каждого слова делайте заглавной

В полном варианте "camel case" следует с большой буквы писать каждую первую букву каждого слова, независимо от того, переменная перед нами или нет.

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

Аналогом можно считать нижнее подчёркивание вместо слитного написания, однако согласитесь, что выглядит несколько странно

Хотя и жизнеспособно. Используйте одно из двух - camel/mixed case или подчёркивание, но не смешивайте их.
Как отмечено ранее, макрос всегда пишется в верхнем регистре.


Много ошибок может быть из-за незнания что что-то глобально. Все глобальные переменные должны быть обозначены буквой g.

Каждую такую переменную следует писать с новой строки и с добавлением перевода каретки для облегчения поиска

  • g or g_ - глобальные переменные (global)
  • p or p_ - указатели (Pointer. Приемлемо. А вот обозначений ниже лучше избегать)
  • i - целое число (integer)
  • f or fl - число с плавающей точкой (float)
  • sz - строковые переменные (string)
  • b - логические типы (boolean)
  • h - дескрипторы (handlers. Могут использоваться вместо тэга указателя, что технически не является ошибкой)
  • v - векторы (Vector. Не стандарт, но всё ещё полезно). К примеру, такая запись векторов/ координат new Float: g_fvOrigin[3];
  • fn - функции (Fubction. устарело даже по меркам HN)

Если вы не пользуетесь HN, автор советует применять "g" вместо "g_".
С точки зрения технического анализа Венгерская запись актуальна только для указателей и глобальных переменных. Pawn не содержит типов и поэтому не коррелирует с к актуальными типами данных. Префикс для Boolean бессмысленен, типы float и cell конвертируются виртуальной машиной AMXX при надобности.


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

Первый удобнее, так как закрывающая скобка расположена вертикально над открывающей, мы можем визуально провести линию сверху вниз и понять какой именно блок выделен.

  • В блоке только один вызов функции или одна операция. Например, log_amx( "%d", get_user_kills( id ) )
  • There is a single code block inside it, even if it contains a lot more code that does not fit in a single function call.

Оба способа жизнеспособны и не вызывают проблем при компиляции.
В целом отбрасывание скобок в исключениях субъективно. Находится масса аргументов за и против. С одной стороны, пишем меньше кода. С другой, код менее читабелен. Временами встречается промежуточное решение - табуляция вместо скобок. Так или иначе, все эти варианты приемлемы.


Оставление комментариев - важная составляющая хорошего стиля.
Большие тексты вне функций должны быть закомментированы с использованием операторов "/*" и "*/" , первый открывает блок, второй закрывает.
В случае однострочных комментариев используйте знак // . Учтите, что Pawn не поддерживает вложенные комментарии, то есть вот так делать не надо

Выглядит не очень и больше подходит для ситуаций когда надо что-то быстро проверить/отладить.

Старайтесь, чтобы длина любой строки не превышала 80 символов, не у всех широкоформатные мониторы. К тому же слишком большую длину может жаловаться компилятор. Некоторые добавляют в начало комментария 1-2 пробела для повышения читабельности.
Комментарий должен быть максимально нагляден и отражать суть: что делается и каков ожидается результат.
Например, вот этот бесполезен, так как из его содержания ничего не понять

Комментарии следует размещать также между большими отдельными блоками программы. Например, в форме заголовков или мини-описаний


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

set_pcvar_num, устанавливающий значение, имеет мало что общего с нахождением игрока и убийством, поэтому отделён.


Как показывает опыт, имена переменных и функций должны быть максимально описательными. Ниже пример плохого имени

Название говорит нам всё что нужно знать. Можно даже предположить что переменная целочисленного типа.

Желательно проставлять тэги, например "Event" у события или "Forward" у форварда.

Часто вы увидите краткую пометку, то есть не "Forward", а "Fwd", так тоже можно. Важно отделить подобные функции от остальных служебных.

Здесь то, что по смыслу не вошло в предыдущие главы.

По возможности пользуйтесь константами


Знак ";" полезен если вы планируете переходить с Pawn на другой язык(C/C++/PHP), но часто допускаете ошибки в его использовании. Например, многие не знают, что в конце цикла "do. while" должна стоять одна ";" . Опытному программисту не составит труда переключаться между наличием и отсутствием ";" . Так как Pawn позволяет не использовать ";" , то нет смысла проставлять лишний раз. Заставить компилятор требовать обязательного расставления ";" в конце строк можно директивой


Иногда, при записи API или заголовка, вам придётся документировать свои функции таким образом, чтобы другие могли их понять. Doxygen (исходный код, документирующий пакет программного обеспечения) использует определенный формат, который AMXX начал использовать после добавления SQLx. Вероятно, это является лучшим способом, потому что такая запись наиболее читабельна. Вот пример Doxygen-задокументированной служебной функции:

Освоение вышеперечисленных нехитрых приёмов сделает ваш код удобнее для изучения как вам, так и сторонним пользователям. Автор надеется, что читатель в дальнейшем будет пользоваться хотя бы некоторыми из них. Часто люди находят простые правила оформления кода излишними, трудоёмкими, но поверьте, копаться в коде без комментариев и выдержанной стилистики - удовольствие ниже среднего, не говоря уже о затраченном на понимание времени.

1. Касательно "camel case"/"mixed case" в регистрах.

Спорно. Как правило там, где нету явного указания области видимости, различают именно по первой букве. Если большая то переменная глобальная, иначе локальная. В python-е принято обозначать приватные свойства через "_" в начале.

2. На скорость выполнения кода наличие или отсутствие скобок и комментариев никак не влияет, поэтому в первую очередь думайте о читабельности.

3. Хорошей практикой является самодокументированый код. Это такой код, где из названия переменной сразу понятно для чего она предназначена и в коментировании не нуждается. Также стоит сохранять баланс между коментариями и без них. Наилучший вариант - самодокументированный код и комментарии в тех местах, которые сложно понять с первого взгляда.

4. Автор пишет, что не стоит в конце каждой строки проставлять знак ";". Так говорили в начале 2000-ых касательно JavaScript. В итоге понадобились годы дабы убедить всех использовать везде ";". То, что компилятор AMXX сам их проставляет вовсе не означает, что он не может ошибиться. Потому лучше добавлять, благо наличие либо отсутствие ";" никак не сказываеться на производительности.

Соглашения по оформлению кода команды RSDN

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

Данные правила являются плодом коллективного труда команды RSDN, но мы позволяем использовать их кому угодно. :) При перепечатке или использовании этих правил в качестве основы для ваших собственных сделайте ссылку на этот документ.

Список терминов

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

Именование идентификаторов

Общие правила

  1. Помните! Код чаще читается, чем пишется, поэтому не экономьте на понятности и чистоте кода ради скорости набора.
  2. Не используйте малопонятные префиксы или суффиксы (например, венгерскую нотацию), современные языки и средства разработки позволяют контролировать типы данных на этапе разработки и сборки.
  3. Не используйте подчеркивание для отделения слов внутри идентификаторов, это удлиняет идентификаторы и затрудняет чтение. Вместо этого используйте стиль именования Кемел или Паскаль.
  4. Старайтесь не использовать сокращения лишний раз, помните о тех, кто читает код.
  5. Старайтесь делать имена идентификаторов как можно короче (но не в ущерб читабельности). Помните, что современные языки позволяют формировать имя из пространств имен и типов. Главное, чтобы смысл идентификатора был понятен в используемом контексте. Например, количество элементов коллекции лучше назвать Count, а не CountOfElementsInMyCollection.
  6. Когда придумываете название для нового, общедоступного (public) класса, пространства имен или интерфейса, старайтесь не использовать имена, потенциально или явно конфликтующие со стандартными идентификаторами.
  7. Предпочтительно использовать имена, которые ясно и четко описывают предназначение и/или смысл сущности.
  8. Старайтесь не использовать для разных сущностей имена, отличающиеся только регистром букв. Разрабатываемые вами компоненты могут быть использованы из языков, не различающих регистр, и некоторые методы (или даже весь компонент) окажутся недоступными.
  9. Старайтесь использовать имена с простым написанием. Их легче читать и набирать. Избегайте (в разумных пределах) использования слов с двойными буквами, сложным чередованием согласных. Прежде, чем остановиться в выборе имени, убедитесь, что оно легко пишется и однозначно воспринимается на слух. Если оно с трудом читается, и вы ошибаетесь при его наборе, возможно, стоит выбрать другое.

Стили использования регистра букв

  • Паскаль – указание этого стиля оформления идентификатора обозначает, что первая буква заглавная и все последующие первые буквы слов тоже заглавные. Например, B ack C olor, L ast M odified, D ate T ime.
  • Кэмел – указание этого стиля обозначает, что первая буква строчная, а остальные первые буквы слов заглавные. Например, b order C olor, a ccess T ime, t emplate N ame.

Сокращения

  1. Не используйте аббревиатуры или неполные слова в идентификаторах, если только они не являются общепринятыми. Например, пишите GetWindow, а не GetWin.
  2. Не используйте акронимы, если они не общеприняты в области информационных технологий.
  3. Широко распространенные акронимы используйте для замены длинных фраз. Например, UI вместо User Interface или Olap вместо On-line Analytical Processing.
  4. Если имеется идентификатор длиной менее трех букв, являющийся сокращением, то его записывают заглавными буквами, например System. IO, System.Web. UI. Имена длиннее двух букв записывайте в стиле Паскаль или Кэмел, например Guid, Xml, xmlDocument.

Выбор слов

Пространства имен

Импорт пространств имен (директива using)

  1. Все не вложенные типы (размещаемые в пространствах имен или непосредственно в глобальном пространстве), за исключением делегатов, должны находиться в отдельных файлах.
  2. Старайтесь объявлять вложенные типы в начале внешнего типа.
  3. Старайтесь не делать излишней вложенности типов. Помните, что вложенными должны быть только тесно связанные типы.

Элементы типов (type members)

  1. Элементы типов должны отделяться одной строкой друг от друга. Вложенные типы должны отделяться двумя строками. При объявлении большого количества полей, используемых внутри класса (не публичных), можно опускать пустую строку (особенно если поля отделены XML-комментариями).

Классы/Структуры

Интерфейсы

  1. Используйте описывающее существительное, прилагательное или одно или несколько прилагательных и существительное для идентификатора интерфейса. Например, IComponent – это описывающее существительное, ICustomAttributeProvider – это конкретизированное прилагательными существительное, а IPersistable – это характеризующее прилагательное.
  2. Используйте стиль Паскаль для регистра букв.
  3. Используйте префикс I (заглавная i) для интерфейсов, чтобы уточнить, что тип является интерфейсом. Старайтесь избегать интерфейсов с двумя I в начале, например IIdentifiable. Попробуйте подобрать синоним, например IRecognizable.
  4. Для пары класс-интерфейс, в которой класс является некоторой стандартной или эталонной реализацией интерфейса, используйте одинаковые имена, отличающиеся только префиксом I для интерфейса. Например, IConfigurationManager и ConfigurationManager.

Атрибуты

  1. Класс, являющийся атрибутом, должен иметь суффикс Attribute. Ни один класс, атрибутом не являющийся, не должен иметь такого суффикса. Если семантика класса требует в названии слова что-то вроде Attribute, используйте синонимы, например Descriptor, Sign, Qualifier, Specifier, Declarator.

Перечисления

  1. Непубличные поля (private, protected и protected internal) именуются в стиле Кэмел и начинаются с префикса _.
  2. Публичные поля именуются в соответствии с правилами именования свойств.
  3. Одна декларация должна содержать не более одного поля и должна располагаться на одной строке.
  1. Публичные поля должны в обязательном порядке документироваться XML-комментариями. Желательно снабжать XML-комментариями и непубличные поля.
  2. Обращаясь к публичным полям старайтесь избегать их передачи по ссылке, т.к. велика вероятность того, что в следующих версиях приложения эти поля могут стать свойствами.

Методы

  1. Используйте глаголы или комбинацию глагола и существительных и прилагательных для имен методов.
  2. Используйте стиль Паскаль для регистра букв (вне зависимости от области видимости метода).

Свойства

  1. Используйте существительное или одно или несколько прилагательных и существительное для имени свойства.
  2. Используйте стиль Паскаль для регистра букв.
  3. В подходящих случаях используйте имя свойства, совпадающее с типом его значения. Одним из критериев для применения этого правила является наличие единственного свойства со значением некоторого (нетривиального) типа.
  4. Старайтесь избегать использования имен свойств, совпадающих с названиями каких-либо типов, если значения этих свойств не являются значениями этих типов. В этом случае будет трудно получить доступ к статическим членам типа или значениям перечисления. Например, при использовании конструкции public int Color < get; set; >, обращение Color.Xxx будет рассматриваться как получение свойства Color и затем доступ к свойствам или методам этого значения, которое в данном случае будет являться типа System.Int32.
  5. Рассмотрите возможность включения имени типа в идентификатор свойства, особенно если этот тип – перечисление. Например, OuterBorderStyle , BackColor, SocketFlags.

События

  1. Используйте суффикс EventHandler для делегатов, являющихся типами событий. Другие классы не должны использовать этот суффикс.
  2. Создавая событие в компонентах и control-ах, старайтесь описывать их по следующей схеме. Определите два параметра с именами sender и e. Параметр sender описывает объект, инициировавший событие, и всегда должен быть типа object, даже если возможно использование более конкретного типа. Второй параметр, e, должен содержать состояние и дополнительную информацию, соответствующую событию. Этот параметр должен быть конкретного типа, относящегося к событию.
  3. Делайте тип, описывающий связанную с событием информацию, производным от EventArgs, и используйте суффикс EventArgs . Другие классы, не описывающие информацию о событии, не должны использовать этот суффикс.
  4. Для имен событий старайтесь использовать глаголы, которые описывают производимое над объектом действие (например, Click, GotFocus или FontChanged).
  5. Не используйте суффиксы наподобие On, Before, After для идентификатора события. Используйте соответствующую форму глагола, например Closing перед закрытием и Closed после закрытия.
  6. При описании события также предоставляйте виртуальный protected-метод, который можно переопределить в классе-наследнике. Называйте такой метод OnXxx, где Xxx – имя события. В качестве параметров таких методов не следует передавать sender , так как – это всегда текущий объект (this).
  7. Пытайтесь подобрать стандартный делегат и название для своих событий. Например, если ваш элемент управления должен реагировать на нажатие кнопки мыши, следует использовать стандартное событие Click. Для элементов управления, обычно, такие события уже объявлены в базовом классе Control.

Параметры

Стиль кода

Оформление

  1. Используйте табуляцию , а не пробелы для отступов. В средах типа VS лучше использовать режим табуляции. Его можно настроить в диалоге Options -> Text Editor -> Ваш_любимый_язык ->Tabs: Indenting = Smart, Tabs = Keep Tabs. В общем, это настройки по умолчанию для многих языков.
  2. При форматировании текста (кроме отступа в начале строки) используйте пробелы. Для этого удобно использовать режим Virtual Space, который в VS 2002 настраивается в Options -> Text Editor -> Ваш_любимый_язык -> General.
  3. Избегайте строк длиннее 78 символов, переносите инструкцию на другую строку при необходимости.
  4. При переносе части кода инструкций и описаний на другую строку вторая и последующая строки должны быть отбиты вправо на один отступ (табуляцию).
  5. Оставляйте запятую на предыдущей строке так же, как вы это делаете в обычных языках (русском, например).
  6. Избегайте лишних скобок, обрамляющих выражения целиком. Лишние скобки усложняют восприятие кода и увеличивают возможность ошибки. Если вы не уверены в приоритете операторов, лучше загляните в соответствующий раздел документации.
  7. Не размещайте несколько инструкций на одной строке. Каждая инструкция должна начинаться с новой строки.

Пустые строки

  1. Используйте две пустые строки между логическими секциями в исходном файле.
  2. Используйте две пустые строки между объявлениями классов и интерфейсов.
  3. Используйте одну пустую строку между методами.
  4. Если переменные в методе объявляются отдельным блоком, используйте одну пустую строку между их объявлением и инструкцией, идущей за этим блоком.
  5. Используйте одну пустую строку между логическими частями в методе.

Пробелы в строке

  1. После запятой должен быть пробел. После точки с запятой, если она не последняя в строке (напр. в инструкции for), должен быть пробел. Перед запятой или точкой с запятой пробелы не ставятся.
  2. Все операторы должны быть отделены пробелом от операндов с обеих сторон.
  3. Логически связный блок регулярной структуры желательно форматировать в виде таблицы. При этом для выравнивания в таблице следует использовать пробелы, но не табуляцию. Среды типа VS автоматизируют процесс форматирования, вставляя пробелы или табуляции в соотвтествии с пользовательскими настройками. Будьте внимательны и проверяйте конечный результат, включая неотображаемые символы (для VS 2002 и старше – меню Edit->Advanced->View White Space).

Для упрощения работы можно использовать следующий трюк. Таблицу можно сформировать с помощью табуляции, выделить область прямоугольным выделением (Alt + курсор мыши вправо), а затем применить к этой области Edit->Advanced->Untabify Selection.

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

  1. Точно представлять логическую структуру кода. Смысл форматирования — показать логическую структуру кода. Для демонстрации логической структуры программисты обычно применяют отступы и другие неотображаемые символы.
  2. Единообразно показывать логическую структуру кода. Некоторые стили форматирования состоят из правил с таким количеством исключений, что последовательно их соблюдать практически невозможно. Действительно хороший стиль подходит в большинстве случаев.
  3. Улучшать читабельность. Стратегия использования отступов, соответствующая логике, но усложняющая процесс чтения кода, бесполезна. Схема форматирования, использующая пробелы и разделители только там, где они требуются компилятору, логична, но читать такой код невозможно. Хорошая структура форматирования упрощает чтение кода.
  4. Выдерживать процедуру исправления. Лучшие схемы форматирования хорошо переносят модификацию кода. Исправление одной строки не должно приводить к изменению нескольких других.

Стиль форматирования

Базовый стандарт оформления кода: Kernighan & Ritchie (K&R)

Данный стиль использует стиль расстановки скобок при котором скобка переносится на новую строку при определении пространств имен (namespaces), классов (classes), функций, в остальных случаях скобка остается на той же строке, где располагается часть кода, к которой она (скобка) принадлежит. Отступ в данном стиле равняется 4-м пробелам.

Расстановка скобок как в стиле (K&R) соответствует формату явных блоков для управляющих структур.

Способы форматирования

Неотображаемые символы, к которым относятся пробелы, знаки табуляции, переводы строк и пустые строки, — это основное средство для демонстрации структуры программы.

Способ применения неотображаемых символов — группировка взаимосвязанных выражений, т.е. выделение связанных между собой конструкций в отдельный блок. Кроме необходимости группировать взаимосвязанные операторы, очень важно отделять несвязанные выражения друг от друга. Для этого можно использовать пустые строки. Они позволяют продемонстрировать организацию программы. Вы можете использовать их для деления групп взаимосвязанных операторов, отделения методов друг от друга и выделения комментариев.

Логический блок - группа подходящих друг к другу операторов. Отделяйте их друг от друга с помощью пустых строк.

Отступы применяются для демонстрации логической структуры программы. Как правило, операторы выделяются отступами, когда они следуют после некоторого выражения, от которого они логически зависят.

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

Форматируйте блоки из одного оператора единообразно. Блоком из одного оператора называется единственный оператор, следующий за управляющей структурой. Причем форматирование с использованием скобок более предпочтително.

Форматирование строк, длина операторов/выражений

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

В сложных выражениях размещайте каждое условие на отдельной строке.

Делайте так, чтобы незавершенность выражения была очевидна, например, помещая оператор соединяющий выражения в начале новой строки (см. также пример выше).

Не выравнивайте правые части выражений присваивания, в дальнейшем поддержка такого форматирования может привести только к пустой трате времени.

Пример (не нужное выравнивание):

Всегда располагайте один оператор на строке. Это даст следующее:

  1. Точное представление о сложности программы.
  2. Если операторы расположены на отдельных строках, чтение кода происходит сверху вниз, без необходимости чтения слева на право.
  3. При размещении операторов на отдельных строках легко найти синтаксические ошибки, если компилятор сообщает только номера строк, где они произошли. При расположении нескольких операторов на одной строке ее номер ничего не скажет о том, какой оператор содержит ошибку.
  4. Когда строка содержит только один оператор, его легко редактировать — можно удалить или временно закомментировать всю строку.

Функции

Операторы if/else, do, while

Расстановка скобок cоответствует формату явных блоков.

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

do / while следует писать так:

Операции

Необходимо вставлять пробел между операциями присваивания, логическими и арифметическими операциями.

Не оставлять пробела после унарной операции.

Правила именования

Комментирование

Начинайте каждый файл с комментария, информации о правах и лицензии:

или более краткая версия:

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

Заголовочные файлы

В заголовочный файл можно помещать следующее:

  • директивы include
  • определения типов данных
  • определения структур, классов для С++
  • прототипы (объявления) функций, только не статических функций
  • определения inline-функций (для С++)
  • определения констант
  • перечисления
  • макроопределения
  • комментарии

В заголовочном файле не должно быть:

  • определения обычных функций
  • определения данных
  • определения сложных константных объектов

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

Для того, что бы не проиcходило повторного включения заголовочного файла, включайте в него следующие инструкции:

Где MODULE - это имя заголовочного файла.

Настройка GNU Emacs

Если вы пользуетесь редактором GNU Emacs, то добавьте в файл ~/.emacs следующие строки для того, чтобы описанный в этом документе стиль использовался по умолчанию при редактировании исходного кода на языке C:

Читайте также: