Chapter 6 - Functions

6.1 Modular Programming

6.2 Defining and Calling Functions
Function Definition

Definition includes:
Function Return Type

If a function returns a value, the type of the value must be indicated:
    int main()
If a function does not return a value, its return type is void:
    void printHeading()
    {    
            cout << "Monthly Sales\n";
    }

Calling a Function

To call a function, use the function name followed by () and ;
        printHeading();
When called, program executes the body of the called function
After the function terminates, execution resumes in the calling function at point of call.


// Functions in Program 6-1

// This program has two functions: main and displayMessage
#include <iostream>
using namespace std;

//*****************************************
// Definition of function displayMessage  *
// This function displays a greeting.     *
//*****************************************

void displayMessage()
{
   cout << "Hello from the function displayMessage.\n";
}

//*****************************************
// Function main                          *
//*****************************************

int main()
{
   cout << "Hello from main.\n";
   displayMessage();
   cout << "Back in function main again.\n";
   return 0;
}

Calling Functions

6.3 Function Prototypes


Ways to notify the compiler about a function before a call to the function:

  Place function definition before calling function’s definition
  Use a function prototype (function declaration) – like the function definition without the body

           Header: void printHeading()
           Prototype: void printHeading();



// Program 6.5

// This program has three functions: main, first, and second.
#include <iostream>
using namespace std;

// Function Prototypes
void first();
void second();

int main()
{
   cout << "I am starting in function main.\n";
   first();    // Call function first
   second();   // Call function second
   cout << "Back in function main again.\n";
   return 0;
}

//*************************************
// Definition of function first.      *
// This function displays a message.  *
//*************************************

void first()
{
   cout << "I am now inside the function first.\n";
}

//*************************************
// Definition of function second.     *
// This function displays a message.  *
//*************************************

void second()
{
   cout << "I am now inside the function second.\n";
}


Prototype Notes

6.4 Sending Data into a Function

Can pass values into a function at time of call:
            c = pow(a, b);
Values passed to function are arguments
Variables in a function that hold the values passed as arguments are parameters

A Function with a Parameter Variable

    void displayValue(int num)
    {
       cout << "The value is " << num << endl;
    }


// Program 6.6

// This program demonstrates a function with a parameter.
#include <iostream>
using namespace std;

// Function Prototype
void displayValue(int);

int main()
{
   cout << "I am passing 5 to displayValue.\n";
   displayValue(5);  // Call displayValue with argument 5
   cout << "Now I am back in main.\n";
   return 0;
}

//*********************************************************
// Definition of function displayValue.                   *
// It uses an integer parameter whose value is displayed. *
//*********************************************************

void displayValue(int num)
{
   cout << "The value is " << num << endl;
}


Other Parameter Terminology
Parameters, Prototypes, and Function Headers

For each function argument,
  the prototype must include the data type of each parameter inside its parentheses
  the header must include a declaration for each parameter in its ()
    void evenOrOdd(int);     //prototype
    void evenOrOdd(int num)  //header
    evenOrOdd(val);          //call

Function Call Notes
Passing Multiple Arguments


// This program demonstrates a function with three parameters.
#include <iostream>
using namespace std;

// Function Prototype
void showSum(int, int, int);

int main()
{
   int value1, value2, value3;
   
   // Get three integers.
   cout << "Enter three integers and I will display ";
   cout << "their sum: ";
   cin >> value1 >> value2 >> value3;
   
   // Call showSum passing three arguments.
   showSum(value1, value2, value3);
   return 0;
}

//************************************************************
// Definition of function showSum.                           *
// It uses three integer parameters. Their sum is displayed. *
//************************************************************

void showSum(int num1, int num2, int num3)
{
   cout << (num1 + num2 + num3) << endl;
}


6.5 Passing Data by Value
Passing Information to Parameters by Value

    evenOrOdd can change variable num, but it will have no effect on variable val


6.6 Using Functions in Menu-Driven Programs

Using Functions in Menu-Driven Programs

Functions can be used
    Higher-level  functions can call general-purpose functions, minimizing the total number of functions and speeding program development time


// Program 6-10

// This is a menu-driven program that makes a function call
// for each selection the user makes.
#include <iostream>
#include <iomanip>
using namespace std;

// Function prototypes
void showMenu();
void showFees(double, int);

int main()
{
   int choice;       // To hold a menu choice
   int months;       // To hold a number of months
   
   // Constants for the menu choices
   const int ADULT_CHOICE = 1,
             CHILD_CHOICE = 2,
             SENIOR_CHOICE = 3,
             QUIT_CHOICE = 4;

   // Constants for membership rates
   const double ADULT = 40.0,
                SENIOR = 30.0,
                CHILD = 20.0;

   // Set up numeric output formatting.
   cout << fixed << showpoint << setprecision(2);
   
   do
   {
      // Display the menu and get the user's choice.
      showMenu();
      cin >> choice;
      
      // Validate the menu selection.
      while (choice < ADULT_CHOICE || choice > QUIT_CHOICE)
      {
         cout << "Please enter a valid menu choice: ";
         cin >> choice;
      }
      
      // If the user does not want to quit, proceed.
      if (choice != QUIT_CHOICE)
      {
          // Get the number of months.
          cout << "For how many months? ";
          cin >> months;
             
          // Display the membership fees.
          switch (choice)
          {
             case ADULT_CHOICE:  
                  showFees(ADULT, months);
                  break;
             case CHILD_CHOICE:
                  showFees(CHILD, months);
                  break;
             case SENIOR_CHOICE:
                  showFees(SENIOR, months);
          }
      }
   } while (choice != QUIT_CHOICE);
   return 0;
}

//*****************************************************************
// Definition of function showMenu which displays the menu.       *
//*****************************************************************

void showMenu()
{
   cout << "\n\t\tHealth Club Membership Menu\n\n"
        << "1. Standard Adult Membership\n"
        << "2. Child Membership\n"
        << "3. Senior Citizen Membership\n"
        << "4. Quit the Program\n\n"
        << "Enter your choice: ";
}

//*****************************************************************
// Definition of function showFees. The memberRate parameter      *
// the monthly membership rate and the months parameter holds the *
// number of months. The function displays the total charges.     *
//*****************************************************************

void showFees(double memberRate, int months)
{
    cout << "The total charges are $"
         << (memberRate * months) << endl;
}


6.7 The return Statement


// Program 6-11

// This program uses a function to perform division. If division
// by zero is detected, the function returns.
#include <iostream>
using namespace std;

// Function prototype.
void divide(double, double);

int main()
{
   double num1, num2;

   cout << "Enter two numbers and I will divide the first\n";
   cout << "number by the second number: ";
   cin >> num1 >> num2;
   divide(num1, num2);
   return 0;
}

//***************************************************************
// Definition of function divide.                               *
// Uses two parameters: arg1 and arg2. The function divides arg1*
// by arg2 and shows the result. If arg2 is zero, however, the  *
// function returns.                                            *
//***************************************************************

void divide(double arg1, double arg2)
{
   if (arg2 == 0.0)
   {
      cout << "Sorry, I cannot divide by zero.\n";
      return;
   }
   cout << "The quotient is " << (arg1 / arg2) << endl;
}


6.8 Returning a Value From a Function
    double x;
    x = pow(2.0, 10.0);

In a value-returning function, the return statement can be used to return a value from function to the point of call. Example:

    int sum(int num1, int num2)
    {  
       double result;  
       result = num1 + num2;  
        return result;
    }



// Program 6-12

// This program uses a function that returns a value.
#include <iostream>
using namespace std;

// Function prototype
int sum(int, int);

int main()
{
   int value1 = 20,   // The first value
       value2 = 40,   // The second value
       total;         // To hold the total

   // Call the sum function, passing the contents of
   // value1 and value2 as arguments. Assign the return
   // value to the total variable.
   total = sum(value1, value2);
   
   // Display the sum of the values.
   cout << "The sum of " << value1 << " and "
        << value2 << " is " << total << endl;
   return 0;
}

//*****************************************************
// Definition of function sum. This function returns  *
// the sum of its two parameters.                     *
//*****************************************************

int sum(int num1, int num2)
{
   return num1 + num2;
}


//  Program 6-13

// This program demonstrates two value-returning functions.
// The square function is called in a mathematical statement.
#include <iostream>
#include <iomanip>
using namespace std;

//Function prototypes
double getRadius();
double square(double);

int main()
{
   const double PI = 3.14159; // Constant for pi
   double radius;             // To hold the circle's radius
   double area;               // To hold the circle's area

   // Set the numeric output formatting.
   cout << fixed << showpoint << setprecision(2);
   
   // Get the radius of the circle.
   cout << "This program calculates the area of ";
   cout << "a circle.\n";
   radius = getRadius();
   
   // Caclulate the area of the circle.
   area = PI * square(radius);
   
   // Display the area.
   cout << "The area is " << area << endl;
   return 0;
}

//******************************************************
// Definition of function getRadius.                   *
// This function asks the user to enter the radius of  *
// the circle and then returns that number as a double.*
//******************************************************

double getRadius()
{
   double rad;

   cout << "Enter the radius of the circle: ";
   cin >> rad;
   return rad;
}

//******************************************************
// Definition of function square.                      *
// This function accepts a double argument and returns *
// the square of the argument as a double.             *
//******************************************************

double square(double number)
{
   return number * number;
}


Returning a Value From a Function
6.9 Returning a Boolean Value


// Program 6-15

// This program uses a function that returns true or false.
#include <iostream>
using namespace std;

// Function prototype
bool isEven(int);

int main()
{
   int val;

   // Get a number from the user.
   cout << "Enter an integer and I will tell you ";
   cout << "if it is even or odd: ";
   cin >> val;
   
   // Indicate whether it is even or odd.
   if (isEven(val))
      cout << val << " is even.\n";
   else
      cout << val << " is odd.\n";
   return 0;
}

//*****************************************************************
// Definition of function isEven. This function accepts an        *
// integer argument and tests it to be even or odd. The function  *
// returns true if the argument is even or false if the argument  *
// is odd. The return value is an bool.                           *
//*****************************************************************

bool isEven(int number)
{
   bool status;

   if (number % 2 == 0)
      status = true;  // number is even if there is no remainder.
   else
      status = false; // Otherwise, the number is odd.
   return status;
}


6.10 Local and Global Variables


// Program 6-16

// This program shows that variables defined in a function
// are hidden from other functions.
#include <iostream>
using namespace std;

void anotherFunction(); // Function prototype

int main()
{
   int num = 1;   // Local variable

   cout << "In main, num is " << num << endl;
   anotherFunction();
   cout << "Back in main, num is " << num << endl;
   return 0;
}

//*****************************************************
// Definition of anotherFunction                      *
// It has a local variable, num, whose initial value  *
// is displayed.                                      *
//*****************************************************

void anotherFunction()
{
   int num = 20;  // Local variable

   cout << "In anotherFunction, num is " << num << endl;
}


Local Variable Lifetime
Global Variables and Global Constants


//  Program 6-19

// This program calculates gross pay.
#include <iostream>
#include <iomanip>
using namespace std;

// Global constants
const double PAY_RATE = 22.55;    // Hourly pay rate
const double BASE_HOURS = 40.0;   // Max non-overtime hours
const double OT_MULTIPLIER = 1.5; // Overtime multiplier

// Function prototypes
double getBasePay(double);
double getOvertimePay(double);

int main()
{
   double hours,           // Hours worked
          basePay,         // Base pay
          overtime = 0.0,  // Overtime pay
          totalPay;        // Total pay
          
   // Get the number of hours worked.
   cout << "How many hours did you work? ";
   cin >> hours;
   
   // Get the amount of base pay.
   basePay = getBasePay(hours);
   
   // Get overtime pay, if any.
   if (hours > BASE_HOURS)
      overtime = getOvertimePay(hours);
   
   // Calculate the total pay.
   totalPay = basePay + overtime;
   
   // Set up numeric output formatting.
   cout << setprecision(2) << fixed << showpoint;
   
   // Display the pay.
   cout << "Base pay: $" << basePay << endl
        << "Overtime pay $" << overtime << endl
        << "Total pay $" << totalPay << endl;
   return 0;
}

//************************************************
// The getBasePay function accepts the number of *
// hours worked as an argument and returns the   *
// employee's pay for non-overtime hours.        *
//************************************************

double getBasePay(double hoursWorked)
{
   double basePay; // To hold base pay
   
   // Determine base pay.
   if (hoursWorked > BASE_HOURS)
      basePay = BASE_HOURS * PAY_RATE;
   else
      basePay = hoursWorked * PAY_RATE;

   return basePay;
}

//*************************************************
// The getOvertimePay function accepts the number *
// of hours worked as an argument and returns the *
// employee's overtime pay.                       *
//*************************************************

double getOvertimePay(double hoursWorked)
{
   double overtimePay; // To hold overtime pay
   
   // Determine overtime pay.
   if (hoursWorked > BASE_HOURS)
   {
      overtimePay = (hoursWorked BASE_HOURS) *
               PAY_RATE * OT_MULTIPLIER;
   }
   else
      overtimePay = 0.0;

   return overtimePay;
}


Initializing Local and Global Variables
6.11 Static Local Variables


//  Program 6-21

// This program shows that local variables do not retain
// their values between function calls.
#include <iostream>
using namespace std;

// Function prototype
void showLocal();

int main()
{
   showLocal();
   showLocal();
   return 0;
}

//***********************************************************
// Definition of function showLocal.                        *
// The initial value of localNum, which is 5, is displayed. *
// The value of localNum is then changed to 99 before the   *
// function returns.                                        *
//***********************************************************

void showLocal()
{
   int localNum = 5; // Local variable

   cout << "localNum is " << localNum << endl;
   localNum = 99;
}


A Different Approach, Using a Static Variable



//  Program 6-12

// This program uses a static local variable.
#include <iostream>
using namespace std;

void showStatic(); // Function prototype

int main()
{
   // Call the showStatic function five times.
   for (int count = 0; count < 5; count++)
      showStatic();
   return 0;
}

//**************************************************************
// Definition of function showStatic.                          *
// statNum is a static local variable. Its value is displayed  *
// and then incremented just before the function returns.      *
//**************************************************************

void showStatic()
{
   static int statNum;

   cout << "statNum is " << statNum << endl;
   statNum++;
}


6.12 Default Arguments

    A Default argument  is an argument that is passed automatically to a parameter if the argument is missing on the function call.

Must be a constant declared in prototype:
    void evenOrOdd(int = 0);
Can be declared in header if no prototype
Multi-parameter functions may have default arguments for some or all of them:
    int getSum(int, int=0, int=0);

If not all parameters to a function have default values, the defaultless ones are declared first in the parameter list:
    int getSum(int, int=0, int=0);// OK
    int getSum(int, int=0, int);  // NO
When an argument is omitted from a function call, all arguments after it must also be omitted:
    sum = getSum(num1, num2);    // OK
    sum = getSum(num1, , num3);  // NO


6.13 Using Reference Variables as Parameters

Passing by Reference

A reference variable is an alias for another variable
Defined with an ampersand (&)
    void getDimensions(int&, int&);
Changes to a reference variable are made to the variable it refers to
Use reference variables to implement passing parameters by reference


//  Program 6-25

// This program uses a reference variable as a function
// parameter.
#include <iostream>
using namespace std;

// Function prototype. The parameter is a reference variable.
void doubleNum(int &);

int main()
{
   int value = 4;

   cout << "In main, value is " << value << endl;
   cout << "Now calling doubleNum..." << endl;
   doubleNum(value);
   cout << "Now back in main. value is " << value << endl;
   return 0;
}

//**********************************************************
// Definition of doubleNum.                                *
// The parameter refVar is a reference variable. The value *
// in refVar is doubled.                                   *
//**********************************************************

void doubleNum (int &refVar)
{
   refVar *= 2;
}


Reference Variable Notes

6.14 Overloading Functions

Function Overloading Examples

    Using these overloaded functions,

    void getDimensions(int);           // 1
    void getDimensions(int, int);      // 2
    void getDimensions(int, double);   // 3
    void getDimensions(double, double);// 4

    the compiler will use them as follows:

    int length, width;
    double base, height;
    getDimensions(length);           // 1
    getDimensions(length, width);    // 2
    getDimensions(length, height);   // 3
    getDimensions(height, base);     // 4



// Program 6-27

// This program uses overloaded functions.
#include <iostream>
#include <iomanip>
using namespace std;

// Function prototypes
int square(int);
double square(double);

int main()
{
   int userInt;
   double userFloat;

   // Get an int and a double.
   cout << fixed << showpoint << setprecision(2);
   cout << "Enter an integer and a floating-point value: ";
   cin >> userInt >> userFloat;
   
   // Display their squares.
   cout << "Here are their squares: ";
   cout << square(userInt) << " and " << square(userFloat);
   return 0;
}

//**************************************************************
// Definition of overloaded function square.                   *
// This function uses an int parameter, number. It returns the *
// square of number as an int.                                 *
//**************************************************************

int square(int number)
{
   return number * number;
}

//***************************************************************
// Definition of overloaded function square.                    *
// This function uses a double parameter, number. It returns    *
// the square of number as a double.                            *
//***************************************************************

double square(double number)
{
   return number * number;
}


6.15 The exit() Function

    Example:    exit(0);

The cstdlib header defines two constants that are commonly passed, to indicate success or failure:

    exit(EXIT_SUCCESS);
    exit(EXIT_FAILURE);


6.16 Stubs and Drivers

Useful for testing and debugging program and function logic and design
Stub: A dummy function used in place of an actual function
  Usually displays a message indicating it was called.  May also display parameters
Driver: A function that tests another function by calling it
  Various arguments are passed and return values are tested