CPS 445 Programming Style Guide
It has been said that `programs must be written for people to read, and only
incidentally for machines to execute' (ref. H. Abelson and G. J. Sussman,
Structure and Interpretation of Computer Programs, MIT Press, preface to
the first edition). Therefore, as discussed in class, it is important to
follow some basic guidelines for writing source code. Follow the guidelines
below for all programming assignments. Note: We may evolve this set of
guidelines as the course progresses.
Remember, assignments provide you with an opportunity to show us that you care
enough to submit a professionally-prepared submission. Practice good
programming habits early and you will be rewarded with effective and efficient
programs. Following this guide will improve the readability, writeabiliy, and
maintainability of your programs and therefore reduce the likelihood of costly
errors which will save you time in debugging. A portion of your grade for all
work will be evaluated for style.
- Begin each source file with the following header filled-in appropriately.
/*******************************************************************************
/
/ filename: doenv.c
/
/ description: Implements the UNIX env utility.
/
/ author: Linus Lowgator
/ login id: cps445-n1.xx
/
/ class: CPS 445
/ instructor: Perugini
/ assignment: Homework #1
/
/ assigned: January 18, 2006
/ due: January 25, 2006
/
/******************************************************************************/
Do not allow any line of code to exceed 80 characters in length. Most
text editors have an option to give you column position.
Find an
appropriate place to break long program statements to continue them on the
following line. Break long character strings using string concatenation.
Indent all code within a block.
Do not use tabs anywhere in your code. For each level of
indentation, use three
spaces. Tabs cause different amounts of horizontal spacing on different
systems. By using spaces (and a fixed-width font), you guarantee your code
will be properly indented for every system, editor, and printout.
Align corresponding opening and closing braces, begin or
ends, or any other program unit delimiters. My preference for curly
braces { } (or similar delimiters)
is to always place the opening brace on the same line as
the block it opens. This makes it easy to see where blocks of code, such as
loops, begin and end, and does not waste a line of code.
An alternate style is to place each brace on line by
itself. You may use either of these styles, but do not mix them. Always be
consistent.
Use descriptive (variable, constant, procedure, function)
identifiers and use appropriate naming conventions for
variables (total_sold) and constants (OUNCES_PER_TON).
Remember, syntax should imply semantics.
- Descriptive: int dollars, average, weight
- Cryptic: int x, y, z
Initialize variables (to a value of the appropriate type) before you use them
to avoid garbage. This can be done when you declare the variable or with
an assignment statement before the variable is used.
- Incorrect: double radius = 3;
- Correct: double radius = 3.0;
Avoid type mismatches.
Following this guideline will make your programs more portable.
- Consider:
char c;
while ((c = getchar()) != EOF) {
...
}
Do not assign a variable or literal of one type to a variable of
another, even if our compilers/interpreters permit it.
Following this guideline will make your programs more portable.
- Consider: double avg_score = 76.7; int exam1 = 86;
- Incorrect: avg_score = exam1;
- Correct: avg_score = static_cast (exam1);
- Consider: double average = 0.0; int total = 967, num_students = 10;
- Incorrect: average = total/num_students;
- Correct: average = static_cast (total)/num_students;
Do not use goto.
Only use break in switch statements.
Avoid the use of global variables.
Avoid the use of static variables.
Use comments to explain critical subsections or any ambiguous
parts of your programs (e.g., a tricky expression).
If supported, do not use multi-line comments where they
are likely to make your program less readable.
Use named constants rather than "magic" numbers. This gives you a
single point of modification which will save you time and reduce bugs.
#define SIZE 76
const int NUMBER_OF_RECORDS = 101;
const char A = 'a';
const char E = 'e';
const char I = 'i';
const char O = 'o';
const char U = 'u';
switch (character) {
case A:
case E:
case I:
case O:
case U:
}
Always use enumerated types where they make your code
more readable.
typedef enum { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } months;
main() {
months my_months;
switch (my_months) {
case JAN:
...
break;
case FEB:
...
break;
...
case NOV:
...
break;
case DEC:
...
break;
}
}
Enforce the principle of least privilege.
Do not use local variables with same name in different scopes
(they are different variables).
Always exit from main
with a 0 exit status to indicate success and a
non-zero status to indicate failure. Use exit
rather than return to make your program more
uniform. Use an int as
a return type for main.
int main() {
FILE* fp = NULL;
char* filename = "input.txt";
if ((fp = fopen (filename, "r")) == NULL) {
fprintf (stderr, "cannot open %s\n", filename);
exit (1);
} else {
...
exit (0);
}
Always initialize pointer variables.
Node* node_ptr = NULL;
char* filename = "input.txt";
FILE* myinstream = fopen (filename, "r");
When allocating memory, always verify that the memory was allocated successfully.
if ((node_ptr = malloc (sizeof (Node))) == NULL) {
fprintf (stderr, "out of memory!");
exit (1);
} else {
...
exit (0);
}
Once finished, always free memory that you explicitly allocated.
if ((node_ptr = malloc (sizeof (Node))) == NULL) {
fprintf (stderr, "out of memory!");
exit (1);
} else {
...
free (node_ptr);
exit (0);
}
When opening a file, always verify that the file was opened successfully.
if ((fp = fopen (filename, "r")) == NULL) {
fprintf (stderr, "cannot open %s\n", filename);
exit (1);
} else {
...
exit (0);
}
Always close files that you explicitly opened.
if ((fp = fopen (filename, "r")) == NULL) {
fprintf (stderr, "cannot open %s\n", filename);
exit (1);
} else {
...
fclose (fp);
exit (0);
}
Always print error and debugging messages to stderr
(output written to stdout is buffered)
if ((fp = fopen (filename, "r")) == NULL) {
fprintf (stderr, "cannot open %s\n", filename);
exit (1);
} else {
...
}
Functions:
No routine/subprogram, block, procedure, function, or method (or message)
should exceed 50 lines of code.
Be consistent in your application of the above guidelines.
Overall, write your programs such that they are self-documenting.
In other words, structure your code such that the program itself provides
its own documentation. Self-documentation means using
descriptive identifiers and a consistent, aligned format.
|