There are several aspects that constitute a coding style. By understanding my coding style, which I have obviously used in all examples in this book, you will find it easier to follow my code.
Indentation
Looking at the source code attached to this book, you will notice that all closed braces that end block statements are indented, as shown in Listing .
1. void dar_list(Dar *stk) {
2. if (stk == NULL) {
3. printf("Nothing to list\n");
4. }
5. while (stk != NULL) {
6. printf("%p %zu %zu\n", stk, stk->size, stk->n);
7. stk = stk->down;
8. }
9. }
Listing 1-1.
The Authors Coding Style
The open braces in lines 1, 2, and 5 are appended to the previous line, while the closed braces in lines 4, 8, and 9 are indented. This style must be unusual because Eclipse and other development environments do not foresee it, while the two widely used styles shown in Listings are fully supported.
1. void dar_list(Dar *stk)
2. {
3. if (stk == NULL)
4. {
5. printf("Nothing to list\n");
6. }
7. while (stk != NULL)
8. {
9. printf("%p %zu %zu\n", stk, stk->size, stk->n);
10. stk = stk->down;
11. }
12. }
Listing 1-2.
Spread-Out Coding Style
The spread-out style of Listing . Obviously, if you need to achieve targets based on number of written lines of code, you might like to adopt this style!
1. void dar_list(Dar *stk) {
2. if (stk == NULL) {
3. printf("Nothing to list\n");
4. }
5. while (stk != NULL) {
6. printf("%p %zu %zu\n", stk, stk->size, stk->n);
7. stk = stk->down;
8. }
9. }
Listing 1-3.
Compact Not-Indented Coding Style
The style shown in Listing is probably the most widely used. The K&R uses it (with the exception of writing the open brace that begins a function body on a new line). It is good but, IMO, it has two problems: one conceptual and one practical.
The conceptual problem is that both braces delimiting a block statement belong to the block statement itself, which is indented. Then, why shouldnt the closing brace (and, in the case of the spread-out style, the opening brace too) be indented as well? For example, the closing brace in line 8 of Listing belongs to the block statement that begins in line 5 and contains the printf() and the assignment to stk . Then, it should be placed below the s of stk , rather than below the w of while .
The practical problem is that by not indenting the closed braces, you compromise the visual clarity of what I call the flagging effect. To illustrate what the flagging effect is, I took a screenshot of Listing by adding some shading.
Figure 1-1.
The flagging effect of my coding style
As you can see, everything that depends on the if -condition hangs from the if statement, and everything contained in the while -loop hangs from the while statement. This definitely makes reading the source code easier.
One more word concerning if s and else s.
I often see chains of if s and else s written like this:
if (condition 1) {
...
} else if (condition 2) {
...
} else {
...
}
This might be graphically pleasing and very compact, but it doesnt reflect the fact that the if s and the else s are not shown to be at the same level (which they are). Here is how I would write such a piece of code:
if (condition 1) {
...
}
else if (condition 2) {
...
}
else {
...
}
Naming and Other Conventions
This book includes several libraries of functions, each one consisting of a C file and the corresponding header file (e.g., string.c and string.h ). Each library is characterized by a small number of identifying letters that prefix the names of all exported macros, variables, and functions (e.g., str ). Macro constants (i.e., macros without parameters) are in capital letters (e.g., STR_LOG ), while with names of function-like macros only the prefix is capitalized (e.g., STR_crash() ). In names of exported variables and functions, the prefix is in lowercase (e.g., str_stack and str_list() ).
The names of most integer variables begin with a letter in the range i to n , especially if they are very short. This is a legacy of my initial experience with computers: the first computer language I learned (more than 40 years ago!) was FORTRAN, which automatically identified variables with names beginning with one of those letters to be of type INTEGER . I have to admit I am not perfectly consistent in following this rule when naming integer variables, but you will never find in my code a non-integer variable that starts with one of the integer letters. I simply couldnt!
If you look at modules containing several functions, you will perhaps notice that the functions are in alphabetical order, so that you always find them at once without having to search for them. To be able to refer to non-exported functions regardless of where they are within the module, I declare them at the beginning of the C file.
Also for convenience, I write a line of comment immediately before each function, with the name of the function on the far right:
//---------------------------------------------------------------- str_clean_up