Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C++ For Mathematicians (2006) [eng]

.pdf
Скачиваний:
194
Добавлен:
16.08.2013
Размер:
31.64 Mб
Скачать

386 C++ for Mathematicians

}

void Polygon::move_vertex(int j, Point P) {

// If the index is invalid, no action is taken if ( (j<0) || (j >= np) ) return;

vertices[j] = P;

}

double Polygon::perimeter() const {

// The perimeter is zero unless we have at least two points if (np <= 1) return 0.;

double ans = 0.; // place to accumulate the distances

//add up the distances between successive vertices for (int k=0; k<np-1; k++) {

ans += dist(vertices[k],vertices[k+1]);

}

//Add in the distance between the first and last points ans += dist(vertices[0], vertices[np-1]);

return ans;

}

The only Doxygen comments in Polygon.cc are to document the file. Other, ordinary comments are included to clarify the code to a human reader.

B.2 Using Doxygen

If Doxygen is not already installed on your computer, download it from its Web site (www.doxygen.org) and install it according the instructions found there.

You should also collect all the files for your project into a single folder (directory) on your computer. You probably have done this already.

Now launch the Doxygen tool. You are presented with a graphical user interface (“GUI”) window that specifies the easy steps for you to follow. See Figure B.1.

B.2.1 Configuring Doxygen

The first step is to configure Doxygen. In the configuration process you set various options (and I’ll give you recommendations on what to select) and then save the configuration as a file named Doxyfile.

To begin the configuration process, click the Wizard. . . button. A new window opens with four tabs. See Figure B.2. The four tabs are named Project, Mode, Output, and Diagrams. Here’s how to complete each of these pages.

Documentation with Doxygen

387

Figure B.1: Doxygen GUI window.

Figure B.2: Doxygen configuration panel.

388

C++ for Mathematicians

On the Project page, type in a name for your project in the first field. If you desire, you can specify a project version in the second field.

Next you specify the location of the source code (i.e., the full path name of the folder containing your .cc and .h files). Either type in the full path to your source folder in the text field, or use the first Select. . . button to navigate to the directory (and the Wizard fills in the field for you).

If your source code is organized into various subfolders, check the Scan recursively box. Otherwise, you can leave this unchecked.

Finally, specify the destination directory. This is the directory in which the beautifully formatted documentation is to reside. If you wish, this can be the same directory as the source code. As needed, Doxygen creates subdirectories in which it places the documentation. For example, it creates an html subfolder for the Web pages.

Now click to the Mode page. In the top portion, select the All entities button. This tells Doxygen to create documentation for all parts of your program including private data members, and so on.

Check the Include cross-referenced source code in the output box. This causes Doxygen to create Web pages that show your source code. (You can click on the documentation to look at the source code and click inside the source code to go back to the documentation. This is a handy feature.)

Finally, click the Optimize for C++ output button.

Now click to the Output page. Check the HTML box. Under that box either select plain HTML or with frames and navigation tree. If you are only building documentation for one procedure or a small class, then the plain HTML option is sufficient. However, if the project has more than one source file, select the with frames option.

For now, leave the other options (LaTeX, Man pages, Rich Text Format, and XML) unchecked. Later, if you wish to explore these other output formats, you can change your selection.

Finally, click to the Diagrams page. For now, select the No diagrams option. Later, you can explore the different kinds of diagrams that Doxygen can create for you.

You are now finished using the Wizard, so click OK to return to the main Doxygen GUI window.

You now proceed to Step 2 on the GUI: save the configuration file. When you click Save. . . you will be prompted to save the configuration in a directory. Choose the same directory as your code and use the file name Doxyfile.

Doxygen is now configured for your project. All of Doxygen’s settings are saved in the file named Doxyfile in the same directory as your source code.

Documentation with Doxygen

389

If, after you have saved the Doxyfile, you wish to modify your settings, select Load. . . in the Doxygen GUI to select the Doxyfile you wish to modify, and then use Wizard. . . to choose the new options. If you want finer control, you may modify the settings using the Expert. . . button.

You are now ready to run Doxygen to generate the Web pages.

B.2.2 Running Doxygen

Continuing in the Doxygen GUI, Step 3 asks for a directory in which Doxygen is to run. Use the Select. . . button to navigate to the same directory that holds the code and holds the Doxyfile configuration file.

Finally, press the Start button in Step 4. If all is well, a subfolder is created named html into which the Web pages for your documentation are deposited. Open this folder and double-click on index.html. You are greeted by a main page from which you can explore all the documented files, classes, procedures (functions), methods, and so forth.

If there are mistakes in the formatting of your Doxygen comments, error messages appear in the box labeled Output produced by doxygen in the main GUI window.

B.2.3 More features

In this brief introduction to Doxygen we presented just a few of the documentation tags available. Reviewing tersely, we have seen:

@file and @brief document the overall purpose of a file, and

@param and @return to document the inputs and outputs of procedures and methods.

Doxygen provides many other tags and we mention just a few of them here.

Cross references. Doxygen provides a tag named @see that you can use to insert a cross-reference to another procedure or method.

Sample code. It is useful to include a snippet of C++ code to illustrate how a procedure is used. To do this, enclose the code fragment between @code and @endcode, like this:

/// Find the median /**

*This procedure finds the median value in an array of numbers.

*@code

*double* values;

*// allocate and populate the values array

*m = median(values, n);

*@endcode

*@param vals array of real numbers

*@param nels number of elements in the array

*@return the median value in the array

390

C++ for Mathematicians

*/

double median(double* vals, int nels);

Mathematical notation. It is possible to include mathematical formulas into

the documentation using TEX. This requires that TEX be installed on your system. In TEX, mathematical notation is enclosed between single dollar signs. For Doxygen, enclose your notation between @f$ tags, like this:

/// Approximate the Riemann zeta function /**

*This procedure calculates an approximation to the Riemann

*zeta function by expanding @f$\zeta(s)=\sum_{k=1}ˆn 1/kˆs@f$.

*@param s argument to the zeta function

*@param n number of terms in the series

*@return an approximation to @f$\zeta(s)@f$

*/

double zeta(double s, int n);

It is also possible to typeset displayed formulas enclosed in the tags @f[ and

@f].

Bugs. Sometimes programs don’t work properly and give incorrect results. Until you have your code working properly, you can flag what is wrong with a

@bug tag.

/// Group element powers /**

*Given a Group element g and an integer n, calculate gˆn.

*@bug This isn’t working for negative exponents.

*

*@param g an element of the group

*@param n the power to which we wish to raise g

*@return g multiplied by itself n times

*/

Author, date, and version. With the tags @author, @date, and @version you can flag who did what and when on a large-scale project.

Many more Doxygen tags can be found in the Doxygen documentation (available online).

In addition to Doxygen tags, it is possible to insert HTML code in your comments. For example, suppose you implemented an algorithm you found on a Web page in your code and you wish to give proper attribution to the source you consulted. You can include a link to that Web page like this:

/**

*Description of this procedure...

*<p>

*The algorithm we use was invented by Ann Expert and is described

*<a href="http://www.math.major-univ.edu/˜expert/algo.html">on

*this Web page</a>.

*/

Appendix C

C++ Reference

This appendix gives a brief review of the C++ language as developed in this book. After you have read this book, you can use this appendix as a refresher course.

C.1 Variables and types

All variables in C++ must be declared before they are used. The declaration specified the type of data the variable holds. The type of a variable may be one of the fundamental types or a class.

C.1.1 Fundamental types

Boolean: bool

Character: char

Integer: short, int, long, long long1

Real: float, double, long double

The integer types may be preceded with the keyword unsigned to shift their range to nonnegative values. The long long and long double types might not exist on all systems.

C.1.2 Standard classes/templates

C++ provides a large collection of standard classes. Many of these require a #include directive to load the appropriate header file.

For example, to work with complex numbers, we include the <complex> header. A typical complex number is declared complex<double> z; and a Gaussian integer is declared complex<long> w;.

1Use int64 in Visual Studio.

391

392

C++ for Mathematicians

Character strings are handled most conveniently using the standard string class (see Chapter 14); use the header #include <string>.

There is a variety of standard classes for input/output (see Chapter 14) and to serve as containers (see Chapter 8).

C.1.3 Declaring variables

The simplest declaration statement specifies the type of a variable: int j;. Two or more variables of the same type may be declared in a single statement:

long a,b;.

A variable may be given an initial value when it is declared: double x = 3.5;. A variable declared using a template class should include the type parameters

between < and > symbols, like this: complex<double> z;.

Class variables often take arguments (sent to the constructor methods) when declared: Mod a(3,10);.

There are three natural locations for a variable declaration.

• Inside the body of a procedure (such as main or a class method). For example,

int main() { double x;

...

}

• Inside the declaration of a procedure or method. For example,

long gcd(long a, long b) {

...

}

• Inside a looping control structure. For example,

for (int k=0; k<10; k++) { cout << k << endl;

}

C.1.4 Static variables and scope

Variables are created when they are declared and are lost when the section of the program in which they are declared finishes. Two different procedures (say, alpha and beta) may both declare a variable named x, but alpha’s x and beta’s x have nothing to do with each other. All variables are local to the procedure in which they are declared. (It is possible, but ill advised, to create global variables in C++. We don’t discuss how.)

When a procedure finishes, the values held in its variables are lost unless the variables are declared static. In this case, the value held in the variable is retained between calls to the procedure.

C++ Reference

393

C.1.5 Constants and the keyword const

If a variable is declared with a given value and the program never changes that value, then the variable should be declared const. For example, in a program that uses the Golden Mean, we would have this: const phi = (1.+sqrt(5.))/2.;.

Arguments to procedures that are not modified by the procedure should be declared const. For example, suppose we create a procedure to calculate the sum of the elements in a set of integers. Because such a procedure does not modify the set, we declare it such as this:

long sum(const set<long>& S) {

...

}

A third use of the keyword const is to certify that a method does not change the object on which it is invoked. For example, if we are creating a LineSegment class, a method that reports the length of the segment would not modify the segment. In the header file, say LineSegment.h, we would find this:

class LineSegment{ private:

//variables to specify the segment public:

//constructors, etc.

double length() const;

};

and in the program file, say LineSegment.cc, we find this:

double LineSegment::length() const { // calculate and return the length

}

C.1.6 Arrays

If the size of an array can be determined before the program is run, it may be declared like this: int alpha[20];.

However, if the size of an array is unknown until the program is running, use a dynamically sized array like this:

int n;

cout << "Enter array size: "; cin >> n;

int* alpha;

alpha = new int[n];

...

delete[] alpha;

Remember that every array allocated with new should be released with a delete[].

394

C++ for Mathematicians

C.2 Operations

Here we describe the behavior of C++’s fundamental operations. Remember, however, that classes can override these meanings (e.g., the << operator does input when used with cin but its fundamental use is to shift bits).

C.2.1 Assignment

The statement a=b; takes the value held in the variable b and places that value in the variable a. Assignment statements can be combined. The statement a=b=c; is equivalent to a=(b=c); and the effect is to take the value in c and store that value in both b and a.

C.2.2 Arithmetic

The basic arithmetic operators are +, -, *, and /. For integer types, the mod operator is %. There is no exponentiation operator, but the pow and exp procedures fill this gap.

The - operator can be used as a unary operator; this negates its argument. For example, if a holds the value 3, then b=-a; assigns to b the value −3 (leaving a unchanged).

The arithmetic operators can be combined with assignment. For example, a+=b; is equivalent to a=a+b;.

For integer types, the operators ++ and -- cause the variable to which they are applied to increase (respectively, decrease) by one. There is a difference between ++a and a++. Do not write code that exploits this subtlety.

C.2.3 Comparison operators

Numerical types can be compared for equality, inequality, and order using these operators:

== != < <= > >=

The result of these operators is a value of type bool.

C.2.4 Logical operators

C++ provides the following operators for bool values,

&& || !

These are logical and, or, and not.

C++ Reference

395

C.2.5 Bit operators

The individual bits in an integer variable can be manipulated using the following operators,

& | ˜ ˆ << >>

These are (bitwise) and, or, not, exclusive or, left shift, and right shift.

C.2.6 Potpourri

Square brackets are the subscript operator, used to access elements of an array. The first element of an array has index 0.

Parentheses are used for grouping, but also indicate the invocation of a procedure or method: y = alpha(x,n);.

Dot (.) is the member-of operator used to specify a data member of method of a class: x.size() or thing.first.

The question mark/colon trigraph is an abbreviated if/then statement. The statement a=q?b:c; assigns the value of b to a if q is true; otherwise (q is false) it assigns the value of c to a.

The keyword sizeof is an operator that returns the number of bytes required to hold a type; for example, sizeof(double).

The comma is used for separating procedure arguments and when declaring more than one variable of a given type (e.g., double x,y;). It also has the obscure purpose of combining two (or more) expressions into a single statement. For example, in a for loop, if we want to initialize two counters, we may have a code such as this:

int a, b;

for (a=N,b=0; a-b>0; a--,b++) { // stuff to do

}

This initializes a with the value held in N and b with 0.

The following operators are for working with pointers.

Ampersand is the address-of operator. If x is an int variable, then &x returns a pointer to x of type int*. The ampersand is also used to specify call-by-reference semantics in procedures.

Asterisk is the pointer dereferencing operator. If p is a pointer to an integer value, then *p is the value held in the location pointed to by p.

The arrow operator, ->, combines the action of . and *. For example, if p is a pointer to an object, then p->x is equivalent to (*p).x (the data element x of the object p points to) and p->alpha() is equivalent to (*p).alpha() (invoke method alpha on the object pointed to by p).