Стиль программирования на C/C++Источник: CODENET Бодриков Сергей Валентинович
Наверное сколько людей, столько и стилей написания исходников. Я много читал на эту тему, но, как и следовало ожидать, ничего универсального не нашел. Стиль, на мой взгляд, ключ к красивым, хорошо отлаженным программам. Ведь если программист строго придерживается какого-либо стиля, значит и "видит" свою программу лучше и ошибок делает меньше, и сопровождение этой программы не превращается в кошмар. Есть мнение, что не нужно увлекаться выработкой собственного стиля, что на это уходит много времени. Но, господа, если не заниматься этим с самого начала, то постепенно разгильдяйское отношение к своему исходному тексту войдет в привычку, избавиться от которой впоследствии будет очень сложно. Язык
Возможно этот пункт покажется странным, но я решил его вставить так как он касается именно использования английского языка в именовании идентификаторов. Мне часто попадаются фрагменты кода приблизительно такого вида: 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< nCount; n++) { printf( "%d\n", n); } Хотя и в этом примере если использовать вместо n, что-нибудь более осмысленное, то вы потом сами себе (или тот кто будет пользоваться вашим исходником) скажете спасибо. Например: for( int nLineNo= 0; nLineNo< nLineCount; nLineNo++) { printf( "%d\n", 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 лет вырабатывали свой стиль и теперь нужно переходить на общекорпоративный - вам нужно будет еще очень долго плевать на свои пальцы и терпеть упреки начальника. |