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 лет вырабатывали свой стиль и теперь нужно переходить на общекорпоративный - вам нужно будет еще очень долго плевать на свои пальцы и терпеть упреки начальника.
Оставить комментарий
Комментарии
Цитата: "Несколько слов о стиле. Вот эти несколько слов: стиль
кодирования меня вообще не интересует. Я достаточно краток?" :)
В любом случае современное программирование чаще всего процесс
коллективный.=> Соглашения о кодировании чаще всего навязываются руководителем группы.
MyVar - только если вы печатаете 2-мя пальцами, для быстрой печати это очень раздражает - извращаться с шифтами.
dxMyVar это вообще какой-то дебилизм. Компилятор прекрасно проверяет типы.
MySuperPuperComplicatedFunction - из той-же оперы. Дебилизм.
О префиксах, еще надо хорошенько подумать, насколько они нужны в современных языках, да в старом добром ассемблере, необходимость префиксов диктовалась тем, что любое имя - это именнованная ячейка памяти, с которой начинается переменная, а в современном виде - есть различные дописыватели, wizzard-ды для описания типа, поэтому указание типа не строль важно, особенно если название выбрано верно (говорящее). Кроме того существуют различные "i", говорящие сами за себя
сравните
{...}
с текстом а статье, а если это "i" не в простом цикле а в сложных наборах условий
Сколько искал какие-то более-менее толковые учебники по стилю программирования (именование переменных, форматирование, тонкости формирования структуры программы и т.д.), но ничего толкового не нашел.
Может кто знает книги вышеопределенной тематики?
Насчет использования русского языка в идентификаторах -это "болезнь" большинства начинающих кодеров. Сам когда-то делал то же самое. Проходит со временем. Помогает чтение чужих исходников, ну и, естественно, изучение английского. Только, на мой взгляд, лексикона из 400-500 слов явно недостаточно для того, чтобы научиться давать названия идентификаторам, не задумываясь.
А вообще, кому интересно, можно почитать "Практику программирования" Б. Кернигана и Р. Пайка. Написано очень и очень неплохо.
P.S.
{
printf( "%d\n", nLineNo);
}
ИМХО, нет никакого смысла нагораживать черт знает что из простой локальной итерационной переменной, используемой только внутри данного цикла. Лучшему пониманию программы это никак не способствует.
P.P.S:
<blockquote><small>Цитата:<hr size=1>Кстати, вот вам некоторое из WinAPI: FindClosePrinterChangeNotification, ... [/quote]
А как вам это: ToolBarButtonClickEventHandler (оттуда же) ;-)
Вообще, подобные статьи не помогут даже начинающим программистам, т.к. им лучше почитать что-нибудь вроде Гради Буча или Б.Страуструпа и посмотреть, какую нотацию используют _корифеи_.
Например, class CFile должен называться "class Files", т.к. класс - это представление для МНОЖЕСТВА объектов, тогда получаем:
TextFiles letter,answer;
что тут непонятного?