home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 2
/
FFMCD02.bin
/
new
/
dev
/
misc
/
cweb
/
examples
/
primes.w
< prev
next >
Wrap
Text File
|
1993-12-21
|
22KB
|
486 lines
% PRIMES example of WEB/CWEB portability. This documentation was
% originally published in the article ``Literate Programming'' by Donald
% E. Knuth in ``The Computer Journal'', May 1984, and later in the book
% ``Literate Programming'', October 1991, where it appeared as the first
% example of WEB programming for Pascal. It has been translated into
% CWEB by Andreas Scherer to show the ease of portability between
% Pascal/WEB and C/CWEB. As little changes as possible were made, so that
% the section numbering of the Pascal and the C version are identical,
% except that a small list of related literature was appended at the end.
% Minor changes to include extra C functionality are mentioned in the text
% that follows. The `cite' feature of CWEB 2.8 is used.
% This program is distributed WITHOUT ANY WARRANTY, express or implied.
% WEB Version --- Don Knuth, 1986
% CWEB Version --- Andreas Scherer, 1993
% Copyright (c) 1993 Andreas Scherer
% Permission is granted to make and distribute verbatim copies of this
% document provided that the copyright notice and this permission notice
% are preserved on all copies.
% Permission is granted to copy and distribute modified versions of this
% document under the conditions for verbatim copying, provided that the
% entire resulting derived work is distributed under the terms of a
% permission notice identical to this one.
\font\csc=cmcsc10
\def\CWEB{{\tt CWEB}}
\def\Pascal{{\csc Pascal}}
\def\[{\ifhmode\ \fi$[\mkern-2mu[$}
\def\]{$]\mkern-2mu]$\ }
\def\Section{\mathhexbox278}
\hyphenation{Dijk-stra}
\def\title{PRIMES (C Version 1.1)}
\def\topofcontents{\null\vfill
\centerline{\titlefont Printing prime numbers}
\vskip15pt
\centerline{(C Version 1.1)}
\vfill}
\def\botofcontents{\vfill
\noindent Copyright \copyright\ 1993 Andreas Scherer
\bigskip
\noindent Permission is granted to make and distribute verbatim copies of
this document provided that the copyright notice and this permission
notice are preserved on all copies.
\smallskip
\noindent Permission is granted to copy and distribute modified versions
of this document under the conditions for verbatim copying, provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.}
@* Printing primes: An example of \CWEB\null. The following program is
essentially the same as Edsger Dijkstra's@^Dijkstra, Edsger@> ``first
example of step-wise program composition,'' found on pages 26--39 of his
{\sl Notes on Structured Programming\/} [1], as presented by Donald E.
Knuth@^Knuth, Donald E.@> on pages 103--112 of his {\sl Literate
Programming\/} [2], but it has been translated into the \CWEB\ language by
Andreas Scherer@^Scherer, Andreas@>.
@.CWEB@>@.WEB@>
\[Double brackets will be used in what follows to enclose comments relating
to \CWEB\ itself, because the chief purpose of this program is to introduce
the reader to the \CWEB\ style of documentation. \CWEB\ programs are always
broken into small sections, each of which has a serial number; the present
section is number 1.\]
Dijkstra's program prints a table of the first thousand prime numbers. We
shall begin as he did, by reducing the entire program to its top-level
description. \[Every section in a \CWEB\ program begins with optional {\it
commentary\/} about that section, and ends with optional {\it program
text\/} for the section. For example, you are now reading part of the
commentary in \Section1, and the program text for \Section1 immediately
follows the present paragraph. Program texts are specifications of \Cee\
programs; they either use \Cee\ language directly, or they use angle brackets
to represent \Cee\ code that appears in other sections. For example, the
angle-bracket notation `|@<Program to print...@>|' is \CWEB's way of saying
the following: ``The \Cee\ text to be inserted here is called `Program to
print $\ldots$ numbers', and you can find out all about it by looking at
section 2.'' One of the main characteristics of \CWEB\ is that different
parts of the program are usually abbreviated, by giving them such an
informal top-level description.\]
@c
@<Program to print the first thousand prime numbers@>
@ This program has no input, because we want to keep it rather simple. The
result of the program will be to produce a list of the first thousand prime
numbers, and this list will appear on the |stdout| file.
Since there is no input, we declare the value |MM==1000| as a compile-time
constant. The program itself is capable of generating the first |MM| prime
numbers for any positive |MM|, as long as the computer's finite limitations
are not exceeded. The boolean values |TRUE| and |FALSE| are defined.
\[The program text below specifies the ``expanded meaning'' of `|@<Program
to print...@>|'; notice that it involves the top-level descriptions of two
other sections. When those top-level descriptions are replaced by their
expanded meanings, a syntactically correct \Cee\ program will be obtained.\]
@d MM 1000
@d TRUE 1
@d FALSE 0
@<Program to print...@>=
#include <stdio.h>
void main(void)
{
@<Variables of the program@>@;@#
@<Print the first |MM| prime numbers@>@;
}
@* Plan of the program. We shall proceed to fill out the rest of the
program by making whatever decisions seem easiest at each step; the idea
will be to strive for simplicity first and efficiency later, in order to
see where this leads us. The final program may not be optimum, but we want
it to be reliable, well motivated, and reasonably fast.
Let us decide at this point to maintain a table that includes all of the
prime numbers that will be generated, and to separate the generation
problem from the printing problem.
\[The \CWEB\ description you are reading once again follows a pattern that
will soon be familiar: A typical section begins with comments and ends with
program text. The comments motivate and explain noteworthy features of the
program text.\]
@<Print the first...@>=
@<Fill table |p| with the first |MM| prime numbers@>@;
@<Print table |p| @>@;
@ How should table |p| be represented? Two possibilities suggest
themselves: We could construct a sufficiently large array of boolean values
in which the |k|th entry is |TRUE| if and only if the number |k| is prime;
or we could build an array of integers in which the |k|th entry is the
|k|th prime number. Let us choose the latter alternative, by introducing an
integer array called |p[MM]|.
In the documentation below, the notation `|p[k]|' will refer to the |k|th
element of array |p|, while `$p_k$' will refer to the |k|th prime number.
If the program is correct, |p[k-1]| will either be equal to $p_k$ or it
will not yet have been assigned any value. (Note that arrays in \Cee\ are
indexed starting from 0 and not from 1 as in \Pascal)
@^Differences between \Pascal\ and \Cee@>
\[Incidentally, our program will eventually make use of several more
variables as we refine the data structures. All of the sections where
variables are declared will be called `|@<Variables of...@>|'; the
number `4' in this name refers to the present section, which is the first
section to specify the expanded meaning of `|@<Variables of...@>|'.
The note `{\eightrm See also~$\ldots$}' refers to all of the other sections
that have the same top-level description. The expanded meaning of
`|@<Variables of...@>|' consists of all the program texts for this name,
not just the text found in \Section4.\]
@<Variables of the program@>=
int p[MM]; /* the first |MM| prime numbers, in increasing order */
@* The output phase. Let's work on the second part of the program first.
It's not as interesting as the problem of computing prime numbers; but the
job of printing must be done sooner or later, and we might as well do it
sooner, since it will be good to have it done. \[And it is easier to learn
\CWEB\ when reading a program that has comparatively few distracting
complications.\]
Since |p| is simply an array of integers, there is little difficulty in
printing the output, except that we need to decide upon a suitable output
format. Let us print the table on separat