Checklist for good programming
This checklist should help you write high-quality programs.
Raphael Finkel, 8/17/2005
- Identifiers: Make sure all your identifiers are meaningful.
- One-letter identifiers are almost never meaningful.
- Names like flag and temp are seldom
meaningful. Instead of flag, consider naming the Boolean
condition it checks for, such as valueFound.
- Consider multi-word identifiers, like nameIndex.
Long identifiers (within reason) tend to be very readable.
- Bare literals: Avoid numbers other than 0 and 1 and strings other
than "" in your program except when you
define constants.
- Don't use a literal integer as an array bound.
- Don't use a literal integer as a run parameter, such as a timeout
or port number.
- Don't use literal integers to select menu entries.
- Don't use a literal integer to measure the size of a string or
some data; use sizeof() and strlen() in C and
C++ and .length() and .size in Java.
- Don't use a literal string for a file name. You may output
literal strings, though.
- Don't use a literal integer to index into an array containing
heterogeneous data.
- Don't declare an identifier with a name denoting a literal,
such as "thirty".
- Modularization: A program is built out of interacting components.
- Don't put all your code into the main() routine.
- In fact, don't make any routine do too much work. If it's longer
than about 50 lines, it is maybe too long.
- If you duplicate code several times, consider whether a loop would
work better, or perhaps a subroutine.
- If you find you are indenting very deeply, you most likely aren't
using subroutines when you should.
- Don't reinvent library routines (unless your assignment requires
it). Look in the manuals to learn about sprintf() and
atoi(), for instance.
- Use header files in C and C++ (header files have names ending
.h) to define all constants needed by multiple files and
declare all subroutines exported between files.
But don't put the body of subroutines in header files (with the rare
exception of inline subroutines).
- Formatting: Your program should be easy to read.
- Look at
http://geosoft.no/development/javastyle.html for clear suggestions on
formatting and other presentation issues. This reference is specifically
directed at Java, but it has value for other languages, too.
- Try to restrict all your lines to 80 characters; many people view
code in 80-column windows for historical reasons.
- Don't use both tabs and spaces for indentation, because not all
text editors treat tabs as exactly 8 spaces.
- Do follow a consistent indentation pattern that reflects the
program's control structure.
- Don't put lots of blank lines in your program. One blank line
between subroutines is enough.
- Different operating systems terminate lines different ways. If
you move between Win32 (which uses \r\n), Unix (which uses \n), and MacOS
(which uses \r), reformat your file to use a consistent termination method.
- Don't set the executable bit (Unix) on your source files.
- Coding: You want your coding to be clear, maintainable, and
efficient, in that order. Some of the rules here are very specific; others are
more general.
- Don't use a sequence of if statements that have no
else if only one can match; use
else if.
- When you want to categorize text input, don't enumerate the
possible first characters.
- Use shift operators instead of multiplication for
constructing bit patterns.
- In a switch statement, always check for the
default case. Likewise, in a sequence of if-then-else
statements, use a final else.
- All system calls can fail. Always check the return code, and use
perror() to report the failure.
- Booleans should always use the boolean type in
Java, bool in C++, and 0/1 integers in C. Don't use
characters t and f, and don't use -1 and 1.
- Use loops to initialize data structures if possible.
- Use each variable and each field of a structure for exactly one
purpose. Don't overload them unless there is an excellent reason to do so.
- Don't use the same identifier for both a type, a variable, and a
file name, even if you change the capitalization. It's too confusing.
- If you are modifying data with htonl() or a
similar routine before network transmission, don't modify the data in
place. Build a second data structure.
- Try not to use global or nonlocal variables. Declare each
variable in the smallest scope you can. There are legitimate uses of
nonlocal variables, but make sure you really need them.
- Shell, Perl, and Python programs should have their #! line as
the first line of the file; otherwise, the line is just a comment.
- Try to avoid coding special cases. You can often use pseudo-data
or other data-structure methods that allow you to fold special cases into
the regular cases.
- Compilers: Let them help you find mistakes. Always invoke compilers
with all warnings enabled.
- For C and C++,
use the -Wall flag.
- For Java, use -Xlint:all -deprecation, and use the pmd program to get suggestions for better style.
- For Python, use -t -W all.
- For Perl, use the -w flag and
specify use strict. Cgi-bin scripts should
have the -T flag, too.
- The make utility: Use it, and use it well.
- A Makefile should always have a "clean" recipe, which should
remove all files that can be reconstructed by other recipes in the
Makefile, including object and executable files.
- If your project has multiple source files, the Makefile should
generate object (.o) files as needed and link them together.
- The Makefile should be written so that if you
run make twice in a row, the second run does no recompilation.
- Every recipe should create the file specified in its target.
- Every recipe should use every file specified in its
prerequisite list.
- Learn to use rules for targets like .c.o to avoid
repetitious makefiles.
- If you have just one C or C++ source file, the executable file
should have the same name (without the extension .c or
.cpp).
- Make sure you list all .h files as prerequisites
where they are needed. Consider using makedepend to generate the
prerequisite list for you.
- Documentation: It's not just just for the grader. It helps you as
you write the program, too!
- Add documentation as you write the program. You can always modify
it as your design changes.
- Write external documentation: How does one compile and run the
program, and what is it meant to do? The external documentation is usually
in a separate README
file; for small projects, it can be a comment in the single
source file.
- Include internal documentation: What algorithms and data
structures are you using? An overview can be in a separate README file, but
usually internal documentation is placed on the specific routines,
declarations, and steps that it describes.
- Check your whole program and documentation for spelling mistakes.
It is impolite to turn in misspelled work, and it bespeaks inattention to
detail.
- Check all your documentation (and output messages) for grammar
mistakes.
- Programs are much more readable if you put a short comment on
closing braces. For instance, the brace closing a conditional can have
a comment like "if value looks good". A brace closing a loop can have a
comment like "for each input line". A brace closing a procedure can have a
comment just naming the procedure. A brace closing a class can have a
comment saying "class" and then the name of the class.
For some reason, this page is popular with translators.