Global Variables and Constants
Several functions may need to use a constant. If so, it makes sense
to declare the constant as a global constant. You do
this by declaring it outside of the scope of any function, including the
main function (i.e. usually global declarations are placed
between #include
directives and function prototypes). Although this is allowed in C++ we will not use globals. Note: We will not use global variables in this
class (see the rules link at the Programming Assignments page). Local Variables Examine the following program: #include <iostream.h> Note the following: e.g: Consider the factorial function: n! = n*n-1*n-2*...*2*1. The implementation
below illustrates local variables. Note that the changes to n in the function don't change anything in the
function calling factorial #include <iostream.h> Overloading Function Names C++ allows you to give two or more different function definitions to the
same function name. In fact, we've already seen examples of this. e.g: Arithmetic operators are defined on all of the number types,
that is, long, int, float, double
and long double. As it turns out,
arithmetic operators are actually functions and so, to accomplish
this, for each type, there is a separate function definition
for each operator. Let us say, we want to write a function to average two numbers: double average(double n1, double n2) and we might also need a function to average three numbers: double average3(double n1, double n2, double n3) We can give this second function the same
name, average, and at that point we
have overloaded the function name average.
We still need a function prototype for each function definition even though
they have the same name. #include <iostream.h> The compiler checks the number and type of arguments in
the invocation and uses the definition that matches the invocation. When overloading a function ensure that one of the following holds: Note. You cannot have two function definitions with the same number
of arguments of the same type. This is true even if the functions differ in
the type of the returned value. e.g: The following are illegal: int dbl_func (double n1, double n2); double dbl_func (double num1, double num2); We really must be careful about the types that we give functions. If
two definitions exist for a function and we accidentally give the wrong type
for the arguments, the compiler may pick the wrong definition. Note: For an example, see page 154. All functions seen so far take at least one argument and return exactly one
value. We sometimes need functions that: C++ allows us to easily accomplish the first need. The mechanism provided
is the void function. We cannot directly accomplish the second need. However, C++ provides a
mechanism to indirectly do this. The mechanism is known as call-by-reference. Return no value A function that returns no values is called a void-function. Definitions
of void-functions in C++ void-functions are defined in a way that is very similar
to functions that return a value. e.g: Consider the function that outputs a temperature in Celsius and
its equivalent value in Fahrenheit. void output_temps(double c_degrees, double f_degrees)
void
functions vs. normal functions:
Note: The prototype for such a function is like that for any other
function. A call to a void function is an executable statement like any other.
Such functions do not evaluate to a value and so to invoke them we write them
as a statement by themselves. Functions with no arguments It's perfectly legal and sometimes very useful to have functions that
do not take any arguments. For example, we might want to have a function that
simply writes a few lines of text to the screen before we produce new
output void initialize_screen () return
statements in void-functions
Note: Although the above program used a return statement for the
void function, void functions don't actually need
a
return
statement. Since a value is not
returned, the compiler will treat that the final brace as an implicit return
statement. However, it's a good idea to include them (as a matter of good
programming style – or since it is a good way of indicating the end of the
function). However, note that as with functions that return values, we may want to
return before the end of a function, and in those cases the return is necessary (see page 170-174 of your text). main
#include <math.h>
double cube_plus_one (double number1);
int main ()
{
double number1, number2, number3, result;
cout << "Enter three real numbers:";
cin >> number1 >> number2 >> number3;
result = cube_plus_one(number1) * number2 + sqrt(number3);
cout << "The result is: " << result << endl;
return 0;
}
double cube_plus_one (double number1)
{
double number2 = 1.0;
return (number2 + (number1 * number1 * number1));
}
int factorial (int n);
// Returns n!, n should be nonnegative
int main()
{
int n;
cout << "Enter an integer number: ";
cin >> n;
cout << "\n\tYou entered: " << n;
cout << "\n\tThe factorial is: "
<< factorial(n) << endl;
cout << "\tThe value you entered is: " << n
<< endl << endl;
return 0;
}
int factorial (int n)
// computing the n!, the local value of n is changed in the process
{
long product = 1;
while (n > 0)
{
product = n * product;
n--;
}
return product;
}
{
return ((n1 + n2) / 2.0);
}
{
return ((n1 + n2 + n3) / 3.0);
}
double ave( double n1, double n2);
// returns the average of n1 and n2
double ave( double n1, double n2, double n3);
// returns the average of n1, n2 and n3
int main()
{
cout << "The average of 2.0, 2.5 and 3.0 is "
<< ave(2.0, 2.5, 3.0) << endl;
cout << "The average of 4.5 and 5.5 is "
<< ave(4.5, 5.5) << endl;
return 0;
}
double ave( double n1, double n2)
// returns the average of n1 and n2
{
return (n1 + n2)/2;
}
double ave( double n1, double n2, double n3)
// returns the average of n1, n2 and n3
{
return (n1 + n2 + n3)/3;
}
// Outputs two temperatures to the screen
{
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(1);
cout << f_degrees << " degrees Farenheit is "
<< c_degrees << " C.\n";
return;
}
{
cout << "---------------------------"
<< "CSC 215-402
<< "Void functions\n"
<< "--------------------------";
return;
}
main
is actually just a function itself (think of it as a function to the operating system). The convention used for the main function requires that an integer value be returned since it is of type int there. Note that although the value returned is not used, C++ tradition preserves its use.
Call-by-Reference Parameters
The call-by-value functions that we've been using up until now are not sufficient for some tasks.
e.g.:
Let us say we wanted to write a function to handle screen input and say we the requirement was to get two (two or more) numbers from the user. We would not be able to use a call-by-value function since we need to return the value of two (or more ) things and call-by-value functions can return at most one value.
Call-by-Reference
We need a way to return more than one value to the main function. One way to accomplish this is to allow the function to change the values of its arguments so that the values we want to return are updated directly in the space of the calling routine.
A call-by-reference argument provides the the address of the variable that is its argument. This means that it gives it access to the memory location labeled by the argument in the main function.
We indicate that we have a call-by-reference argument by simply putting an ampersand (&) directly behind (and adjacent to) the type of the argument in the function prototype and definition.
The ampersand in C++ (from C) actually means "give me an address of" specified type. The addresses that we've been talking about are simply the places in memory that the compiler has assigned to each of the variables declared in the main function.
Consider the following function:
void get_two_numbers (double& x, double& y)
{
cout << "Please input two numbers: ";
cin >> x >> y;
return;
}
Consider the invocation: int main () Note the following: How would this have been different if we had left the arguments to get_two_numbers as call-by-value? void get_two_numbers(double x, double y) Note:
{
double product, first_float, second_float;
get_two_numbers (first_float, second_float);
product = first_float * second_float;
cout << "\nThe product is: " << product << endl;
return 0;
}
{
cout << "Enter two numbers: ";
cin >> x >> y;
return;
}