Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

C/C++ - стиль программирования

Автор: Бодриков Сергей Валентинович
http://bodrikoff.nakhodka.ru/
То что вы здесь прочитаете касается пока только именования идентификаторов, впoследствии надеюсь развить эту тему. Если у кого-то имеются свои доводы и суждения на счет стиля, буду очень благодарен за высланные комментарии.

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

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

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

Язык


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

Мне часто попадаются фрагменты кода приблизительно такого вида:

  void main( void)
  {
    int stipendiya, eda, na_devchonok;
    ...
    na_devchonok= stipendiya- eda;
    printf( "%d", na_devchonok);
  }
  

Eсли на этот исходник посмотрит какой-нибудь Билл Гейтс (который хочет взять вас на работу), то он ничего не поймет так как русского языка не знает. Кстати, мне попадались исходники на немецком и итальянском. Во вторых - английский язык достаточно емкий, сравните на сколько стало короче:

  void main( void)
  {
    int pay, food, for_girls;
    ...
    for_girls= pay- food;
    printf( "%d", for_girls);
  }
  

Вопреки распространенному мнению, для того что бы использовать англоязычные идентификаторы, английского языка знать не нужно (хотя для программиста очень желательно), для этого достаточно лексикона из 400-500 наиболее употребимых слов.

Размер

Допустим у вас есть переменная или функция означающая "Убрать из строки все пробелы", программист, именующий идентификаторы в стиле операционных систем Unix записал бы ее название так "strsptr" или даже "strst". То есть все было бы максимально кратко и в нижнем регистре. Да, я тоже читал про то что когда-то терминалы принимали данные со скоростью 10 символов в секунду и хитрые программеры специально записывали все как можно короче. Вполне возможно что эта привычка осталась еще и потому, что некоторые программисты писали свои первые программы на Бейсике, в старых версиях которого для имени переменной разрешалось использовать только один или два символа.

При таком подходе у исходных текстов программы имеется один большой недостаток. Если в тексте нет комментариев (а это скорее правило чем исключение), то через полгода просматривая исходник вы будете долго вспоминать, чего бы это значило - "if( !strst( mystr)) printf...". На мой взгляд, не нужно лениться набивать "лишние" буквы. Краткое название идентификатора уместно использовать только для именования индексных переменных в теле цикла или в качестве локальной переменной небольшой процедуры. Например:

  for( int n= 0; n

Хотя и в этом примере если использовать вместо n, что-нибудь более осмысленное, то вы потом сами себе (или тот кто будет пользоваться вашим исходником) скажете спасибо. Например:

  for( int nLineNo= 0; nLineNo

Можно именовать идентификаторы и по другому. Допустим у вас есть все та же функция "Убрать из строки все пробелы", название может выглядеть примерно так "StrRemoveSpaces". В связи с таким подходом программа становится самодокументируемой и в этом случае можно уже действительно обойтись без комментариев. Хотя увлекаться самодокументированием тоже не следует, иначе если эта функция называется "RemoveAllSpacesFromThisString", то читать ее уже тоже затруднительно. Кстати, вот вам некоторое из WinAPI: FindClosePrinterChangeNotification, SystemTimeToTzSpecificLocalTime, INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY - песня, а не константа.

Префиксы

Допустим у вас есть переменная имеющая тип DWORD, переменная в этом случае записывается например, так dwMyVar, то есть название переменной начинается с некоторых (или всех) букв взятых из названия ее типа. Так же иногда принято именовать глобальные переменные с префиксом g_... (g_dwMyVar). Переменные-члены класса в MFC начинаются с m_... (m_dwMyVar), а дальний указатель на строку которая заканчивается нуль-терминатором (LPSTR в WinAPI) так - lpsz... (lpszMyVar - Long Pointer String Zero).

Имеется великое множество таблиц префиксов переменных. Я сам когда-то составил свою, и успешно ею пользуюсь. Хотя без тупиков в этом деле не обошлось, это касается составных типов данных. Я например сначала для каждого класса (это было с Delphi VCL) придумал свой префикс, таблица получилась большой, но я не испугался трудностей. Постепенно эта таблица разрослась до угрожающих размеров и, уже перейдя на Visual C++, я решил что объекты будут иметь префикс "o" (CMyObj -> oMyObj), а структуры вообще его не иметь (SYSTEMTIME -> SystemTime), хотя это и не является идеальным решением.

Некоторое время давал префиксы еще и функциям, т.к. функция тоже возвращает значение определенного типа (dwGetValue()), но скоро от этого отказался, решив, что такой стиль уж слишком сильно отличается от остальных, хотя это и удобно и красиво.

Использование сокращений

Не стоит увлекаться использованием сокращений и аббревиатур в именовании идентификаторов, исключением могут быть только "общепринятые" сокращения, например: str -> string, src -> source, tbl -> table и т.д., так как если написать вместо server - srv, может или получиться путаница (возможно это означает - service), или другой программист этого сокращения вообще не поймет.

Использование разделителей

Некоторые программисты используют в качестве разделителей слов в идентификаторах символ подчерка "_", имя нашей функции получилось бы таким - "str_remove_spaces". Некоторые вообще не используют разделителей ("strremovespaces" - читать затруднительно). Наиболее упорные используют такой стиль именования - "Str_Remove_Spaces". Остальные используют в качестве разделителей заглавные буквы - "strRemoveSpaces" или "StrRemoveSpaces". Я придерживаюсь последнего варианта, т.к. "экономится" одна буква на слово и читать при этом вполне удобно.

Именование в составе класса

Допустим вы написали класс с именем "CFile", выполняющий некоторые операции с файлом. Избыточно называть методы этого класса так: CFile::FileOpen() или CFile::FileClose(), ведь и так понятно, что класс работает с файлом. Tак и короче и логичней: CFile::Open(), CFile::Close().

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

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
62K
08 июня 2010 года
Drizzt_DoUrden
0 / / 08.06.2010
Мне нравитсяМне не нравится
8 июня 2010, 01:32:52
Помню как тоже долго думал, какой лучше писать префикс для int переменных - i или n. Сейчас смеюсь, т.к. полностью отказался от использования венгерской нотации. Она нелогична, запутывает читающего код и загромаждает код бесполезной инфой. В англ. языке логично написать idString, а не sId (т.е. String Id). Смысл она ВОЗМОЖНО имеет для ассемблера, где тип только один - байт или набор байт. Так же нет смысла использовать префиксы для классов (типа CMyClass) - всё тоже самое + причина, по которой используют в библиотеках эти префиксы (типа "C" в Microsoft или "Q" в Qt) - освободить человеческие имена классов для пользователя библиотеки. Т.е. я могу сделать так: class LineEdit : public QLineEdit. А вообще это всё выводы, которые я сделал для себя, но одно понял точно - почти не важно какой стиль использовать. Важно одно - везде (в одном проекте по крайней мере) использовать один и тот же стиль. Ну и пара мелочей типа дефайны писать БОЛЬШИМИ_БУКВАМИ, не использовать подчеркивания в начале имен, т.к. они зарезервированы по стандарту ну и т.д. Вообще наверное не стоит себе голову ломать, таких вопросов куча по стилю (напр. таб или 4 пробела использовать, или все 8) - стоит взять за основу готовый стиль, который нравится. Я посмотрел, как пишут в исходниках Qt, и решил такого стиля придерживаться. Так же стоит упомянуть про code beautifier'ы, типа Artistic Style для линухи - ими можно существующий код привести к любому стилю (по большему счету).
2.
56K
19 декабря 2009 года
marmar
0 / / 19.12.2009
+4 / -0
Мне нравитсяМне не нравится
5 мая 2010, 23:11:50
Izvinite ja konechno ne pro n c++ no pisat void main ne po standartu
3.
Аноним
Мне нравитсяМне не нравится
28 мая 2006, 14:45:44
Не знаю, я програмировать учился на паскале, и существующие отступы и тп в визуал си мне подходят, а если надо сделать програму понятней-никакой идентификатор не заменит краткого коментария...
4.
Аноним
Мне нравитсяМне не нравится
30 ноября 2005, 22:21:16
А еще не плохо почитать Элджера.
Цитата: "Несколько слов о стиле. Вот эти несколько слов: стиль
кодирования меня вообще не интересует. Я достаточно краток?" :)

В любом случае современное программирование чаще всего процесс
коллективный.=> Соглашения о кодировании чаще всего навязываются руководителем группы.
5.
Аноним
+1 / -0
Мне нравитсяМне не нравится
22 октября 2005, 19:10:50
Совет: почитайте CodingStyle из Linux kernel, там всё прекрасно объяснено.
MyVar - только если вы печатаете 2-мя пальцами, для быстрой печати это очень раздражает - извращаться с шифтами.
dxMyVar это вообще какой-то дебилизм. Компилятор прекрасно проверяет типы.
MySuperPuperComplicatedFunction - из той-же оперы. Дебилизм.
6.
Аноним
Мне нравитсяМне не нравится
1 сентября 2005, 12:12:19
Да, вообще над этим стоит задуматься. Я, как начинающий программист, еще только начинаю формировать свой стиль и надо что-то с этим делать ;)
7.
Аноним
Мне нравитсяМне не нравится
6 мая 2005, 18:25:12
Сколько читателей, столько и мнений, хотя некоторые вещи сомнительны с точки зрения реальных программ, а не учебных примеров

О префиксах, еще надо хорошенько подумать, насколько они нужны в современных языках, да в старом добром ассемблере, необходимость префиксов диктовалась тем, что любое имя - это именнованная ячейка памяти, с которой начинается переменная, а в современном виде - есть различные дописыватели, wizzard-ды для описания типа, поэтому указание типа не строль важно, особенно если название выбрано верно (говорящее). Кроме того существуют различные "i", говорящие сами за себя
сравните
Код:
for (int i=0; i< NumLines; i++)

{...}

с текстом а статье, а если это "i" не в простом цикле а в сложных наборах условий
8.
Аноним
Мне нравитсяМне не нравится
5 мая 2005, 12:14:10
А как по мне то лучше всего использовать венгерскую нотификацию и от нее не отходить. Хотя знаю мноиге плюются ею, но реально сильно помогает в разборе своих и чужих програм.

Сколько искал какие-то более-менее толковые учебники по стилю программирования (именование переменных, форматирование, тонкости формирования структуры программы и т.д.), но ничего толкового не нашел.
Может кто знает книги вышеопределенной тематики?
9.
Аноним
Мне нравитсяМне не нравится
15 апреля 2005, 21:12:41
ИМХО, начинать вырабатывать свой стиль нужно уже после знакомства с основами программирования. Тем, кто пока не отличает конструктор класса от метода, особенно заморачиваться на этот счет не стоит. Хотя, конечно, неплохо бы с самого начала соблюдать правила отступов и расстановок скобок, т. к. это действительно очень сильно влияет на легкость визуального восприятия кода. А на остальное, вроде имен идентификаторов и расстановки пробелов, до поры до времени можно "забить". По поводу того, что разгильдяйское отношение войдет в привычку, не согласен. Хороший стиль постепенно придет с опытом.
Насчет использования русского языка в идентификаторах -это "болезнь" большинства начинающих кодеров. Сам когда-то делал то же самое. Проходит со временем. Помогает чтение чужих исходников, ну и, естественно, изучение английского. Только, на мой взгляд, лексикона из 400-500 слов явно недостаточно для того, чтобы научиться давать названия идентификаторам, не задумываясь.
А вообще, кому интересно, можно почитать "Практику программирования" Б. Кернигана и Р. Пайка. Написано очень и очень неплохо.

P.S.
Код:
for( int nLineNo= 0; nLineNo< nLineCount; nLineNo++)

{

   printf( "%d\n", nLineNo);

}

ИМХО, нет никакого смысла нагораживать черт знает что из простой локальной итерационной переменной, используемой только внутри данного цикла. Лучшему пониманию программы это никак не способствует.

P.P.S:
<blockquote><small>Цитата:<hr size=1>Кстати, вот вам некоторое из WinAPI: FindClosePrinterChangeNotification, ... [/quote]
А как вам это: ToolBarButtonClickEventHandler (оттуда же) ;-)
10.
Аноним
Мне нравитсяМне не нравится
21 февраля 2005, 20:36:31
class CFile это конечно, очень замечательно, но это "M$-way", и он далеко не самый лучший. Писать "lpsz" слишком длинно и неудобно, кроме того, это устаревшее наименование, потому что lp - это long pointer, и восходит к ключевым словам near и far, которые применялись в те времена, когда указатели (как и компьютеры, и API операционных систем M$ на них) ещё делились на 16-ти и 32-разрядные.

Вообще, подобные статьи не помогут даже начинающим программистам, т.к. им лучше почитать что-нибудь вроде Гради Буча или Б.Страуструпа и посмотреть, какую нотацию используют _корифеи_.

Например, class CFile должен называться "class Files", т.к. класс - это представление для МНОЖЕСТВА объектов, тогда получаем:

TextFiles letter,answer;

что тут непонятного?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог