Practical C Programming, 3rd Edition (2011)
Part III. Advanced Programming Concepts
Chapter 23. Programming Adages
Second thoughts are ever wiser.
—Euripides
General
§ Comment, comment, comment. Put a lot of comments in your program. They tell other programmers what you did. They also tell you what you did.
§ Use the “KISS” principle. (Keep It Simple, Stupid.) Clear and simple is better than complex and wonderful.
§ Avoid side effects. Use ++ and -- on lines by themselves.
§ Use the prefix version of ++ and -- (++x, --x) instead of the postfix version (x++, x--). This adage does nothing for you in C, but will serve you well when you move to C++.
§ Never put an assignment inside a conditional.
§ Never put an assignment inside any other statement.
§ Know the difference between = and ==. Using = for == is a very common mistake and is difficult to find.
§ Never do “nothing” silently.
§ /* Don't program like this */
§ for (index = 0; data[index] < key; ++index);
/* Did you see the semicolon at the end of the last line? */
Always put in a comment or statement.
for (index = 0; data[index] < key; ++index)
continue;
Design
§ When designing your program, keep in mind “The Law of Least Astonishment,” which states that your program should behave in a way that least astonishes the user.
§ Make the user interface as simple and consistent as possible.
§ Give the user as much help as you can.
§ Clearly identify all error messages with the word “error,” and try to give the user some idea of how to correct his problem.
Declarations
§ Put one variable declaration per line, and comment them.
§ Make variable-names long enough to be easily understood, but not so long that they are difficult to type in. Two or three words is usually enough.
§ Never use default declarations. If a function returns an integer, declare it as type int.
§ All parameters to a function should be declared and commented. Never use default declarations.
§ Always declare main as:
§ int main(void) /* Correct declaration */
int main(int argc, char *argv[]) /* Also correct */
Never declare main as:
void main() /* never program like this */
void main(int ac, char *av[]) /* never use names like this */
switch Statement
§ Always put a default case in a switch statement. Even if the case does nothing, put it in.
§ switch (expression) {
§ /* ... */
§ default:
§ /* do nothing */
}
§ Every case in a switch should end with a break or /* Fall through */ comment.
Preprocessor
§ Always put parentheses around each constant expression defined by a preprocessor #define directive.
#define BOX_SIZE (3*10) /* size of the box in pixels */
§ Use const declarations instead of #define wherever possible.
§ Put ( ) around each argument of a parameterized macro.
#define SQUARE(x) ((x) * (x))
§ Surround macros that contain complete statements with curly braces ({ }).
§ /* A fatal error has occurred. Tell user and abort */
#define DIE(msg) {printf(msg);exit(8);}
§ When using the #ifdef/#endif construct for conditional compilation, put the #define and #undef statements near the top of the program and comment them.
Style
§ A single block of code enclosed in {} should not span more than a couple of pages. Anything much bigger than that should probably be split up into several smaller, simpler procedures.
§ When your code starts to run into the right margin, you should split the procedure into several smaller, simpler procedures.
Compiling
§ Always create a Makefile so that others will know how to compile your program.
§ Turn on all the warning flags, then make your program warning free.
Final Note
Just when you think you’ve discovered all of the things that C can do to you—think again. There are still more surprises in store for you.
Question 23-1: Why does Example 23-1 think everything is two? (This inspired the last adage.) (Click here for the answer Section 23.9
Example 23-1. not2/not2.c
#include <stdio.h>
int main()
{
char line[80];
int number;
printf("Enter a number: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &number);
if (number =! 2)
printf("Number is not two\n");
else
printf("Number is two\n");
return (0);
}
Answer
Answer 23-1: The statement (number =! 2) is not a relational equation, but an assignment statement. It is equivalent to:
number = (!2);
Because 2 is nonzero, !2 is zero.
The programmer accidentally reversed the not equals, !=, so it became =!. The statement should read:
if (number != 2)