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

C++ For Mathematicians (2006) [eng]

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

6

C++ for Mathematicians

As mentioned, the << operation takes two arguments: the cout object on its left and the character array on its right. The effect of this operation is that the character array is typed onto the computer’s screen.

The semicolon at the end of the line is mandatory; it marks the end of the statement. We could have broken this statement into two (or more lines), like this,

cout

<<

"Don’t you just feel like a louse"

;

Line 13 is similar to line 12, but in place of the character array, we have the endl object. The endl stands for end of line; it causes the computer’s output to move to a new line in the output. Without this statement, the next output would begin immediately after the e in the word louse.

Lines 15 and 16 write the second line of the poem to the computer screen. The only interesting thing here is that we want quotation marks to be part of the output (surrounding the word new). Because quotation marks signal the beginning and end of the character array, we need a way to indicate that the quotes around new are not delimiters, but part of the text message. This is done by preceding the " mark with a backslash, \.

Lines 12 through 16 comprise four separate statements. These could be combined into a single statement without loss of clarity. The various objects to be printed can be fed to cout by repeated use of the << operation.

cout << "Don’t you just feel like a louse" << endl

<<"To learn that your \"new\" theorem was proved by Gauss?"

<<endl;

Here is the output of the program.

Don’t you just feel like a louse

To learn that your "new" theorem was proved by Gauss?

The other parts of the program are important, too. Let’s examine them one by one.

The first line of the program is #include <iostream>. This line is necessary to incorporate the definitions of various input/output objects and operations. The objects cout and endl are not in the main part of C++, and need to be read into the program.

Ironically, this first line of our first C++ program is not actually C++ code. It is a request to the C++ compiler to read a file called iostream and include the contents of that file in this program. The file iostream is called a header file. This header file is part of the C++ system, and so is called a system header file. Soon, you will write your own header files, and those are known as user header files.

The compiler knows where to find iostream and before it does anything else with your program, it inserts the full contents of the file iostream at the start of your program.

The Basics

7

Because this line is not a C++ statement, no semicolon is needed at its end. Instructions that begin with the # sign are preprocessing directives. We examine a few other such commands later.

Any time you write a C++ program that reads or writes data from the computer screen, you need to include the iostream header.

Line 2 is particularly inscrutable. For now, just know that if you use #include to read in any standard system header files, then you must have the statement using namespace std; as well.

You may safely skip the rest of this explanation. The objects cout and endl are not core parts of C++, but standard additions to the language. It is possible that a software developer—let’s call her Sophie—might want a different version of cout that is somehow different from the standard version.

Sophie also wants to call her console output object cout; this is possible in C++. Sophie creates (don’t worry about how, you are not a software developer) a separate namespace, which she calls, say, sophie. The full name of Sophie’s cout is sophie::cout. The full name of the standard cout is std::cout, where std stands for the “standard” namespace.

In the iostream file, cout and endl are defined to have the full names std::cout and std::endl. It is possible to delete line 2 from the program, but then it would be necessary to replace cout with std::cout (and likewise for endl). However, for our purposes, it is much easier to declare: we are going to be using the standard namespace, so we will use the short forms of the names. That’s what the statement using namespace std; does.

Lines 4–9 are a comment. Comments are important features of computer programs. This comment immediately precedes the main part of the program and explains what the program does.

Comments in C++ are of two forms: multiple-line comments and single-line comments.

Multiple-line comments may span one or more lines. The comment begins with the pair of characters /* and ends with */. Everything between these is ignored by the compiler; the comments are meant for a human reader. The comment spanning lines 4 through 9 is of this sort. The single asterisks on lines 5 through 8 are present only to make it clear that this block of text is a comment. Clean formatting like this makes the program more readable. The extra * on line 4 serves a purpose that is revealed later (see Appendix B); for the present, you can think of it as optional.

Single-line comments begin with a double slash // and continue to the end of the line. They are useful for short comments. For example, to explain line 12 of the program, I could have written this:

cout << "Don’t you feel like a louse"; // rhymes with Gauss

8

C++ for Mathematicians

Line 11 and lines 18–19 surround the main part of the program. As we create more elaborate C++ programs, we separate the program into multiple files, with each file containing various procedures. In each program, there must be exactly one procedure whose name is main. We examine procedures in more detail later, but for now here is what you need to know.

Procedures take various values as arguments, execute instructions, and return a value. In this case, the procedure named main returns an integer value; this is signified by the word int before the name of the procedure. The value returned is zero, and this is accomplished at the end of the procedure with the statement return 0; which returns the value 0.

The main procedure does not take any arguments; this is signified by the empty pair of parentheses following the word main. There is an alternative way to create a main procedure that does take arguments; we explore that later (see Chapter 14).

Thus the beginning of line 11, int main(), says that this is a procedure that takes no arguments and returns an integer-valued answer.

After int main(), the statements of the procedure are enclosed in curly braces. The opening curly brace is on line 11 and its matching closing brace appears alone on line 19.

Notice that lines 12–18 are indented from the left margin. This indenting helps enormously with readability.

This completes our analysis of Program 1.1.

1.3Exercises

1.1The following comment in a C++ program would cause the compiler to issue an error message.

/*

* In C++ comments are enclosed between /* and */ */

What’s wrong?

1.2 The following program is typed into the computer and saved as bad.cc.

#include <iostream>

int main() {

cout << "What is wrong with this program?" cout << endl;

The Basics

9

return 0;

}

When this program is compiled, the following output is produced.

bad.cc: In function ‘int main()’:

bad.cc:4: error: ‘cout’ undeclared (first use this function) bad.cc:4: error: (Each undeclared identifier is reported only

once for each function it appears in.) bad.cc:5: error: parse error before ‘<<’ token

There are two errors in the program. Use the output to figure out what those errors are.

1.3 A programmer included the following line in a program.

cout << "My favorite web site is http://www.google.com";

Do the slashes // start a comment?

1.4To include a quotation symbol in output, we use the sequence \". Write a program to see what the sequences \n, \t, and \\ do when part of a character sequence.

For example, your program should contain a line such as this:

cout << "What does \n do?";

1.5Write your own bad math poem. There’s great potential for a terrible rhyme with Euler including under the broiler and stop or you’re goin’ to spoil her and how long does an egg boil fer?

Send your worst to the author at ers@jhu.edu and we’ll post the best/worst on this book’s Web site www.ams.jhu.edu/˜ers/cpp4m. Use math poem as the subject line of your message.

Chapter 2

Numbers

Numbers are the building blocks of mathematics and, of course, computers are extremely adept with numbers. There are several ways in which numbers are handled in C++. In this chapter, we explore the different representations of numbers and how to convert between representations. We also catalogue the various operations we can perform with numbers.

Numbers in C++ are divided into two broad categories: integers and reals. Each of these categories is refined further. Of course, to a mathematician every integer is a real number, so these categories may seem spurious. The reasons for having many different ways to represent numbers are efficiency and accuracy; if the quantities with which we are computing are known to be integral, then using an integer representation is not subject to roundoff error and the computations are faster.

2.1The integer types

Every variable in a C++ program must be given a type. The type of a variable is a specification of the kind of data the variable can store. The most basic type is int. An int represents an integer quantity. Consider the following program.

Program 2.1: Introducing the int type.

1 #include <iostream>

2using namespace std;

3

4 int main() {

5 int x;

6int y;

7

8 x = 3;

9y = 4;

10

11 cout << x+y << endl;

12

13return 0;

14}

11

12

C++ for Mathematicians

In this program, two variables, x and y, are declared to be of type int. These declarations occur on lines 5 and 6. C++ requires that we specify the type of every variable, and the declaration statement is the manner by which this is accomplished. Variables may be declared anywhere in the program so long as they are declared before they are used.

Subsequently (lines 8 and 9) the variables are assigned values. In this case x is assigned the value 3 and y the value 4. The equal sign = is an operation (called assignment) that stores the value of the expression to its right into the variable on its left.

It is possible to combine declarations on a single line; in place of lines 5 and 6, we could have this:

int x,y;

It is possible to combine declaration with assignment. Lines 5–9 can be replaced by these two:

int x = 3; int y = 4;

It’s easy to see what the rest of Program 2.1 does. In line 11, the contents of x and y are added, and the result is written on the computer’s screen.

Variables of type int can store a finite range of integer values. The size of that range depends on your specific computer. On many computers an int is held in 4 bytes of memory (one byte is 8 bits, so this is 32 bits). With 32 bits one can store 232 different values. In this case, the 232 values are from −231 to 231 −1 inclusive.

There is an easy way to learn the size of an int on your computer in C++ with the sizeof operator. Evaluating sizeof(int) gives the number of bytes used to store variables of type int. If an int on your computer is b bytes long, then the minimum and maximum values an int may hold are −2b−1 and 2b−1 − 1, respectively. See also Program 2.3 later in this chapter (page 15).

There are a few variations of the fundamental int type.

A short is an integer type that is either the same as int, or else a smaller size than int. That is, sizeof(short) cannot exceed sizeof(int).

A long is an integer type that is either the same size as int, or else a larger size than int. In other words, sizeof(long) is at least sizeof(int).

Some compilers provide a long long type. This is an integer type that is at least the size of a long. That is, sizeof(long long) cannot be less than sizeof(long).

Other compilers may provide an equivalent alternative. For example, in Microsoft’s Visual Studio, use the type int64 (the name begins with two underscore characters) in place of long long.

In summary,

sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long).

Numbers

13

Finally, each of the integer types can be modified for holding only nonnegative integers using the unsigned keyword. For example, a variable can be declared

unsigned int x;

In this case, x may take on only nonnegative values. If sizeof(unsigned int) is 4, then x can be any value from 0 to 232 −1 inclusive.

Because integer variables are of finite capacity, if a calculation exceeds the limits incorrect results emerge. Consider the following program that we run on a computer on which sizeof(int) equals 4. Please note the operation * in the code which is used for multiplication.

Program 2.2: A program to illustrate integer overflow.

1 #include <iostream>

2using namespace std;

3

4/**

5

* A program to illustrate what happens when large integers

6* are multiplied together.

7

*/

8

 

9int main() {

10int million = 1000000;

11int trillion = million * million;

12

13cout << "According to this computer, " << million << " squared is "

14<< trillion << "." << endl;

15}

Line 10 defines a variable million equal to 106. Because 231 is roughly 2 billion, there is no problem assigning x this value. However, when we define (line 11) y to be x*x, the result of squaring x is greater than 231. What happens? Let’s run theprogram and see.

According to this computer, 1000000 squared is -727379968.

The result is obviously wrong! Unfortunately, such errors are rarely so easy to detect. Here is some advice on how to handle this situation. First, know the sizeof of the various integer types on your machine (see Program 2.3 later in this chapter). Second, use long or long long routinely unless for reasons of speed or space you need to use a smaller size. Finally, if the long or long long type is not big enough for your calculations (and you need to keep the full precision) you can learn about arbitrary precision arithmetic packages (see Section 13.1).

14

C++ for Mathematicians

2.2 The real number types

C++ can handle more than integers. Real numbers are represented using floating point approximations. There are two principal types of floating point types: float and double. Both hold real values of limited precision. Variables of type float use less memory and have less precision than those of type double.

Some computers may have a long double type that has even greater precision

 

 

than double.

 

 

 

 

Unless you have special needs (for increased speed or decreased memory), use the

 

 

 

 

double type for all your real number calculations.

 

 

 

 

One may be tempted to use double for all numbers. For example, if we replace

 

 

 

 

int by double in Program 2.2, we have the following output.

 

 

 

 

 

 

 

 

 

 

 

 

According to this computer, 1e+06 squared is 1e+12.

 

 

 

 

 

 

 

 

 

Notice that the value of x is reported as 1e+06; this is simply scientific notation for

 

 

 

 

1 ×106. The value of y is 1e+12 and this is correct: 1012.

 

 

 

 

So why bother with the integer types at all? First, if the problem you are solving

 

 

 

 

deals with integers, using int or long is more efficient than float or double.

 

 

 

 

Second, the integer types are not subject to roundoff errors. Finally, there are certain

 

 

 

 

instances in which an integer type is required by C++ (e.g., when accessing elements

 

 

 

 

of an array).

 

 

2.3The bool and char types

There are other basic data types available in C++. Two that we encounter frequently in C++ are designed for handling Boolean and character data.

The data type bool is used to represent the logical values TRUE and FALSE. In C++, these are represented as integers: 1 for TRUE and 0 for FALSE. Indeed, bool is considered to be an integer type.

Boolean values emerge as the result of comparison operations. In C++, to see if two variables hold equal values we use the == operator. The result of x == y is either 1 (TRUE) in the case where x and y hold equal values and 0 (FALSE) otherwise. If your program contains the statement

cout << (x==y) << endl;

either a 0 or a 1 is typed on the screen.

Individual characters have the type char. One can create variables to hold single characters by declaring them to be of type char as in this example.

Numbers

15

char x; x = ’A’;

cout << x << endl;

This code causes the letter A to appear on the computer’s screen.

Notice that a single character is enclosed in single quotes. Arrays of characters are enclosed in double quotes. It is incorrect to write char x = "A"; because x is of type char whereas "A" is an array of elements of type char.

C++ has two principal ways of handling textual data: arrays of characters and objects of type string. We discuss these later (see Chapter 14). However, programs whose purpose is to solve mathematical problems rarely have much need for extensive processing of textual data.

2.4Checking the size and capacity of the different types

Earlier we mentioned the sizeof operator that is used to determine the number of bytes a given data type occupies in memory. The following program reports on the sizes of the various basic data types we have discussed.

Program 2.3: A program to show the sizes of the fundamental data types.

1 #include <iostream>

2using namespace std;

3

4/**

5* Report on the size of various C++ data types.

6*

7* This program may give different results when run on different

8* computers depending on how each of the fundamental data types is

9

* defined on those platforms.

10

*/

11

 

12int main() {

13// Integer types:

14cout << "The size of short is " << sizeof(short)

15<< " bytes" << endl;

16cout << "The size of int is " << sizeof(int)

17<< " bytes" << endl;

18cout << "The size of long is " << sizeof(long)

19<< " bytes" << endl;

20

21// long long might not exist on all computers

22cout << "The size of long long is " << sizeof(long long)

23<< " bytes" << endl;

24

25// Character and boolean types:

26cout << "The size of char is " << sizeof(char) << " bytes" << endl;

27cout << "The size of bool is " << sizeof(bool) << " bytes" << endl;