//strahinja.org | Профил Блог Програми Текстови

Стандард који користим приликом програмирања у програмском језику C

[верзија 1.0, 12. август 2021.]

Страхиња Радић

Овде ћу описати кодни стандард који користим у програмима које пишем у програмском језику C. До њега сам дошао поступно, током година, и он је инспирисан ГНУ-овим кодним стандардом и suckless стандардом, али се ипак разликује од њих.

У основним цртама се начин на који форматирам код у C-у може описати следећим параметрима програма indent:

-nbad -bap -bbb -bbo -nbc -bl -blf -bli0 -brs -cbi8 -cd40 -ncdw -nce -nlp -ci8
-cli0 -ncs -nbfda -nbfde -di0 -nfc1 -nfca -hnl -i8 -il0 -ip8 -l80 -lc80 -pal
-npcs -pi8 -nprs -psl -saf -sai -sar -saw -ts8 -ut

Програм clang-format је за нијансу бољи у изражавању моје идеје форматирања кода. Мој кодни стандард се у том програму може описати датотеком .clang-format.

Ипак, овде ћу дати и нешто детаљнији опис.

Увлачење редова и уравнање (-cd40, -ncs, -i8, -il0, -ts8, -ut, -pal, -psl)

За увлачење редова првенствено користим знак Tab (ASCII 0x09). Размаке користим једино када је потребно да се неки делови изворног кода уравнају по вертикали, на пример (-i8, -ts8, -ut):

	int some_var = 10;
	char a       = 'b';
⇥int some_var = 10;
⇥char a␣␣␣␣␣␣␣= 'b';

Иницијализаторске доделе уравнавам код знака једнакости, што се нажалост не може задати у програму indent. Код уношења изворног кода програма, користим додатак tabular.

	/*
	 *
	 */
⇥/*
⇥␣*
⇥␣*/

Коментаре у истом реду као и код (рецимо, код описивања променљивих у блоку декларација или код дефиниције struct-а) уравнавам по истој колони. За потребе задавања параметра програму indent, одлучио сам се да одаберем половину екрана, -cd40.

После cast-овања, не користим размак (-ncs):

char c = (char)v;

Ознаке почињу од почетка реда (-il0):

void
bad_func()
{
beginning:
	if (misbehave)
		goto beginning;
}

Показивачке типове у декларацијама уравнавам „слева“ (-pal):

char* message  = "Hello";
FileRecord* fr = NULL;

Да би ово функционисало у програму indent и за кориснички дефинисане типове (преко typedef), они се морају проследити преко параметра -T.

Називи функција се налазе у посебном реду (-psl), што омогућава правилно функционисање програма за издвајање тагова из изворног кода:

int
fact(int n)
{
	if (n <= 1)
		return 1;
	else
		return n * fact(n-1);
}

Прелом редова (-bbo, -l80, -lc80)

Редове форматирам тако да се могу комотно читати на стандардном текстуалном екрану, који је ширине 80 знакова (-l80). Ово се односи и на коментаре (-lc80).

Уколико се ред састоји од дугачког логичког израза, преламам га тако да је нови ред увучен и почиње логичким оператором (-bbo):

if ((statement == ST_MOV && *token)
	|| (statement == ST_NOP && !*token))

Блокови (-bl, -blf, -bli0, -brs, -cbi8, -ncdw)

Витичасте заграде после наредби контроле тока почињу у новом реду, и уравнате су вертикално са кључном речју if (-bl, -bli0):

if (!running)
{
	save_files();
	clean_up();
}

Витичасте заграде у дефиницијама функција се такође налазе у новом реду, и уравнате су са називом функције (-blf):

int
main()
{
	printf("Hello, world!\n");
	return 0;
}

Код struct-ова, витичаста заграда остаје у првом реду (-brs):

struct Point {
	int x;
	int y;
};

У switch блоковима, case блокови (које углавном не користим) почињу витичастом заградом која је увучена у односу на кључну реч case (-cbi8). Такође, case ознаке су уравнате са кључном речју switch (-cli0):

switch (day_of_week)
{
case MONDAY:
	{
		mondays++;
		log_monday();
	}
	break;
case TUESDAY:
	tuesdays++;
	break;
default:
	others++;
}

Код do-while петље, завршна витичаста заграда је у посебном реду (-ncdw):

do
{
	on_tick();
}
while (running);

слично код if-else конструкције (-nce):

if (success)
{
	save_file();
	print_ok();
}
else
{
	print_error();
	clean_up();
}

Напомене

У зависности од времена настанка, програми које сам писао могу у мањој или већој мери одступити од овог стандарда.