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;
}
This is a tremendous improvement! Unfortunately, such a function is not a part of any of the standard libraries. Therefore, it's up to us to make it!
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):
cos takes an object of type double (that's
the x).
double.
cos("Hello") is not going to make sense, since
"Hello" has type string, not type
double.
Similarly, something like
if( cos(3*z) && k < 0 )isn't going to make sense, since the && operator expects an object of type
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();
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.
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.
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 animated 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 the right:
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
int main() {
int y = 4;
cout << factorial(y) << endl;
cout << y << endl;
return 0;
}
The result would be
24 4Although 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.
Remember also that scoping rules show us that any variable named
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 << "This is a little demo program." << endl;
cout << "I hope you enjoy it." << endl;
}
This function is only used for the side effect of writing something on the
screen, not for any value it would return.