Functions help us to do this, and that is one of their most important features. They help us write programs in a top down manner, essentially be letting us write our program using a "wish-list" of functions that we can actually go back and implement later. An example should make this clearer.
There's a lot to this problem. However, imagine how much easier it would be to solve if the following functions were available:
double rate(double B);
This function would return the interest rate based on the account balance.
double compound(double r);
This function would give you the value of $1 after a
year's monthly compounding with annual interest rate r
.
If your blance is B
and your rate is r
at
the beginning of the year, the new balance is
B*compound(r)
.
double transaction(double B);
This function would do the interactive part for you, taking the
initial balance B
and returning the balance after the
transaction.
With this "wish list" of functions, we could write the program quite easily:
double B = 0.0;
for(int i = 0; i < 5; i++)
{
B = transaction(B);
double r = rate(B);
B = B*compound(r);
}
cout << B << endl;
This is a pretty easy program!
Of course, the 3 functions in our wish list do not exist, so we'll have to implement them for ourselves.
|
|
transaction
, I
don't need to worry about any other aspect of the program - it's like
transaction
is its own little (easy!) program to write.
Take a look at the complete program.
For example, suppose you wanted to define a function
max
that looked at two int
s and returned the
larger of the two. It's prototype would be
int max(int,int);
The definition would look like this:
int max(int a, int b)
{
if (a < b)
return b;
else
return a;
}
Note that this example shows you that you can return from
anywhere within a function (e.g., it returns b
in
the middle of the function definition, if a
is less than
b
), just like you can return from anywhere within
main
.
void rep(int,char);
The function function name rep
stands for repetition.
That is, it prints the char
argument to the screen the
number of times given by the int
.
Order of arguments.
It's important to note that the order of arguments is matters. For
example,
If I want to print a #
symbol 42 times, I need to be sure
to say rep(42,'#')
, because the function expects the
int
object first.
rep('#',42)
instead, do you know what'd happen?
A: I'd print *
, 35 times!
Why? Because the same kind of implicit type conversions that go on inside expressions go on with function arguments!
rep
function expects an int
as
its first argument, and when it gets '#'
instead, it
simply converts it to an int
, and the ASCII value
of '#'
is 35, so that's the int
you get.
char
is expected as the second
argument, and when rep
gets the number 42 instead, it
converts it to a character, and ASCII value 42 gives you the
char
'*'
.
Arguments' data type. When implicit conversions aren't possible, the compiler gives you an error message.
rep("#",42)
, what would
happen?
A: The compiler would give you an error saying:
rep
was supposed to be an
int
, but you gave it a string
, and there's
no way to convert the string
to an int
.
bool
are
traditionally referred to as predicates.
Imagine that you want to know whether an integer is a prime number or not.
We could write a function isprime
to do this.
The prototype would be as follows:
bool isprime(int);
We can define the function as follows:
bool isprime(int n)
{
if (i <= 1)
return false;
for (int i=2; i < n; i++)
{
if (n % i == 0 )
return false;
}
return true;
}
With the definition of this predicate, you can use the function as follows:
if( isprime(n) ) // isprime returns true or false
cout << n << " is a prime number!" << endl;
Really there's no need to bring predicates up as a special
subject, since functions that return bool
s are not
any more special than functions that return, say,
string
s. However, you might not have thought much
about the use of having such functions.