Documentation in general is not considered part of the coding process, but perhaps it should be. Many programmers don't like it, but it is, of course, very important. This article would be incomplete without a discussion of this topic.
The two broad categories of documentation are internal and external. They serve different purposes and should be approached totally differently.
Internal documentation is mainly for the benefit of the programmer reading or modifying the source code. (I say "mainly" because I'll make an exception to this shortly.) There is not much to say about this except the advice that is routinely given to undergraduates: Comment profusely, especially the hardest parts of the code; comment at a high level and avoid useless comments such as "increment the counter"; and strive to keep the comments in sync with the code as it changes.
The concept of literate programming tends to blur this distinction because it advocates the generation of (at least some) external documentation from the internal docs. For example, you can put specially formatted comments and directives in your source and run a tool that will extract them and convert the result to HTML or a similar format. The open source tool cppdoc is one such tool (inspired by the Java equivalent javadoc). Such a tool is especially useful in generating an API reference because many tools can parse not just the comments but also the source to produce an excellent written "map" of your code.
External documentation is very important if you are creating something to be used by others. There are several kinds of this documentation, and they are not usually mutually exclusive. Most of the time, we will (or should) create all of them.
The installation notes usually take the form of a README file or the equivalent, which we routinely anticipate seeing in an archive. These notes will detail any instructions for building or installing the software. (As an aside, the process of building and installing should be automated as much as possible.) These notes should document any external dependencies such as third-party libraries or special operating system or software version requirements. They should also (when possible) document any quirks pertaining to specific compilers or operating systems. (It's not a bad idea to put comments in the makefiles also.)
The install notes should also document known bugs and limitations in the software. A version history is sometimes a good idea. Ideally, there should be a FAQ or a list of common problems and what to do if they are encountered. When possible, courtesy dictates pointing the user to external sources of help: users' groups, web pages, newsgroups, online tech support, and so on. This will vary depending on whether it is a commercial product or a free one, whether it is widely used software, and whether it is an individual or team effort.
It's an excellent idea to have tutorial information for your software. This might be plain text, but it's good to have a "prettier" format such as HTML. Show the user step by step what is going on, show one operation at a time, explain alternatives, and let the examples build on each other. When you refer to a whole file in the tutorial, point the user to a ready-to-run file in the distribution. If possible, let the test cases serve as additional examples (and comment them appropriately if you do).
Perhaps most important of all is to have reference documentation for the software. This should be in some hypertext format such as HTML, and may additionally be in some other form such as a command-line program that searches for a specified item and dumps a piece of information on that item. On Unix or Linux, man pages are a good idea; on Windows, the Windows help format is a standard.
As I said before, it's possible to generate much of this documentation automatically. This serves a dual purposeit keeps the external documentation in sync with the source, and it motivates the programmer to keep the internal docs in line with the code itself.
If you do generate parts automatically, consider weaving in other parts by hand. If an occasional picture or diagram helps, don't hesitate to throw in a PNG file here and there. You might consider generating a PDF file for those users who want to print really nice-looking, page-oriented docs.
Documentation always gets out of date. When possible, point the user to an external resource that will be more current, such as a web page.
In short, remember the "golden rule" of documentation: Write the kind of docs that you like to see; the kind you wish you had for every piece of software. Think of it as software karma: What goes around comes around.