The goal is to learn about:

__ Predefined__ functions,

__Type casting__ using functions that convert
variable types,

Functions that __return a value__,

__Procedural abstraction__ and the importance
of argument ordering,

Scope of variables, and

Function Overloading

**Activity
4-1 - Preparations**

Before we begin this lab, please change your directory to 1440 and
in that directory, create the lab4 directory. Change to that directory
and complete all your lab work in that directory.

**Activity
4-2 - Predefined Functions**

A function is a subprogram that is included in a C++ program to perform
a particular task such as obtaining data, carrying out some calculations,
displaying some information or messages, and displaying the output data.
In C++, there are many predefined functions that are written to simplify
the computations. Following is an example in which a predefined function
is used. This program is the same as the program given in the first
question in your prelab assignment. You were supposed to modify the
program to compute 2^{4}, 3^{3},
5^{4}, and 4^{5} and display the results.

// P40.C This C++ program computes the value of
3^4.

#include<iostream.h>

int main(void)

{

int i = 0, p
= 1;

int x = 3, y =
4;

while(i < 4)

{

p = p * x;

i++;

}

cout <<
x << " to the power of " << y << " is = " << p
<< endl;

return 0;

}

The heart of this program is the part in red font.
**Exercise 4.1**

In the above program, P40.C, all variables are
declared as int. Could you modify this code to work for real values.
Thus, could you make changes such that it would compute something like
3.5^{4.8}. Write your answer in a file called ex41 in the
lab4 directory.

There is a predefined function in C++ that does
this computation. The function is called *pow*. This function
will take two numbers and will compute one to the power of the other.
For example, in the above program we want to compute 3^{4}, we
can use p = pow(3,4) to compute it. Thus, the above code can be simplified
as:

// P40a.C - This C++ program computes the value
of 3^4 using the pow function.

#include<iostream.h>

#include<math.h>

int main(void)

{

int i = 0;

int x = 3, y =
4;

cout << x << " to the power of " << y << " is = " << pow(x, y) << endl;

return 0;

}

Notice that we have included the math.h directive
to be able to use the *pow* function. Now that you learn about
this function, you can complete the program to compute the rest of the
values.

**Exercise 4.2**

Modify program P40a.C to compute 3.5^{4.8
}and to display the answer. Call your new program ex42.C and
save it under the lab4 directory.

// P41.C This
program computes the 3^4, 2^4, 3^3, 5^4, and 4^5 and displays the results.

#include<iostream.h>

#include<math.h>

int main(void)

{

cout << "3 to
the power of 4 is " << pow(3,4)
<< endl;

cout << "2 to
the power of 4 is " << pow(2,4)
<< endl;

cout << "3 to
the power of 3 is " << pow(3,3)
<< endl;

cout << "4 to
the power of 5 is " << pow(4,5)
<< endl;

return 0;

}

We also could include a *while loop* in this
program to simplify the computation and make the program much better.

// P42.C This
program computes the x^y.

#include<iostream.h>

#include<math.h>

int main(void)

{

int choice = 1;

int x, y;

while(choice ==
1)

{

cout << "Enter the x and y separated by a space, and I will compute
x^y ";

cin >> x >> y;

cout << endl;

cout << x << " to the power of " << y <<
" is = " << pow(x,y)
<< endl;

cout << "\nDo you wish to compute another case, enter 1 to continue,
0 to end: ";

cin >> choice;

}

return 0;

}

There are more predefined functions, here we will
discuss few more. As you may remember in lab2, you were asked to
look into the quadratic equation. The solution to a quadratic equation,
AX^{2} + BX + C = 0, is:

The solutions were discussed in lab2. Here, we only mention that before you could compute these two roots, you had to make sure that the value under the radical was not negative. Another version of the program introduced in lab2 for computing the roots can be written as:

// P43.C This program
solves the quadratic equation, AX^2 + BX + C = 0

#include <iostream.h>

#include <math.h>

int main()

{

double A,B,C,D;

cout << "Enter A,
B, C (without the commas): ";

cin >> A >> B >> C;

D = pow(B,2)
- 4*A*C;

if(D>0)

cout << "The solutions are " << (-B+sqrt(D))/(2*A) <<
", "

<< (-B-sqrt(D))/(2*A) << endl;

else if(D==0)

cout << "The solution is " << -B/(2*A) << endl;

else

cout << "There are no real solutions\n";

return 0;

}

In the above program you used the predefined *sqrt
*function to compute the square root of B^2 - 4AC. For
a more complete list of predefined functions, please see the Display 3.2
given in the text.

**Exercise 4.3**

Modify program P43.C such that is also displays
the solution to the quadratic equation when A = 0. Thus, when A =
0, it displays the value of -C/B as the answer. Call your new program
ex43.C and save it under the lab4 directory.

**Exercise 4.4**

Modify program P43.C such that is keeps asking
for a new set of A, B, and C and computes the root(s) until the user decided
to terminate the program by entering a negative value for the choice.
Call your new program ex44.C and save it under the lab4 directory.

** Activity
4-3 - Round up and Round down Functions**

Sometime in your calculations you may want to round your results up
and/or down. There are two predefined functions that are used for
this purpose. The function *ceil* will round up a given real
number to its next whole number and function *floor *will round down
a given real number to its lower whole number. Examples:

if x = 34.3 then y = ceil(x) is 35.0

if x = 34.3 then y = floor is 34.0

**Exercise 4.5**

Write a C++ program, ex45.C, to compute the ceil
and floor of any input value. Then compute the ceil and floor of
-34.5 ?

We also have two functions that are used to take
the absolute value of an integer or a real value. The first one is
called *abs *that is used to compute the absolute value of an integer.
Example: x = -4, then y = abs(x) will be 4. The other function
is *fabs* that computes the absolute value of a float or double type
number. Example: x = -3.43, then y = fabs(x) will be 3.43.

** Activity
4-4 -Type Changing Functions - Type Casting**

In problem 3 of the prelab, you were asked to determine a possible
source of error in the given program. Perhaps, you have found that
dividing two integers will not always result in the correct answer.
For example, that program produces 0 when you divide 2 by 4 as integers.
There is a way to fix this problem using predefined functions. The
*type
changing functions* allows us to change the type of a variable at the
line that is used. For example, in the code given in problem 3, one can
change the variable type of the numerator (type cast) to float, so the
division will become a float divided by an integer.

#include<iostream.h>

int main(void)

{

int x,y;

cout <<
"Enter 2 values for x and y separated by space, then press <Enter> :";

cin >> x >> y;

cout <<
endl;

cout << x << "/" << y << " = " <<float(x)/y << endl;

return 0;

}

The change is shown in red font for clarity. Note that variable x will stay an integer regardless of the float(x)/y statement. Type casting will not change the type for x, instead float(x) will be the float type value with the same value as x that will be used in the division.

** Activity
4-5 - Functions that return a value**

We can write our own functions to perform some computations.
The following program from your text will compute the total cost of purchases
made in a store. In this program, we will use a function that computes
the cost plus 5% sales tax of purchases made.

// P44.C This program computes the total
cost of purchases made,

//including 5% sales tax, on number_par items at a cost of price_par
each.

#include <iostream>

double total_cost(int number_par, double price_par); // (1) Function prototype

int main( )

{

double price, bill;

int number;

cout << "Enter the
number of items purchased: ";

cin >> number;

cout << "Enter the
price per item $";

cin >> price;

bill = total_cost(number, price); // (2) Function call

// The
following three lines are used for formatting purpose. Since a precision
of 2

//
is set, then all numbers will be displayed with two decimal points.
We work with $

//
that is the way it should be.

cout.setf(ios::fixed);

cout.setf(ios::showpoint);

cout.precision(2);

cout << number <<
" items at "

<< "$" << price << " each.\n"

<< "Final bill, including tax, is $" << bill

<< endl;

return 0;

}

// (3) Function definition

double total_cost(int
number_par, double price_par) // Function heading
**{ **// Function body begins here

const
double TAX_RATE = 0.05; //5% sales tax

double
subtotal;

subtotal
= price_par * number_par;

return
(subtotal
+ subtotal*TAX_RATE);

}// Function body ends here

As you can see, we have used a function called *total_cost* to
compute the cost + 5% tax. Note that this function has computed the
total cost and has returned a __single__ value at return
(subtotal
+ subtotal*TAX_RATE);
The
returned value is of type double.

**Remarks**

There are 3 things that you must remember when
you work with functions.

1) A function must have a name,
in the above program name was total_cost

2) A function must have a
type, the type for the above function is double

3) A function must have correct
parameter definitions. This means that the parameters, if any, must
have type consistency and correct ordering at the a) function prototype,
b) function call, and c) function definition.

Violation of any of these three will result in syntax or logical errors.

Please note that the function used in the above
program is of type double. Thus, it returns a value of type double
and in the main function, that value was received by a variable of type
double at:

bill = total_cost(number, price);

where bill is defined as double in the main function.

**Procedural
Abstraction and Parameter Ordering**

A function must be written like a black box. The user does not
need to have any knowledge of the details in the body of the function.
He/she should be able to determine what the function will do by looking
at the function prototype and provide the correct input values with correct
types to obtain the correct result from a function.

A function may have several parameters of different types. It is critical that the parameters passed to a function have the same order at a) the function prototype, b) the function call, and c) the function definition. Violation of the correct ordering may result in a) syntax error or b) logical error. It is very hard to find the error when the ordering is incorrect. So if you get an error when you are using a function, the first thing you may want to check is the type and ordering constancy in all instances of the function.

**Scope of
a variable**

The scope of a variable declared inside a function is the body of that
function. For example, in the above program variable *bill *declared
inside the body of the main function. Thus, *bill* is unknown
in the total_cost function. If we attempt to use *bill* without
declaring it in the function total_cost, we will get a syntax error that
bill is undeclared. Similarly, variable *subtotal *is unknown
to the main function, because it is a variable defined in the total_cost
function and its scope is the body of the total_cost function only.
These types of variables are referred to as **local variables**.
They are local to the function in which they are declared. There
are, however, a method to define a variable such that it is known to all
functions. This type of variables are defined at the top of the program
right after the include directives. Any variable defined this way
is known as **global variable**.

The parameters passed to a function are also local to the function within
which they are defined. Thus, a parameter that may go through changes
inside a function that is called by another, will assume its original value
upon the completion of the called function. This is referred to as **call_by_value**.
The following example will help you understand all these definitions.

// P45.C This program
illustrates the local and global variables and call-by-value.

// This program computes the side area and the cross section area of
a cylinder

#include<iostream.h>

#include<math.h>

double PI = 3.14159; // This variable is defined globally, known to all functions in this program as PI

double Cross_area(double r); // Function prototype for function
Cross_area

double Side_area(double r, double h); // Function prototype for
function Side_area

int main(void)

{

double h, r;

cout << "Enter the radios and the
height of the cylinder in Cm <Enter> ";

cin >> r >> h;

cout << endl;

cout << "Before I do any computation
or call any function, I want to let you know that \n";

cout << "you have entered r =
" << r << " and h = " << h << endl;

cout << "The cross section area
of the cylinder is " << Cross_area(r) << endl;

cout << "The side area of the
cylinder is " << Side_area(r,h) << "\n\n";

cout << "By the way, I am r and
my value is " << r << endl;

cout << "My value is reset to
whatever it was in the main before you called the function, \n";

cout << "this is because, you
send me there as call_by_value \n";

return 0;

}

double Cross_area(double r)

{

return PI*pow(r,2);

}

double Side_area(double r, double h)

{

double area;

area = 2*PI*r*h;

r = r * 1000; // just to show
what will happen to r

return area;

}

In the above program, r and h are declared in the main function and
are local to that function. These two have been passed to the function
Side_area with the same names but they are still local to both functions
regardless their names. But, PI is defined globally and will be known to
all the functions as PI. If by any chance the value for PI changes
in one of these functions, every function which is using PI will use it
with its new value. That is why it is a good practice to define a constant
that is defined globally using *const* so its value is unchangeable.
For example, PI should be defined as: conts
double PI = 3.14159;

** Activity
4-6 - Function Overloading**

In the above program, we have used two different function names to
distinguish between the function that computes the cross area and the one
that computes the side area. Using **overloading** we can give
both function with the same name. The selection will be made based
on their prototypes. Here is the new version of the same program
written using overloading.

// P46.C This program
illustrates the local and global variables and call-by-value.

// This program computes the side area and the cross section area of
a cylinder

#include<iostream.h>

#include<math.h>

const double PI = 3.14159; // This variable is defined as a constant globally

double Area(double r); // Function
prototype for function that computes the cross section

double Area(double r, double h);
// Function prototype for function that computes the side area

int main(void)

{

double h, r;

cout << "Enter the radios and the
height of the cylinder in Cm <Enter> ";

cin >> r >> h;

cout << endl;

cout << "Before I do any computation
or call any function, I want to let you know that \n";

cout << "you have entered r =
" << r << " and h = " << h << endl;

cout << "The cross section area
of the cylinder is " << Area(r) <<
endl;

cout << "The side area of the
cylinder is " << Area(r,h) <<
"\n\n";

cout << "By the way, I am r and
my value is " << r << endl;

cout << "My value was changed
in the 2nd Area function, \n";

cout << "but it is reset to whatever
it was before you call that function.\n";

cout << "This is because, you
send me to that function using call_by_value. \n";

return 0;

}

double Area(double r)

// Computes the cross sectional area of the cylinder

{

return PI*pow(r,2);

}

double Area(double r, double h)

// Computes the side area of the cylinder

{

double area;

area = 2*PI*r*h;

r = r * 1000; // just to show
what will happen to r

return area;

}

**Exercise 4.6**

Could you use overloading to compute the area
and volume of an sphere with two functions that have the same name? Explain
your answer. Write your answer in a file called ex46 and save it
in your lab4 directory.

**Exercise 4.7**

Modify program P46.C to compute the side area,
total area, and volume of a cylinder and the area and volume of a sphere, depending on the choice that user makes. Your program should ask users
to decide whether the shape is an sphere or a cylinder, then display the
result for the selected shape. Here is the definitions you may need
for a cylinder with radius r, and height h:

Side area: (2*PI*r) * h

Total Area: 2*(PI*r^{2})
+ Side area

Volume: (PI*r^{2})*h

Call your new program Ex47.C and save it under the lab4 directory.

**Post Lab
Exercise**

Modify program **P44.C** to compute the total cost of the purchases
differently. This time if the price per item is more than $20, a
special discount will be applied. The special discount varies depending
on the day of the week or the occasion, so you have to ask for
the special rate of discount at the time of purchase. For now, you
ask the user to enter a rate between 5-20%. For items with price
per item of less than $20, use the same calculations as before. __You
need to use function overloading in your new program.__