sqrt and cos that do all sorts of
nice things for us. If only there were a function
getposint that would get a positive int from the
user and return it to our program, we could rewrite our
program as:
int main()
{
int a = getposint(), b = getposint();
// Compute gcd
while(b != 0)
{
int r = a % b;
a = b;
b = r;
}
// Write out gcd
cout << "The gcd is " << a << endl;
return 0;
}
|
cmath library that they give a description of the
function like:
double cos(double x);This is called a prototype. It tells you (and it tells the compiler) that
cos takes an object of
type double
(that's the x) and returns or evaluates to an object
of type double. It doesn't tell you how or what it's
doing, but it does tell you that something like
cos("Brown")
is not going to make sense, since "Brown" has type
string, not type double. Similarly,
something like
if (cos(3*z) && k < 0)
cos(45)/2What happens here? Either we'll do int division and the answer will be zero, or we'll do double division and we'll get some answer in the range [-0.5,0.5]. So which is it? Well, evaluating
cos(45) results in a double, so
as in any operation in which int's and double's are mixed, the
int is promoted to a double and we get double division and a
double result.
bool and the cos(3*z) evaluates
to an object of type double. When you define
functions of your own, you need to define a prototype as well. It
must be defined outside of the main block, and it
must appear before you ever use the function. Now, in the
getposint function we'd envisioned earlier, there's
nothing that the function takes as input from the program, and it
should evaluate to or return the positive integer it's read in
from the user, so the right prototype would be:
int getposint();
return statement in main
leaves the program, a return statement in your
function body leaves the function. Instead of
returning 0 however, we'll return whatever value the
function's supposed to give. So our getposint
function will have the following definition:
int getposint()
{
int k;
cout << "Enter a positive integer: ";
cin >> k;
while(k <= 0)
{
cout << "I said *positive*, try again: ";
cin >> k;
}
return k;
}
The function definition also has to appear outside of the
main block. This program
gives a complete picture of how to rewrite our GCD calculator to
make use of a getposint function.
int f();
int main()
{
int a, b;
a = 0;
b = f();
cout << "a = " << a << endl;
return 0;
}
|
int f()
{
int a = 2;
return -1;
}
|
a just got assigned that value. On the other hand,
the function f is called in between, and there I
see a being given the value 2. So which is it?
The answer is that "0" gets printed out. It all goes back to
scope. The a in main does
not exist outside of main, and likewise the
a in the function f does
not exist outside of f. These variables are two
different objects that happen to have the same name. Since they
are in different scopes, however, there is no confusion or
conflict. We say that variables like this are local to
the functions in which they are defined, i.e. they don't exist
outside of the functions in which they are defined.
The way that you want to think of this is that each function
call is like a piece of paper with boxes for each of the
function's local variable. When a function is called a new
piece of paper is stacked on the others. The computer only
actually works on the function call represented by the top
paper on the stack. This image helps you think about
how variable scope works with function calls.
In the case of calling the function f() in
evaluating b = f(), you should be thinking of
this ...
pow or sqrt functions from
cmath to do the factorial for us. First, we need a
prototype that specifies that our function (we'll call it
factorial) takes an integer value and returns an
integer value:
int factorial(int);From this point on in our program we can use the
factorial function. However, somewhere along the way
we'll actually have to define the function --- something
like this:
int factorial(int x)
{
int f = 1;
while (x > 0)
{
f = f*x;
x--;
}
return f;
}
Notice that here we give a name to the int value that
gets passed into the function, so that we can reference it within
the body of the function definition. Values that get passed in to
a function in C++ are called function arguments. It's
important to note that the arguments are passed by value,
meaning that you get a copy of the value of the variable
function is called with, not the variable itself.
So, for example, if our main function looked like
main()
{
int y = 4;
cout << factorial(y) << endl;
cout << y << endl;
return 0;
}
The result would be 24 followed by 4. Although the argument
x in the function definition does get modified, the
variable y does not, because y's value
(i.e. 4) got passed to factorial, not the variable
y itself. So pass by value means that a
copy of the object appearing in the function call is what gets
passed along to the function, not the object itself.
x or f in main have no
relation to the x and f in the
factorial function. To reiterate, pass-by-value
means that you get a copy of the argument. By analogy, calling
the "haircut function" with argument "MIDN Jones" would 1) cause a
clone to be made of MIDN Jones, 2) cause the clone's hair to get
cut, and 3) cause the clone to get destroyed after the haircut.
Thus, when MIDN Jones showed up in class the next day, his hair
would still be shaggy.
void in place of a return type. Here's a stupid
example:
void printgreetings();
int main()
{
printgreetings();
return 0;
}
void printgreetings()
{
cout << "G R E E T I N G S !" << endl << endl;
cout << "I am Dr. Brown, and this is my little demo" << endl
<< "program. I hope you enjoy it. If there" << end;
<< "are questions please hesitate to ask." << endl;
}
This function is only used for the side effect of writing
something on the screen, not for any value it would return.