Разделы сайта:
Статьи по C и C++Стандартная библиотека CКнигиЮмор
Оформление кода в C

Вы считаете, что пересматривать свой код через долгие годы Вам не придется? Вы ошибаетесь. Очень часто программисты используют повторно код, написанный давно, и при внесении в него изменений или отладке могут появиться неудобства. В этой саттье я рассмотрю способы оформления кода. Благодаря единому и грамотному оформлению, комментированию участков кода, а также при работе в команде благодаря использованию "корпоративного стиля" Вы не столкнетесь с сильными трудностями. Я - заядлый программист на C/C++ и поэтому все примеры будут на этом языке, но надеюсь, что моя статья будет пролезна более широкому кругу читатетелей.

В C любая обособленная часть кода должна выделяться фигурными скобками ( { и } ); в Pascal эту функцию выполняют операторы begin и end соответственно. Однако, их можно устанавливать по-разному. Вот четыре основных стиля их расстановки:

1TBS

Этот стиль был впервые использован Кернинганом и Ричи в своей книге "The C Progamming Language". Расшифровывается как One True Bracing Style (единственный правильный стиль расстановки скобок). Иногда его называют K&R (Kernighan and Ritchie) или kernel стилем. Вот пример кода (обычно используется восемь пробелов):

void f1(int i1) {
	if(i1==0) {
		 printf("Hello, World");
	 }
}
Плюс такого стиля - экономия вертикального пространства, однако иногда в скобках путаешься, или тяжело найти ее в конце длинной строки. Я сам использую этот стиль.

Стиль Алмена

Впервые был употреблен Эриком Алменом в исходных кодах утилит для ОС BSD, поэтому иногда его называют "стиль BSD". Достаточно нагляден, но требует использования дополнительной строки. Вот пример кода (обычно используется четыре пробела):

void f1(int i1) 
{
	if(i1==0) 
	{
		 printf("Hello, World");
	 }
}

Whitesmith

Использовался в IDE компилятора Whitesmith C. Более тесно улавливается связь кода и скобок. Вот пример кода (обычно используется четыре пробела):

void f1(int i1) 
	{
	if(i1==0) 
		{
		printf("Hello, World");
		}
	}

GNU

Как следует из названия, является традицией кода, распространяющегося по лицензии GNU GPL. По моему мнению, чрезвычайно неэкономный гибрид стилей Алмена и Whitesmith. Вот пример кода (обычно используется четыре пробела):

void f1(int i1) 
	{
		if(i1==0) 
		{
			printf("Hello, World");
		}
	}

В C скобки после операторов if, else, do, while и for ставить фигурные скобки необязательно. Тогда будет выполняться только следующий за оператором условия операнд. Давайте обратимся к коду:

if(i1!=0)
	printf("Hello World");
	printf("\n%i",i1);
На первый взгляд второй вызов printf будет выполняться при i1 не равном нулю. Но это не так. Кстати я делаю так:
if(i1!=0)	printf("Hello World");
	printf("\n%i",i1);

Также следует обратить вниание на обрамление кода пробелами. И это касается не только отступов в одном из вышеприведенных стилей, но и при описании выражений - cравните: a=b+c-d*f/g и a=b + c - d * f / g . В действительности, второй кусок более читаемый, однако некоторые программисты перебарщивают с пробелами. Мне кажется, чтио иногда следует воспользоваться нормами расстановки знаков препинания в печатном тексте и после и перед скобками пробелы опускать: a[index]++ и a [ index ] ++. По-моему, второй пример ужасен!

Особую роль играют правила наименования идентификаторов. Конечно же можно давать короткие имена переменным, функциям и классам (это, конечно же C++) и тсчательно комментировать их, однако это не всегда удобно в коде большого размера; сравните: названия идентификатора цикла (многим известный i) и название, отвечающий за текущее состояние (к ней как правило надо обращаться в разных кусках цикла). Следует также не переусердствовать, ведь некоторые программисты любят переводить смысл переменной на английский язык:

int CountOfSelectedStrings;
В таком случае надо прибегать к сокращениям.

Так как парсеры C-компиляторов чувствительны к регистру, то идентификатор пишут определенным стилем:

int lower_case_with_underscores;
int lowercasefunc();
int _CapitalizedFunc();
int lowerCaseFirstLetterWithMixedCase; 
int AllMixedCase; //По-моему, оптимальный вариант
int UPPERCASENOSEPARSTOR; //Честно говоря чрезвычайно неудобный стиль
int UPPERCASE_WITH_SEPARSTOR;
Можно также использовать это для различения идентификаторов, например макросов, квалификаторов, переменных и т. п., но главное - придерживаться общего стиля:
int draw_on_dcontexts(HDC hdc) {
 HDC Hdc, HDc, hDc, hDC, hdC, HdC;
 /*...*/
}

Теперь поговорим о префиксах. Конечно же многие знакомы с предложением программиста Microsoft Чарльза Симония (так называемая венгерская нотация, однако некоторые программисты окрестили ее трансильванской ересью). Суть ее заключалась в том, чтобы для каждого типа ввести единый префикс, и использовать его в дальнейшем. Например: int - n, char - ca. Конечноже удобно было бы знать, что переменная lpszString является строкой типа char*, однако я не сронник этой нотации, ведь многие программисты вводят свои типы и в зависимости от компилятора свойства переменных могут быть разными, например int, который теоретически вмещает число до INT_MAX не гарантирует точное соответствие 32 битам, и в тоже время никто не запрещает писать __int32 nValue; (BCB). А вот такое правило - для комнаты отдыха:
u - unsigned
n - int
l - long
i8 - short (если short занимает в памяти 8 бит)
i16 - int (если int занимает в памяти 16 бит)
i32 - __int32
i64 - __int64
imax - int с максимальным числом битов
b - bool
ie - enum
ch - char
wch - wchar_t
p - указатель
sz - массив символов
s - тип строки, определенный компилятором:
VC - CString
BCB - AnsiString, String
STL - string
etc.
e - double, float
g - double, float
le, lg - long double, long float

f - FILE*
h - дескрипторы

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

Автор и разработчик сайта - Кляус Сергей. Спасибо Форуму на Исходниках.RU за помощь в сборе материалов.
X