C++ comes with libraries of predefined functions that you can use in your programs. Before we show you how to define functions, we will first show you how to use some functions that are already defined for you.
We will use the sqrt
function to illustrate how you use predefined functions. The sqrt
function calculates the square root of a number. (The square root of a number is the number that, when multiplied by itself, will produce the number you started out with. For example, the square root of 9 is 3 because 32 is equal to 9.) The function sqrt
starts with a number, such as 9.0, and computes its square root, in this case 3.0. The value the function starts out with is called its argument. The value it computes is called the value returned. Some functions may have more than one argument, but no function has more than one value returned. If you think of the function as being similar to a small program, then the arguments are analogous to the input and the value returned is analogous to the output.
The syntax for using functions in your program is simple. To set a variable named theRoot
equal to the square root of 9.0
, you can use the following assignment statement:
theRoot = sqrt(9.0);
The expression sqrt(9.0)
is called a function call (or if you want to be fancy you can also call it a function invocation). An argument in a function call can be a constant, such as 9.0
, or a variable, or a more complicated expression. A function call is an expression that can be used like any other expression. You can use a function call wherever it is legal to use an expression of the type specified for the value returned by the function. For example, the value returned by sqrt
is of type double
. Thus, the following is legal (although perhaps stingy):
bonus = sqrt(sales)/10;
sales
and bonus
are variables that would normally be of type double
. The function call sqrt(sales)
is a single item, just as if it were enclosed in parentheses. Thus, this assignment statement is equivalent to
bonus = (sqrt(sales))/10;
You can also use a function call directly in a cout
statement, as in the following:
cout << "The side of a square with area " << area
<< " is " << sqrt(area);
Display 4.1 contains a complete program that uses the predefined function sqrt
. The program computes the size of the largest square dog house that can be built for the amount of money the user is willing to spend. The program asks the user for an amount of money and then determines how many square feet of floor space can be purchased for that amount of money. That calculation yields an area in square feet for the floor area of the dog house. The function sqrt
yields the length of one side of the dog house floor.
Notice that there is another new element in the program in Display 4.1:
#include <cmath>
That line looks very much like the line
#include <iostream>
and, in fact, these two lines are the same sort of thing. As we noted in Chapter 2, such lines are called include
directives. The name inside the angular brackets <>
is the name of a file known as a header file. A header file for a library provides the compiler with certain basic information about the library, and an include
directive delivers this information to the compiler. This enables the linker to find object code for the functions in the library so that it can correctly link the library to your program. For example, the library iostream contains the definitions of cin
and cout
, and the header file for the iostream library is called iostream
. The math library contains the definition of the function sqrt
and a number of other mathematical functions, and the header file for this library is cmath
. If your program uses a predefined function from some library, then it must contain a directive that names the header file for that library, such as the following:
#include <cmath>
Be sure to follow the syntax illustrated in our examples. Do not forget the symbols <
and >
; they are the same symbols as the less-than and greater-than symbols. There should be no space between the <
and the filename, nor between the filename and the >
. Also, some compilers require that directives have no spaces around the #
, so it is always safest to place the #
at the very start of the line and not to put any space between the #
and the word include
. These #include
directives are normally placed at the beginning of the file containing your program.
As we noted before, the directive
#include <iostream>
requires that you also use the following using
directive:
using namespace std;
This is because the definitions of names like cin
and cout
, which are given in iostream
, define those names to be part of the std
namespace. This is true of most standard libraries. If you have an include
directive for a standard library such as
#include <cmath>
then you probably need the using
directive:
using namespace std;
There is no need to use multiple copies of this using
directive when you have multiple include
directives.
Usually, all you need to do to use a library is to place an include
directive and a using
directive for that library in the file with your program. If things work with just the include
directive and the using
directive, you need not worry about doing anything else. However, for some libraries on some systems, you may need to give additional instructions to the compiler or to explicitly run a linker program to link in the library. Early C and C++ compilers did not automatically search all libraries for linking. The details vary from one system to another, so you will have to check your manual or a local expert to see exactly what is necessary.
Some people will tell you that include
directives are not processed by the compiler, but are processed by a preprocessor. They’re right, but the difference is more of a word game than anything that need concern you. On almost all compilers the preprocessor is called automatically when you compile your program.
A few predefined functions are described in Display 4.2; more predefined functions are described in Appendix 4. Notice that the absolute value functions abs
and labs
are in the library with header file cstdlib
, so any program that uses either of these functions must contain the following directive:
#include <cstdlib>
All the other functions listed are in the library with header file cmath
, just like sqrt
.
Name |
Description |
Type of Arguments |
Type of Value Returned |
Example |
Value |
Library Header |
---|---|---|---|---|---|---|
sqrt |
square root |
double |
double |
sqrt(4.0) |
2.0 |
cmath |
pow |
powers |
double |
double |
pow(2.0,3.0) |
8.0 |
cmath |
abs |
absolute value for int |
int |
int |
|
|
cstdlib |
labs |
absolute value for long |
long |
long |
|
|
cstdlib |
fabs |
absolute value for double |
double |
double |
|
|
cmath |
ceil |
ceiling (round up) |
double |
double |
|
|
cmath |
floor |
floor (round down) |
double |
double |
|
|
cmath |
srand |
Seed random number generator |
none |
none |
srand() |
none |
cstdlib |
rand |
Random number |
none |
int |
rand() |
0-RAND _MAX |
cstdlib |
Also notice that there are three absolute value functions. If you want to produce the absolute value of a number of type int
, you use abs
; if you want to produce the absolute value of a number of type long
, you use labs
; and if you want to produce the absolute value of a number of type double
, you use fabs
. To complicate things even more, abs
and labs
are in the library with header file cstdlib
, while fabs
is in the library with header file cmath
. fabs
is an abbreviation for floating-point absolute value. Recall that numbers with a fraction after the decimal point, such as numbers of type double
, are often called floating-point numbers.
Another example of a predefined function is pow
, which is in the library with header file cmath
. The function pow
can be used to do exponentiation in C++. For example, if you want to set a variable result
equal to x
y, you can use the following:
result = pow(x, y);
Hence, the following three lines of program code will output the number 9.0
to the screen, because (3.0)2.0
is 9.0
:
double result, x = 3.0, y = 2.0;
result = pow(x, y);
cout << result;
Notice that the above call to pow
returns 9.0
, not 9
. The function pow
always returns a value of type double
, not of type int
. Also notice that the function pow
requires two arguments. A function can have any number of arguments. Moreover, every argument position has a specified type and the argument used in a function call should be of that type. In many cases, if you use an argument of the wrong type, then some automatic type conversion will be done for you by C++. However, the results may not be what you intended. When you call a function, you should use arguments of the type specified for that function. One exception to this caution is the automatic conversion of arguments from type int
to type double
. In many situations, including calls to the function pow
, you can safely use an argument of type int
when an argument of type double
is specified.
Many implementations of pow
have a restriction on what arguments can be used. In these implementations, if the first argument to pow
is negative, then the second argument must be a whole number. Since you probably have enough other things to worry about when learning to program, it might be easiest and safest to use pow
only when the first argument is nonnegative.
Games and simulation programs often require the generation of random numbers. C++ has a predefined function to generate pseudorandom numbers. A pseudorandom number is one that appears to be random but is really determined by a predictable formula. For example, here is the formula for a very simple pseudorandom number generator that specifies the i
th random number Ri
based on the previously generated random number Ri-1:
Ri = (Ri−1 × 7) % 11
Let’s set the initial “seed,” R0 = 1. The first time we fetch a “random” number we compute R1 with the formula:
R1 = (R0 × 7) % 11 = (1 × 7) % 11 = 7 % 11 = 7
The second time we fetch a “random” number we compute R2 with:
R2 = (R1 × 7) % 11 = (7 × 7) % 11 = 49 % 11 = 5
The third time we fetch a “random” number we compute R3 with:
R3 = (R2 × 7) % 11 = (5 × 7) % 11 = 35 % 11 = 2
and so on.
As you can see, each successive value seems random unless we know the formula. This is why they are called pseudorandom. This particular function would not be a very good pseudorandom number generator because it would repeat numbers rather quickly. The random number generator in C++ varies depending upon the library implementation but uses the same basic idea as our simple generator with some enhancements to achieve a random uniform distribution.
We can get a different sequence of random numbers if we start with a different seed value. In the example, the seed always started at 1. However, if the seed is initialized with a number that changes, such as the time on the computer’s clock, then we will likely get a different sequence of random numbers every time we run the program.
To seed C++’s random number generator use the predefined method srand
. It returns no value and takes as input an unsigned integer that is the initial seed value. To always seed the random number generator with the value 35, we would use:
srand(35);
To vary the random number sequence every time the program is executed, we can seed the random number generator with the time of day. Invoking the predefined function time(0)
returns the number of seconds that have elapsed since January 1, 19701 on most systems. The time
function requires you to include the ctime
library.
#include <cstdlib>
#include <ctime>
...
srand(time(0));
We can get a random number by calling the function rand
, which will return an integer in the range 0 to RAND_MAX
. RAND_MAX
is a constant defined in cstdlib
and is guaranteed to be 32767 or higher. Usually, a number between 0 and RAND_MAX
is not what is desired, in which case the random number can be scaled by modulus and addition. For example, to simulate rolling a six-sided die we could use the following:
int die = (rand() % 6) + 1;
The random number modulo 6 gives us a number between 0 and 5. Adding 1 results in a random integer that is in the range from 1 to 6.
It is important to seed the random number generator only once. A common error is to invoke srand
every time a random number is generated. If both srand
and rand
are placed in a loop, then the likely result is a sequence of identical numbers, because the computer runs quickly enough that the time value will probably not change for repeated calls to srand
.
Recall that 9/2
is integer division and evaluates to 4
, not 4.5
. If you want division to produce an answer of type double
(that is, including the fractional part after the decimal point), then at least one of the two numbers in the division must be of type double
. For example, 9/2.0
evaluates to 4.5
. If one of the two numbers is given as a constant, you can simply add a decimal point and a zero to one (or both) numbers, and the division will then produce a value that includes the digits after the decimal point.
But what if both of the operands in a division are variables, as in the following?
int totalCandy, numberOfPeople;
double candyPerPerson;
<The program somehow sets the value of totalCandy to 9
and the value of numberOfPeople to 2.
It does not matter how the program does this.>
candyPerPerson = totalCandy/numberOfPeople;
Unless you convert the value in one of the variables totalCandy
or number OfPeople
to a value of type double
, then the result of the division will be 4
, not 4.5
as it should be. The fact that the variable candyPerPerson
is of type double
does not help. The value of 4
obtained by division will be converted to a value of type double
before it is stored in the variable candyPerPerson
, but that will be too late. The 4
will be converted to 4.0
and the final value of candyPerPerson
will be 4.0
, not 4.5
. If one of the quantities in the division were a constant, you could add a decimal point and a zero to convert the constant to type double
, but in this case both quantities are variables. Fortunately, there is a way to convert from type int
to type double
that you can use with either a constant or a variable.
In C++ you can tell the computer to convert a value of type int
to a value of type double
. The way that you write “Convert the value 9
to a value of type double
” is
static_cast<double>(9)
The notation static_cast<double>
is a kind of predefined function that converts a value of some other type, such as 9
, to a value of type double
, in this case 9.0
. An expression such as static_cast<double>(9)
is called a type cast. You can use a variable or other expression in place of the 9
. You can use other type names besides double
to obtain a type cast to some type other than double
, but we will postpone that topic until later.
For example, in the following we use a type cast to change the type of 9
from int
to double
and so the value of answer
is set to 4.5
:
double answer;
answer = static_cast<double>(9)/2;
Type casting applied to a constant, such as 9
, can make your code easier to read, since it makes your intended meaning clearer. But type casting applied to constants of type int
does not give you any additional power. You can use 9.0
instead of static_cast<double>(9)
when you want to convert 9
to a value of type double
. However, if the division involves only variables, then type casting may be your only sensible alternative. Using type casting, we can rewrite our earlier example so that the variable candyPerPerson
receives the correct value of 4.5
, instead of 4.0
; in order to do this, the only change we need is the replacement of totalCandy
with static_cast<double>(total Candy)
, as shown in what follows:
int totalCandy, numberOfPeople;
double candyPerPerson;
<The program somehow sets the value of totalCandy to 9
and the value of numberOfPeople to 2.
It does not matter how the program does this.>
candyPerPerson =
static_cast<double>(totalCandy)/numberOfPeople;
Notice the placement of parentheses in the type casting used in the code. You want to do the type casting before the division so that the division operator is working on a value of type double
. If you wait until after the division is completed, then the digits after the decimal point are already lost. If you mistakenly use the following for the last line of the previous code, then the value of candyPerPerson
will be 4.0
, not 4.5
.
candyPerPerson =
static_cast<double>(totalCandy/numberOfPeople); //WRONG!
The use of static_cast<double>
, as we discussed in the previous section, is the preferred way to perform a type cast. However, older versions of C++ used a different notation for type casting. This older notation simply uses the type name as if it were a function name, so double(9)
returns 9.0
. Thus, if candyPerPerson
is a variable of type double
, and if both totalCandy
and numberOfPeople
are variables of type int
, then the following two assignment statements are equivalent:
candyPerPerson =
static_cast<double>(totalCandy)/numberOfPeople;
and
candyPerPerson =
double(totalCandy)/numberOfPeople;
Although static_cast<
double>(totalCandy)
and double(totalCandy)
are more or less equivalent, you should use the static_cast<double>
form, since the form double(totalCandy)
may be discontinued in later versions of C++.
Determine the value of each of the following arithmetic expressions:
sqrt(16.0) |
sqrt(16) |
pow(2.0, 3.0) |
pow(2, 3) |
pow(2.0, 3) |
pow(1.1, 2) |
abs(3) |
abs(−3) |
abs(0) |
fabs(−3.0) |
fabs(−3.5) |
fabs(3.5) |
ceil(5.1) |
ceil(5.8) |
floor(5.1) |
floor(5.8) |
pow(3.0, 2)/2.0 |
pow(3.0, 2)/2 |
7/abs(−2) |
(7 + sqrt(4.0))/3.0 |
sqrt(pow(3, 2)) |
Convert each of the following mathematical expressions to a C++ arithmetic expression:
Write a complete C++ program to compute and output the square root of PI
; PI
is approximately 3.14159. The const double PI
is predefined in cmath
. You are encouraged to use this predefined constant.
Write and compile short programs to test the following issues:
Determine whether your compiler will allow the #include <iostream>
anywhere on the line, or if the #
needs to be flush with the left margin.
Determine whether your compiler will allow space between the #
and the include
.