Welcome to Lesson 18!


Learning Objectives
By the end of today's class, you should know...
  • What is the difference between pass by reference and pass by value?
  • How do you indicate a reference parameter?
  • What is a stream?
  • How to do you read and write from a file?

Announcements

  • Quiz after the break
  • Lab 9 due Friday
  • Women in Computer Science Club meeting today from 12:30pm-1:30pm in the ATC 203 Computer Lab
      • Attend conferences
      • Learn from industry speakers - Amazon speaker in April!
      • Teach programming in the community
      • Learn skills to help you get a job
        • Coding interview practice
      • Work on a team project to put on your resume


Review Activity

1. Write the following functions:


Function 1
  • The function is named printGrade
  • It takes in a double for the score
  • It prints out the grade to the console as A, B, C, D, or F with a message, "The grade is: <grade>"
  • It returns nothing

Function 2

  • The function is named convertGrade
  • It takes in a double for the score
  • It determines if the grade is A, B, C, D, or F
  • It returns a char for the grade

Function 3

  • The function is named frontTimes
  • It takes in one string parameter and one int parameter called n
  • It returns a new string which is the first three characters of the string repeated n times
  • If the string is fewer than 3 characters long, it simply returns the string repeated n times
  • e.g. frontTimes("Chocolate", 2) → "ChoCho"
  • e.g. frontTimes("Oy", 4)  → "OyOyOyOy"

2. Using the starter code below, call the above printGrade and convertGrade functions:

#include <iostream>
using namespace std;

int main() {
    double score;
    char grade;
    cout << "Please enter your score: ";
    cin >> score;
   
    //call printGrade here
    //Note: when calling printGrade, I can only display the grade to the console

    //call convertGrade here
    cout << "Your grade is " << grade << endl;
    //Note: when calling convertGrade, I can store the grade it returns
    //and do more with it than display it. It is
    //stored for future use.

}


3. Write the comment and prototype for the below function:

double mpg(double miles, double gallons)
{
    return miles / gallons;
}

Functions Calling Functions
  • Functions may call other functions
  • Within the body of one function, we can call another function call
  • Functions can call other functions as often as needed
  • We are already doing this when main() calls a function
  • The following program calls a "helper" function to help calculate the BMI.
  • Because calculating the BMI is a somewhat complicated process, it is helpful to create a second function to do part of the work for us.
  • The heightToSquareInches function handles turning the height from feet and inches (such as 5'8") into inches squared (such as 68"2).

Example of Functions Calling Functions


#include <iostream>
using namespace std;

double calculateBMI(int feet, int inches, double weight);
//Calculates a user's Body Mass Index

int convertFeetInches(int feet, int inches);
//Converts height in feet and inches to height in inches

int squareInches(int inches);
//Squares the height in inches

int main() {
    const double WEIGHT = 135.5;
    const int HEIGHT_FEET = 5;
    const int HEIGHT_INCHES = 8;
    double bmi = calculateBMI(HEIGHT_FEET, HEIGHT_INCHES, WEIGHT);
    cout << "Your BMI is: " << bmi << endl;

    return 0;
}

double calculateBMI(int feet, int inches, double weight) {
    int heightInches = convertFeetInches(feet,inches);
    int heightInches2 = squareInches(heightInches);
    double bmi = 703 * weight / heightInches2;
    return bmi;
}

int convertFeetInches(int feet, int inches) {
    return 12 * feet + inches;
}


int squareInches(int inches) {
    return inches * inches;
}


Value Parameters

  • There are two ways to pass arguments to parameters
  • All our functions so far have used value parameters
  • Value parameters are separate variables from the ones in main() (or another calling function)
  • Modification of value parameters does not affect the original caller's value when the function returns

How Value Parameters Work

  • During the function call, your program copies the argument's value into the parameter variable
  • The scope of value parameters is the same as the scope for a local variable
  • If the parameter is assigned a new value, only the local copy changes
  • When the function returns, your program discards any value assigned to a parameter variable
  • The following example program uses value parameters
  • What does this program output?

Example of Value Parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int mystery(int param) {
    cout << "param=" << param << endl;
    param = param * 2;
    return param;
}

int main() {
    int num = 2;

    cout << "At first, num=" << num << endl;
    int result = mystery(num);
    cout << "After calling, num=" << num << endl;
    cout << "And result=" << result << endl;

    return 0;
}


Reference Parameters

  • C++ has another parameter-passing mechanism known as call-by-reference
  • A reference parameter does not create a new variable, but refers to an existing variable instead
  • Any change in a reference parameter is actually a change in the variable to which it refers
  • We create a reference parameter by using an ampersand (&) between the parameter's type and name
    parameterType& parameterName
    
  • The following program shows an example of reference parameters
  • What is different?
  • What does this program output?

Example of Reference Parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int mystery(int& param) {
    cout << "param=" << param << endl;
    param = param * 2;
    return param;
}

int main() {
    int num = 2;

    cout << "At first, num=" << num << endl;
    int result = mystery(num);
    cout << "After calling, num=" << num << endl;
    cout << "And result=" << result << endl;

    return 0;
}

Call-By-Reference Details

  • What's really passed to the reference parameter?
  • A reference to the caller's original argument!
  • Essentially a reference parameter is another name for the original argument
  • With a reference parameter the code uses the original argument variable in calculations
  • Any change made to a reference parameter changes the original argument
  • Because C++ is passing variables, arguments for reference parameters must be variables and not constants



Mixed Parameter Lists

  • Parameter lists can include both value and reference parameters
  • As usual, the order of arguments in the list is critical
  • The following is a function signature with mixed parameter types:
    void mixedCall(int& par1, int par2, double& par3)
    
  • To call the function:
    int arg1 = 0, arg2 = 1;
    double arg3 = 2.2;
    mixedCall(arg1, arg2, arg3);
    
  • arg1 must be an integer type and is passed by reference
  • arg2 must be an integer type and is passed by value
  • arg3 must be a double type and is passed by reference

When to Use Reference Parameters

  • Reference parameters are usually more efficient than value parameters because they do not make copies of the parameters:
    • A program simply passes the memory address to the function
    • No new memory space is allocated and deallocated
  • Therefore, function calls using reference parameters usually operate faster
  • However, reference parameters restrict the arguments we can use for a function
  • Specifically, we must use a variable argument and not a literal or constant value
  • Usually, the best practice is to pass an object, like a String, by reference
  • Also, we should use value parameters unless a function needs to modify a parameter
  • The performance advantage of reference parameters for primitive types tends to be negligible
  • Thus, it is not worth restricting the call pattern of a function

Reference vs Value Video


Activity 18.1: Exploring Call by Reference (10 pts)

In this exercise we explore how call-by-reference parameters differ from call-by-value parameters.

Specifications

  1. Copy the following program into Eclipse and save it as swap.cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    #include <iostream>
    using namespace std;
    
    void swap(int var1, int var2);
    
    int main() {
        int num1 = 0, num2 = 0;
        cout << "Enter two integers: ";
        cin >> num1 >> num2;
    
        swap(num1, num2);
    
        cout << "After calling function:  "
             << num1 << " " << num2 << endl;
        return 0;
    }
    
    void swap(int var1, int var2) {
        int temp = var1;
        var1 = var2;
        var2 = temp;
    }
    
  2. Compile and run the starter program to make sure you entered it correctly. When you run the program, the output should look like this:
    Enter two integers: 1 2
    After calling function: 1 2
    

    Notice that num1 and num2 have the same values before and after calling the function swap(). Any value assigned to var1 and var2 have no effect on num1 and num2.

  3. Change your program by adding the four ampersands (&) circled below:

    The ampersands tell C++ to use call-by-reference when passing parameter values.

  4. Compile and run the modified program to make sure you made the changes correctly. When you run the program, the output should look like this:
    Enter two integers: 1 2
    After calling function: 2 1
    

    Notice that num1 and num2 have different values before and after calling the function swap(). Any value assigned to var1 and var2 change num1 and num2 respectively.

  5. Submit your final program source code to Canvas.

Wrap Up

  • What will be the value of the num variable after calling the following functions:

void doubleVal(int& value){
    value *= 2;
}

void tripleVal(int value) {
    value *= 3;
}

int main() {
    int num = 3;
    doubleVal(num);
    tripleVal(num);
    cout << num;
}


Upcoming Assignments


~Have a Great Weekend!~