Пробелы относятся к символам, которые используются в форматировании кода, вместе с символами табуляции и, иногда, разрывом строки. Компилятор, как правило, игнорирует пробелы, но все же есть небольшие исключения.
В следующем примере все строки кода выполняют одно и то же:
1 2 3 4 5 6 7 8 |
std::cout << "Hello, world!"; std::cout << "Hello, world!"; std::cout << "Hello, world!"; std::cout << "Hello, world!"; |
Даже последний стейтмент с разрывом строки успешно скомпилируется.
Аналогично:
1 2 3 4 5 6 7 8 9 10 11 12 |
int add(int x, int y) { return x + y; } int add(int x, int y) { return x + y; } int add(int x, int y) { return x + y; } int add(int x, int y) { return x + y; } |
Исключением, где компилятор учитывает пробелы, является цитируемый текст, например: "Hello, world!"
.
"Hello, world!"
отличается от
"Hello, world!"
Разрыв/перевод строки не допускается в цитируемом тексте:
1 2 |
std::cout << "Hello, world!" << std::endl; // не допускается! |
Еще одним исключением, где компилятор обращает внимание на пробелы, являются однострочные комментарии: они занимают только одну строку. Перенос однострочного комментария на вторую строку вызовет ошибку компиляции, например:
1 2 |
std::cout << "Hello, world!" << std::endl; // это однострочный комментарий А это уже не комментарий |
Основные рекомендации
В отличие от других языков программирования, C++ не имеет каких-либо ограничений в форматировании кода со стороны программистов. Основное правило заключается в том, чтобы использовать только те способы, которые максимально улучшают читабельность и логичность кода.
Вот 6 основных рекомендаций:
Рекомендация №1: Вместо символа табуляции (клавиша Tab) используйте 4 пробела. В некоторых IDE по умолчанию используются три пробела в качестве одного символа табуляции — это тоже нормально (количество пробелов можно легко настроить в соответствующих пунктах меню вашей IDE).
Причиной использования пробелов вместо символов табуляции является то, что если вы откроете свой код в другом редакторе, то он сохранит правильные отступы, в отличие от использования символов табуляции.
Рекомендация №2: Открытие и закрытие фигурных скобок функции должно находиться на одном уровне на отдельных строках:
1 2 3 |
int main() { } |
Хотя есть еще и следующий вариант (вы также можете его использовать):
1 2 3 |
int main() { //... } |
Первый вариант хорош тем, что в случае возникновения ошибки несоответствия скобок, найти те самые проблемные скобки визуально будет проще.
Рекомендация №3: Каждый стейтмент функции должен быть с соответствующим отступом (клавиша Tab или 4 пробела):
1 2 3 4 5 |
int main() { std::cout << "Hello world!" << std::endl; // один Tab (4 пробела) std::cout << "Nice to meet you." << std::endl; // один Tab (4 пробела) } |
Рекомендация №4: Строки не должны быть слишком длинными. 72, 78 или 80 символов — это оптимальный максимум строки. Если она будет длиннее, то её следует разбить на несколько отдельных строк:
1 2 3 4 5 6 7 8 9 10 |
int main() { std::cout << "This is a really, really, really, really, really, really, really, " << "really long line" << std::endl; // один дополнительный отступ для строки-продолжения std::cout << "This is another really, really, really, really, really, really, really, " << "really long line" << std::endl; // отступ + выравнивание с учетом главной строки std::cout << "This one is short" << std::endl; } |
Рекомендация №5: Если длинная строка разбита на части с помощью определенного оператора (например, << или +), то этот оператор должен находиться в конце этой же строки, а не в начале следующей (так читабельнее).
Правильно:
1 2 |
std::cout << "This is a really, really, really, really, really, really, really, " << "really long line" << std::endl; |
Неправильно:
1 2 |
std::cout << "This is a really, really, really, really, really, really, really, " << "really long line" << std::endl; |
Рекомендация №6: Используйте пробелы и пропуски строк между стейтментами для улучшения читабельности вашего кода.
Менее читабельно:
1 2 3 4 |
nCost = 57; nPricePerItem = 24; nValue = 5; nNumberOfItems = 17; |
Более читабельно:
1 2 3 4 |
nCost = 57; nPricePerItem = 24; nValue = 5; nNumberOfItems = 17; |
Менее читабельно:
1 2 3 |
std::cout << "Hello world!" << std::endl; // cout и endl находятся в библиотеке iostream std::cout << "It is very nice to meet you!" << std::endl; // эти комментарии ухудшают читабельность кода std::cout << "Yeah!" << std::endl; // особенно, когда строки разной длины |
Более читабельно:
1 2 3 |
std::cout << "Hello world!" << std::endl; // cout и endl находятся в библиотеке iostream std::cout << "It is very nice to meet you!" << std::endl; // эти комментарии более читабельны std::cout << "Yeah!" << std::endl; // не так ли? |
Менее читабельно:
1 2 3 4 5 6 |
// cout и endl находятся в библиотеке iostream std::cout << "Hello world!" << std::endl; // эти комментарии ухудшают читабельность кода std::cout << "It is very nice to meet you!" << std::endl; // особенно, когда они в одной куче std::cout << "Yeah!" << std::endl; |
Более читабельно:
1 2 3 4 5 6 7 8 |
// cout и endl находятся в библиотеке iostream std::cout << "Hello world!" << std::endl; // эти комментарии читать легче std::cout << "It is very nice to meet you!" << std::endl; // ведь они разделены дополнительными строками std::cout << "Yeah!" << std::endl; |
Язык C++ позволяет выбрать вам тот стиль форматирования вашего кода, в котором вам будет наиболее комфортно работать.
Юрий, когда я напишу игру своей мечты, то пришлю вам её) Спасибо за труд
Пожалуйста) Буду ждать тогда вашу игру)
Дождались?
Как это всегда бывает…
Я, конечно, не далеко не профи в программировании, мягко говоря, но логично предположить, что спор о скобочках решается просто — у нормальной конторы наверняка существует определенный стандарт по оформлению кода, проекта, да даже рабочего стола. Думаю скобочки (и прочее, ну вы поняли) лучше писать там, где их пишут все в вашем микроклимате. "Часть корабля, часть команды", так сказать )))
Учить использовать пробелы вместо табуляции это признак дурного тона и извращение.
Мифические плюсы основанные на том что не все редакторы корректно обрабатывают табуляции — это прошлый век и проблемы сортирных редакторов. В цивилизованном мире белых людей в 99,9% случаев все в полном порядке с этим во всех нормальных редакторах и IDE
Итого: пробелы = плохо, табуляция = хорошо.
Очень часто разработчики пользуются текстовыми редакторами, например Sublime (не реклама), для того чтобы быстро открыть один или несколько файлов и посмотреть интересующий фрагмент кода, вместо того, чтобы ждать запуска тяжеловесной IDE с подгрузкой кода проекта на несколько гигабайт. Кроме того, фрагменты кода иногда копируются и вставляются, например, в презентацию. И когда в коде используются одновременно и табы и пробелы, то выглядит это настолько страшно, что быстро понять какие строки находятся внутри блока, а какие — уже за его пределами, просто невозможно. Хотя бы уже по этим причинам "Учить использовать пробелы вместо табуляции" — это НЕ признак дурного тона и извращение, а правильное понимание сути проблем.
Не знаю как сейчас, но 5 лет назад на Github была проблема с табуляцией, что приводило к проблемам при ревью кода, уже тогда перешел на пробелы. Так же во всех компании в которых работал, использовали пробелы, а не табы. Возможно, это только в сообществе разработчиков на JavaScript. В любом случае, во всех компаниях, где работают больше 1 человека формируется какой-то стайл гайд и ориентироваться стоит именно на него
Использование пробелов заместо табуляции, на мой взгляд, является извратом. Мало когда написанный в команде или же для себя код будет открываться в другом редакторе.
Спасибо Юрий! Всё понятно и просто. За ваши труды вам воздастся!
Пожалуйста 🙂
"Мало когда будет открываться"=="Будет открываться". Поэтому лучше использовать только пробелы. Но это, конечно, пожалуй, наименее значимый фактор качества форматирования. Грамотное построение кода, грамотное комментирование, расстановка отступов и скобок дают наибольший вклад в читабельность.
Главное тут то, что подход с позиции "больше никто это читать не будет" изначально дефектен: наступит день и будут. А ещё более вероятное событие — что однажды понадобится самому пересматривать и вспоминать когда-то написанный и давно забытый код. И с привычкой писать как-попало и то и другое будет выглядеть печально.
А реально неудобства с табуляцией бывают в тех случаях, когда символы табуляции смешиваются с пробелами. Так или иначе, но на практике такое встречается и вот это как раз уже больше тянет на изврат.
PS: Поясню, пожауй, некоторые моменты по теме, которые тут изложены достаточно декларативно:
Форматирование кода — суть есть вёрстка (в типографском/издательском смысле этого слова) и потому всё в этом процессе поистекает из методов компоновки текста, применяемых в издательском деле. А именно: отступы, абзацы, колонки. И применять их следует сообразно их смыслу.
В этом ключе поясню всё по пунктам статьи:
2. Не смотря на частое использование второго варианта, где открывающая скобка ставится в той-же строке, что и выражение (предпочту использовать именно перевод слова "стейтмент"), к которому относится этот составной оператор (то, что в скобках), всё-таки такой вариант имеет явный недостаток: если с функциями всё более однозначно, то после условных операторов и в циклах используются не только составные операторы, но и одиночные, которые не требуется заключать в скобки. И тут читабельность кода падает значительно. И именно поэтому лучше открывающую скобку всё-таки переносить на новую строку и ставить на одном уровне с закрывающей.
3. Каждый следующий уровень вложенности операторов/выражений должен идти с [равным] отступом относительно предыдущего уровня. Во всех конструкциях с вложенностью, не только в функциях (если вдруг это не очевидно).
4. Строка — это предложение. Короткое предложение лучще слишком длинного, но если это оправдано — то можно. Если длинная строка — это просто значение строки, которое мало значимо для понимания програмной логики, то можно и длинную написать.
6. Первое — это колонки. Колонки, конечно читабельней, но если между ними слишком большие промежутки, то лучше поблочно эти промежутки сократить.
Второе — это параграфы и абзацы. В начале параграфа (крупного смыслового блока) ставится заголовок, ёмко отражающий его содержание. В коде — это комментарий, однострочный как правило. Меньшие смысловые блоки — абзацы — , которые обычно не требуют отдельного заглавия, отделяются просто вертикальным отступом, т.е. пустой строкой. Тут ещё небольшая практическая ремарка: не надо понимать эти "параграфы" и "абзацы" формально и жёстко: если короткий комментарий отностися к целому небольшому блоку кода, то иногда читабельней поместить его перед этим блоком а не колонкой слева.
PPS:
И самое главное: называйте идентификаторы по их смыслу, отвечая на вопрос: "что делает эта функция" и "что содержит эта переменная/константа". Это не только просто "улучшает читаемость", но и помогает в отладке. Если форматирование кода — это скорее к поиску опечаток и забытых скобок, т.е. тому, о чём подскажет добрый компилятор (но надо помнить, что не во всех языках он столь любезен), то осмысленное именование — это уже к отладке логики. Гораздо проще понять, верно-ли написана функция, выражение, и т.д., когда ясно, что она/оно должно делать или содержать. Потому ошибка — это и есть ситуация, когда действительное не совпадает с должным.
По вашему комментарию к пункту 2 есть также рекомендация, которую советую придерживаться новичкам особенно. ВСЕГДА ставить фигурные скобки, даже если оператор один. Во-первых читаемость лучше. Во-вторых, в рабочих проектах даже встречал, когда был один оператор, а потом потребовалось что-то добавить в обработку условия, про скобки благополучно не вспомнили, компилятор ошибки никакой не выдаёт. А в работу программу запустили через месяц и очень долго потом искали, а почему же работает не так, как надо. На эту же тему, кстати, почему обязательно надо использовать систему управления версиями, когда пишешь код.
Фигурные скобки — это т.н. "составной оператор". Соответственно если они ставятся, значит предполагается, что в них будет несколько операторов. И это надо понимать, а не просто бездумно писать какие-то скобочки и другие значки. Это в смысле новичков. И новичкам я бы посоветовал всегда думать над тем "какой смысл и назначение в языке у тех букв, знаков, операторов, конструкций и т.д., которые ты пишешь?", "соответствует-ли то, что ты используешь тому, что ты хочешь выразить?".
А по принципу "а если потом потребуется" можно наворотить такого, что при самом прекрасном форматировании кода никто просто не поймёт, за чем там всё это понаписано. Если человек не осознаёт, что и для чего он пишет, то ни какие ухищрения не помогут избежать кривого кода. Скорее наоборот, имхо. Ну и от того, чтобы банально где-то ступить, что-то забыть — от этого, имхо, тоже никто не застрахован. Но если код написан осмысленно (ключевое слово — осмысленно) и осмысленно прокомментирован, то не будет проблем с поиском явных ошибок.
ps: Комментарии в коде — это как избыточное кодирование в передаче данных. Этакая контрольная сумма. Если смысл, заявленный в комментарии не совпадает со смыслом, написанным в коде — значит где-то ошибка. То же самое и со смыслами в идентификаторах переменных, функций и т.д.
Поэтому рекомендация, которой я советую придерживаться особенно всем, — всегда и везде ставьте смысл.
Автор в этой статье начал молча использовать using namespace std, не предупредив, не объяснив что это и для чего, и в дальнейшем без объяснения причин и как это работает продолжает использовать.
Не красиво, совсем.
Исправил.
Смысла в этом исправлении особого не вижу. Пролистав два урока дальше — я вижу тоже самое, молчаливый переход на using namespace std без объяснения причин, даже не обращая внимание на это.
Я так бросил уроков 10, потому что неожиданно в тексте появляется функции, которые раьше не использовались, и что это, и для чего они — не объясняется.
Читайте уроки №24 и №54. В них всё детально рассказывается.
простите, всё что вы обьясняете, относится только к консольным приложениям?
В этих уроках объясняются фундаментальные основы и понятия в программировании не только на языке С++, но вообще в программировании (основы одинаковы в большинстве всех языков программирования). В качестве примеров да, используются только консольные приложения.
спасибо,я не знал!
Терпень не могу такой стиль:
Он мне кажется каким-то неаккуратным.
Мне куда больше нравится такой способ:
Для меня он даже выглядит солиднее.
Может быть у меня такое мнение, только после друго языка, в котором хорошим тоном считается именно такой способ (хотя с переносом скобки тоже допускается, хоть и редко используется).
Указанная здесь причина — легче искать несоответствие скобок — их в обоих стилях легко искать. Хотя в любом случае некрасиво писать код в котором десяток вложеных скобок.
Помимо того в способе с переносом скобок получается значительно больше кода, осбенно когда есть много мелких функций.
А работать с большим файлом сложнее. Конечно, код все равно разбивается на много файлов, но все же…
Хотя это все конечно дело вкуса)
В статье описываются рекомендации к базовому форматированию. А каждый уже решает сам, чему ему придерживаться и как писать код. Как уже было сказано, о вкусах не спорят 🙂
https://github.com/Microsoft/WinObjC/wiki/Coding-Standards
Майкрасофт с Димой согласен
По вашей ссылке , если внимательно почитать ,есть еще одна ссылка на https://en.wikipedia.org/wiki/Indentation_style#Variant:_Stroustrup. И вот там очень подробно описываются различные стили. Многие из них (Allman, GNU, Whitesmiths, Horstmann) придерживаются именно такого стиля как в этой статье. Мне это тоже кажется удобнее. Да и при программировании микроконтроллеров используется этот же стиль. Для примера http://narodstream.ru/avr-urok-3-pishem-kod-na-si-zazhigaem-svetodi/
только у МК обычно язык С, а не С++.
Дело вкуса — это подход ненаучный. Вкусы у всех разные, а нам нужен общий метод, дающий лучшие результаты. И в данном случае лучшим является тот вариант, который позволяет легче визуально отслеживать начала и конецы составных операторов.
И мои аргументы за написание
if (условие)
{
оператор1;
оператор2;
...
}
и
if (условие)
только_один_оператор;
и всех остальных аналогичных конструкций такой:
— Просматривать только начало строк проще, чем искать наличие нужного символа в конце строки, и тем более — то в конце, то в начале. Кроме того, условие может быть достаточно сложным, и иногда его приходится даже разбивать на несколько строк (да, не лучший вариант, но иногда оправдано, например чтобы аккуратно откомментить по частям).
— Проще сверять соответствие пар скобок, когда они на одном уровне по вертикали (естественно весь код внутри должен быть с отступом и не попадать на линию между ними).
— Наличие "фигурных скобок", т.е. обозначения составного оператора дополнительно указывает на то, что там должно быть именно несколько операторов, а не один. (Лишний признак для проверки правильности кода.)
НО:
1)
if (условие) {
операторы;
...
}
тоже годный вариант. Главное, чтобы остальные правила выполнялись, иначе что так, что этак — всё будет плохо. (Это второй по важности фактор.)
2) Если человек писал код, не осознавая доподлинно, что делают все эти буквы и значки — разобраться в нём не поможет ни какое форматирование. (И это самый главный фактор, который определяет 70-80% читаемости кода, а все эти отступы, где скобочку поставить и прочее,как говорится, — догадайтесь сами 🙂 )
* Всё это выведено из опыта разбрирания больших объёмов чужого кода, в некоторых случаях написанного явно в состоянии полной невменяемости.