Programming Adages - Advanced Programming Concepts - Practical C Programming, 3rd Edition (2011)

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)