General good programming practices
- Do modular programming.
- If you know you will have an efficiency issue, spend lots of time
investigating techniques and algorithms that address that, then
build your code to accommodate any of the better algorithms.
As opposed to nailing down the first solution you find, and building the whole code around that one solution. - “length of a variable name should be inversely proportional to
its scope”
If you must have a global, mark it so, and give it an explanatory name.
If you must have a variable shared from another file, give it a name that says this.
Often a long name for a variable used on 2 lines is just overkill. - Compile with the strictest compiler warnings available, strive to make no warnings appear.
Special to C
initialization
In C, uninitialized variables contain trash. Nothing stops you from using this trash. This gives rise to a class of problems that do not occur in Java.
Initialize variables in their declarations.
Initialize pointers to NULL
if nothing else (dereferencing
NULL
always segfaults, whereas dereferencing
unfortunately-chosen trash may do something weird and hard to track down.)
allocation/deallocation
Be systematic. The simplest system is, in one code blockmyvar = (type *)malloc( MYVARSIZE ); if( myvar != NULL ) { do_something( myvar ); free( myvar ); }It is best that only one entity in your program is responsible for a given allocation/deallocation pair.
structures
A structure should represent a conceptual entity; members of the structure should be things that are intrinsic to that entity.Beware the structure that’s just a grab-bag for stuff you might need sometime, or a convenient way to pass variables.
scope
Declare functions used only in current file asstatic
.Otherwise, namespace pollution results. (Appropriate use of global: An item for which there is exactly one instance for the run of the program for all conceivable versions of the program for all time. That is, almost never.)
brackets and nested if
Brackets around individual statements are optional, except in the case of nested if statements.constness
Declare all pointer and array function argumentsconst
unless you mean for the function to change their associated data.
headers
Make use of header files to prototype all functions shared by multiple files.
Each header should include precisely the other headers that are required to describe its contents. That is, an otherwise empty .c file that includes just the one header, should compile.
One header per .c file is a good rule of thumb. (Finding an appropriate division is a bit of a challenge—Don’t cram everything into one header !!!)
Don’t put stuff that will only be used by one .c file in a header. Leave it in the .c file.
proper use of static
variables
Wrong: mark a variable static as an easy way to initialize it to 0
Right: mark a variable static when its value should persist through the run of the program
preprocessor
Proper uses:-
#include
s - cutting out code (especially, header include guards)
- very simple macros: max, min
Rather than preprocessor symbols. use enum
‘s for
constants