搜档网
当前位置:搜档网 › Lecture8_05

Lecture8_05

Lecture8_05
Lecture8_05

LECTURE EIGHT (NOTES) – DOCUMENTATION

What these lecture notes cover:

?How to write good comments

?How to document code (a suggestion)

Lecture Eight (Notes) – Documentation (1)

What these lecture notes cover: (1)

Documenting code (1)

Commenting code well (1)

A badly commented piece of code (1)

A well commented piece of code (5)

External Documentation (6)

User Documentation (8)

Documenting code

An important part of your project write up will be the program documentation. There are three separate parts to code documentation:

1) The comments you put in your code. (internal documentation)

2) What you write about your code to explain how it works to a programmer who will be working on expanding your code. (external documentation)

3) What you write about your code to explain how it works to a user who will be using your program (user documentation)

Each of these three types of documentation requires its own approach.

Commenting code well

Comments are easy to put in code and almost every programmer realises that they should put comments in code but almost no programmers do it well. You should consider the following with each comment:

a) Will it help the reader understand the code

or

b) Am I just adding a comment here because I think I should add a comment

ask yourself "Is this something that the reader could have trivially worked out for themselves" Comments are good but sometimes less is more. Consider:

i= i+1; /* Adds one to i */

If something is particularly tricky then refer to a reference rather than explain it in comment:

void very_complicated_sort (int array[])

/* Sorts the array into increasing numeric order – see

Knuth “Very complicated programming” p150-155 for details */

The next page shows a bad set of comments – the code prints part of the Feigenbaum diagram from coursework.

A badly commented piece of code

#include

#include

#include

/* Richard’s chaos program */ /* Prototypes */

void write_2d_array (char [], int, float [], float []);

/* Enums and #defines */

enum { MAXPOINTS= 50000, RESOLUTION= 1000 }; #define OUTFILE "chaos2.out"

int main()

/* main routine */

{

/* Define some variables */

int tot_points; float x,lambda;

float z[RESOLUTION]; int zval; int i,j;

tot_points= 0;

lambda= 0.75+ (0.25*(float)i / (RESOLUTION-1));

for (j= 0; j < RESOLUTION; j++) {

z[j]= 0;

}

x= 0.3456;

for (j= 0; j < 50; j++) { /* Do this for every j*/

}

for (j= 50; j < 150; j++) { /* Long rambling comment which doesn’t finish x= 4*lambda*x*(1.0 - x);

zval= (int) (x* (RESOLUTION-1));

if (zval >= RESOLUTION)

zval= RESOLUTION-1;

if (z[zval] == 0) {

z[zval]= 1;

xpts[tot_points]= lambda;

ypts[tot_points]= x; tot_points++;

return -1;

}

}

}

}

write_2d_array (OUTFILE, tot_points, xpts, ypts);

return 0; /* End of main */

}

void write_2d_array (char filename [], int no_points, float xaxis[],

float yaxis[])

/* Write a 2 dimensional array */

{

FILE *fptr; /*File pointer */

int i; /* Used in for loop */

fptr= fopen (filename, "w"); /* Open the file */

if (fptr == NULL) {

fprintf (stderr, "Unable to open \"%s\" to write\n",

filename);

exit (-1);

}

for (i= 0; i < no_points; i++) { /* Loop over i */

fprintf (fptr, "%f %f\n", xaxis[i], yaxis[i]);

}

fclose(fptr); /* Close it */

} x= 4*lambda*x*(1.0 - x);

The author of this program has managed to put in a lot of comments without actually any of them being helpful (except, perhaps, to a non C programmer – and a non-programmer isn’t going to be fixing your code I would hope).

What should we comment? As I guideline, I would always comment:

a) Variables unless they are obvious – for example no need to say that i,j or k are variables used in loops – they almost always are. No need to comment that FILE *fptr is a file pointer. On the other hand int total might total up anything and could perhaps use some clarifying.

b) I would always try to put in a comment at the beginning of a function to say what that function does, what it returns and when it breaks.

int factorial (int n)

/* Return the factorial of n. This will break if passed a negative number */

{

.

.

.

}

int write_2d_array (char filename[], int no_points, float xaxis[],

float yaxis[])

/* Writes a 2d array to the file specified by filename in a format suitable for Maple plotting. xaxis and yaxis are the two dimensions to be plotted with no_points in each. The function returns 0 if it is successful or –1 if there is a problem writing to the file */

Your comment need not be quite so verbose as this but should give an idea what each function does, what arguments it takes and what it returns.

c) I always try to put a smaller comment by the prototype of each function which gives some description. The reason is that when you write a large program, the prototypes are all grouped together in a header file and it is easier to gain an understanding of the program by looking at them.

d) In multiple file programming I would put a comment in each file to say what purpose it serves in the program:

fileio.c: /* This contains basic file input/output functions for reading and writing records in the payroll program */

e) Structures are almost always worth a comment since these are likely to be very important in your program.

Other than these situations, you must be guided by common sense. Putting in too many comments makes your program unreadable and messy. Putting in too few will leave it cryptic. A good guide is to put a comment on anything which you would find confusing even if given a minute or two to look at it. If what you are doing is unusual then it is as well to comment it as such. For example, it is easy to

be confused by code that has a 1/(r*r*r) if the code is supposed to deal with gravitation (normally a 1/r2) so it is as well to comment that something unusual is going on. Even if you know the code is correct, a later user might be confused by it (or even worse “correct” it to 1/r2).

A final rule is that if something is extremely difficult to comment and you find yourself spending four or five lines going on about it then it’s almost certainly worth putting a reference to external documentation instead.

You should note that in the Model answers to coursework I have tried to comment appropriately but erred on the side of making too many comments because the coursework model answers were written to be understood by learning programmers. Generally you should write comments with the assumption that the readers will be experienced programmers.

Here is how you should comment the code from the above example (the code below is, if anything, over commented for most programmers' tastes):

A well commented piece of code

#include

#include

#include

/* Feigenbaum.c This program plots a Feigenbaum diagram from

the Logistic map – see, for example:

Peitgen, Jurgens and Saupe: Chaos and Fractals

The plotting is simplified by splitting the y-axis into

"bins" and recording whether or not a point falls into

each of these "bins" and then plotting a point accordingly*/

void write_2d_array (char [], int, float [], float []);

/* Write the contents of two arrays to a file in a format

which can be plotted by maple */

enum {

MAXPOINTS= 50000, /* Max. number of pts to be plotted*/

RESOLUTION= 1000 /* Number of "bins" to split [0,1] into */ };

#define OUTFILE "chaos2.out"

int main()

{

/* Calculate the feigenbaum diagram by looping around each

value of lambda and calculate which of the "bins" contain

points to plot */

float xpts[MAXPOINTS], ypts[MAXPOINTS];

int tot_points; /* The number of points actually plotted*/ float x,lambda; /* variables in the logistic equation */

float z[RESOLUTION]; /* Holds a temporary "slice" of the

diagram for a value of lambda */

int zval; /* Holds the "bin" we are plotting in */

int i,j;

tot_points= 0;

for (i= 0; i < RESOLUTION; i++) {

/* lambda is in the range [0.71,1.0] */

lambda= 0.75+ (0.25*(float)i / (RESOLUTION-1));

/* Clear out the z array – in effect make sure

all the "bins" begin empty */

for (j= 0; j < RESOLUTION; j++) {

z[j]= 0;

}

x= 0.3456; /* x_0 – a randomly chosen start point */ /* Skip over the initial 50 points by iterating the

map 50 times */

for (j= 0; j < 50; j++) {

x= 4*lambda*x*(1.0 - x);

}

/* The next 100 points may be plotted so iterate the

map a further 100 times*/

for (j= 50; j < 150; j++) {

x= 4*lambda*x*(1.0 - x);

/* Calculate which "bin" we are in */

zval= (int) (x* (RESOLUTION-1));

if (zval >= RESOLUTION) /* Check it is in range */

zval= RESOLUTION-1;

/* if this "bin" has not been visited before then

set it as visited and plot a point */

if (z[zval] == 0) {

z[zval]= 1;

xpts[tot_points]= lambda;

ypts[tot_points]= x;

tot_points++;

if (tot_points == MAXPOINTS) {

printf ("Too many points to plot\n");

return -1;

}

}

}

}

write_2d_array (OUTFILE, tot_points, xpts, ypts);

return 0;

}

void write_2d_array (char filename [], int no_points, float xaxis[], float yaxis[])

/* Write the x and y points of the graph to a file, named in the string filename, in a format for maple plotting x axis and yaxis should contain at least no_points pieces of data. */

{

FILE *fptr;

int i;

fptr= fopen (filename, "w");

if (fptr == NULL) {

fprintf (stderr, "Unable to open \"%s\" to write\n",

filename);

exit (-1);

}

/* Write all the points to the file*/

for (i= 0; i < no_points; i++) {

fprintf (fptr, "%f %f\n", xaxis[i], yaxis[i]);

}

fclose(fptr);

}

External Documentation

The role of external documentation is to let another programmer who will be working on your code understand w hat is going on and how he or she might modify your code. It’s hard to give a general description of how to document code since every company has its own standards for this. In addition many automatic documentation tools exist for this purpose. This description is intended as a reasonable way of documenting at the level required for your projects rather than as a description of “best practice” in the real world.

Documentation must be done at several levels:

1) Describe the broad purpose of your code – what it is supposed to achieve and how. Describe what files the program needs to run and how it works (in brief). This section can be quite long in a complex program.

Example:

2) Describe the general “flow” of your program. That is, how it works as an algorithm –if you’ve used particular sorting routines for example then describe which one. Often this is clearer in a diagram form. Example:

[Note that this is an example only and you need not use this format, sometimes something more like a traditional “flow chart” can be very effective.]

3) Describe what “source modules” your program has if you have used multiple file programming.

That is, what .cpp and .h files you have used and what they each contain (a brief list of the most important things in each file).

Example:

.

.

4) Almost any struct/typedef used in your code should be described in the documentation unless it is particularly trivial.

Example:

This is very similar to the comments made on every function on the internal documentation. Note that

I have been vague about what constitutes a “major” function. Your code for this project is likely to be short enough that explaining every function won’t take too long. Pay particular attention to describing functions which are doing the “real work” – these are not necessarily the most complicated ones to write – it can be very complicated to write a file input function to read individual words – but it would not be useful (or particularly interesting) to spend a great deal of time describing this.

You should also comment on any equations you use within the code unless their purpose is particularly obvious. If there is anything unusual about how the program works or any quirks then these should be mentioned.

Example:

User Documentation

User documentation is written to describe to the end-user how to run your program. Writing user documentation is an art-form in itself and entire books have been written on how to do it. In general your programs will not be complex enough to require extensive user documentation so I don’t intend to teach you anything about how to write this. Feel free to include limited user documentation in your write up if you want (but don’t spend too long on it, it is not really very important to your mark).

相关主题