Programming language practically always leaves the programmer some freedom of styling that can increase (but also decrease) the aesthetic quality and readability of code, just like a writer has freedom in typesetting and choosing different words to express the same idea. As an example we can choose the variable names at our leisure without affecting how the program functions, expressions may include extra unnecessary brackets for better clarity or leave them out for shorter code and brevity, we can (and should) inserting comments, add proper indentation and whitespaces and so on. This gives rise to various programming styles; typically a programmer develops or adopts his own style over time, a "handwriting" of sort, but in a team compromises have to be found and everyone must temporarily conform to the same agreed style so as to preserve consistency and readability, just like artists have to follow the same visual style as part of larger collaborative work. Some project, e.g. Linux, have evolved quite good, tested and de facto standardized styles, so instead of inventing a custom style (which may not be as easy as it sounds) one may adopt some of the existing ones. While formatting and naming may not appear to be so important at first, it mustn't be underestimated as readability issues typically start to show later on as the project grows. On the other hand, however, it's not so difficult to reformat even a relatively large codebase in later stages (regular expressions and similar tools can help with this very well), it's definitely much easier than reworking the code's architecture.
There exist automatic code formatters, they are often called code beautifiers. But not everything can be automated, for example a program will hardly comment your code, or inserting empty spaces to separate logically related parts of a sequential code is also something that human like intelligence is needed for.
Here we propose a programming style and C code formatting you may use in your programs. { It's basically a style I personally adopted and fine-tuned over many years of my programming. ~drummyfish } Remember that nothing is set in stone (except that you mustn't use tabs), the most important rule of style is to maintain consistency within a single project and to actually think about why you're doing things the way you're doing them. Sticking to the standard presented here will gain you advantages such as increased readability for others already familiar with the same style and avoiding falls into traps of short-sighted decisions, e.g. regarding identifiers. Try to think from the point of view of a programmer who gets just your source code without any way to communicate with you, make his life as easy as possible. Also assume he's reading your code on a calculator. The LRS style/formatting rules follow:
if (a == b)
{
doSomething();
doSomething2();
}
else
{
doSomethingElse();
doSomethingElse2();
}
(a && b) || c
rather than a && b || c
.camelCase
for variables and functions (e.g. myVariable
). Global and big-scope variables should have a greatly descriptive, self-documenting name, even if long (e.g. getTicksSinceStart
, countryAreaKMSquared
), local/short-scope identifiers can be shorter (e.g. argBackup
within a single function), even just one letter (e.g. i
within a single loop).CapitalCamelCase
for data types (e.g. ImaginaryNumber
, GameState
etc.).ALL_CAPS_SNAKE_CASE
for macros and constants (e.g. PI
, MIN
, LOG_ERROR
, ...).S3L_
, SDL uses SDL
etc.). If you choose a prefix XYZ_
, prepend it to all global identifiers, it will prevent name clashes and help readability, e.g. when writing a renderer you will export identifiers such as XYZ_init
, XYZ_draw
, XYZ_setPixel
, XYZ_Model3D
etc. Do NOT use the prefix in local variables (inside functions, loops etc.)._
, e.g. _tmpPointerBackup
; with the above mentioned namespace prefix this will look e.g. like this: _XYZ_tmpPointerBackup
.int x = 10, y = 20;
instead of int x=10,y=20;
, write space between if
and its condition etc.getTimeMS
while a variable will be named timeMS
. Functions are to be formatted like this:void doSomethingCool(int a, int b, int c)
{
// ...
}
getCountryTimezone
and getCountryCapital
instead of getTimeZoneOfCountry
, getCapitalOfCountry
etc. This helps with code completion systems. It's not always exactly clear, you may also decide to go for countryGetTimezone
etc., just keep it consistent.switch (myVariable)
{
case 0:
doSomething();
break;
case 1:
doSomethingElse();
break;
case 2:
{
int a = x + y;
doSomethingCool(a);
break;
}
default:
break;
}
// or even (depending on how long the sections are)
switch (myVariable2)
{
case 0: doSomething1(); break;
case 1: doSomething2(); break;
case 2: doSomething3(); break;
case 3: doSomething4(); break;
default: break;
}
camel_case.ext
or nocase.ext
.int a = x;
char b = y;
double q;
doSomething(a);
c += 3 * a;
d -= b;
if (c < d)
a = b;
// player shoots
to code implementing player shooting etc.). Use doxygen style comments if you can, it costs nothing and allows auto documentation.#define
s._POSIX_C_SOURCE
, _XOPEN_SOURCE
etc.). You MAY use them, but always do so in a way that makes it easy to get rid of them -- for example do not use macros such as PATH_MAX
directly, always define your own macro, e.g. #define MYLIB_PATH_MAX PATH_MAX
and only use that -- this way you may easily switch to e.g. hardcoded limit if the macro isn't available on some system. Similarly with anything else: if your program is using a feature specific to a compiler, operating system, some extra third party standard and so on, always offer an easy way of disabling or replacing it (preprocessor is very good for this).Here is a short example applying the above shown style:
TODO (for now see LRS projects like Anarch, small3dlib, SAF etc.)
Powered by nothing. All content available under CC0 1.0 (public domain). Send comments and corrections to drummyfish at disroot dot org.