CS 010 - Introduction to Computer Science I
Lab 6. Functions, Pass-by-value vs pass-by-reference parameters;

Points(10 overall)

Collaboration policy:

Collaboration on this lab exercise is strongly ENCOURAGED. The exercise is intended for practice, not assessment -- most people who try should get all participation points. Feel free to ask for help from, and provide help to, others. You shouldn't blindly copy solutions from one another (or from anywhere else) nor simply write code for someone else (even if you explain it as you write), but you can certainly help each other debug, give plenty of suggestions and hints, **explain** why things work or don't work, etc. If you get done early, feel free to walk around and help others.


Program 1: Function invocation

You've been using functions all session. sqrt() is a function that takes a floating-point value as an argument and returns the square root of that argument. To use this function we include the cmath library where the definition of this function can be found. We've used this function like this:

     #include<iostream>
     #include<cmath>
    
     using namespace std;

     int main()
     {
        double area;
        cout << "Enter the area of a square:\n";
        cin >> area;
        cout << "The length of a side of this square is " << sqrt(area) << ".";

        return 0;
     }

The last cout statement invokes the function sqrt(). In other words, it stops executing your main function, finds the definition of the sqrt() function, passes in the floating-point value, and executes the code in this function's definition. In this case, the function returns a value, the square root of area, so it is typically used as an expression.

Some functions do not return a value, so they would have to be used as a statement. For example, in your next assignment, you will use a void function to draw your spaceship. This function will pass in a value, but it will not return a value. This function will just draw the spaceship in the graphics window based on the position you pass in as an argument. You will invoke this function something like this:

    draw_ship(position);

Notice that the function invocation is a complete statement, unlike sqrt(area) which was just an expression within a statement. What would happen if we used the invocation of sqrt() as a complete statement?

    sqrt(area);

What would happen if we had used draw_ship() as an expression?

    cwin << draw_ship(position);

Neither of these last two statements make sense. The first won't cause an error, but it won't do anything either. It invokes sqrt() returning the square root of area, but does nothing with the value returned. sqrt is not a variable. It does not save the return value in something called sqrt. So, the following statements also do not make sense.

    sqrt(area);
    cout << "The length of a side of this square is " << sqrt << ".";

The second statement, cwin << draw_ship(position);, will actually cause a syntax error. This statement requires a shape object on the right side of the << operator. The function just draws the ship, it does not return an object that can be drawn (or return anything else for that matter).

Write a program that uses the sqrt function to calculate the perimeter of a square. Recall that the perimeter will be the length of a side * 4.


Program 2: Function definition

When writing our own functions, we must provide the type of the value returned, a list of the parameters to be passed in and their types, the name of the function, and of course the code to perform the function. Function definitions can be broken into 2 parts. The function header, and the function body.

The function header gives the return type, the function name, and the list of parameters and their return types. The function header for a function that returns the sum of 2 integers might look like the following:

    int add(int x, int y)

The first int is the return type, the type of the value that will be returned by this function.

add is the name of the function. This is the name you will use to invoke this function.

Within the parentheses is the list of the parameters and their respective types. This function has 2 integer parameters. When invoking this function, you must pass in 2 integer arguments. Each parameter must declare its type and must be separated by a comma.

The body of the function follows the header. The body must be enclosed by braces as we have done with the main function. The body of this function might look like:

    {
        return (x + y);
    }

The body of a function that returns a value must have a return statement that returns an expression. The expression must evaluate to the type specified in the header.

We put the header and body together to make the function definition.

    int add(int x, int y)
    {
       return (x + y);
    }

To use this function we have to include its definition in the file along with our main function. When invoking this function in main, the program must know that it exists. With predefined functions like sqrt(), we included a library that had its definition. Notice that we did this above the main function. You can put your function definition in the same place, before the main function. If you put the function definition after the main function, you would get a syntax error when trying to invoke the function in main, since it would not know it existed at that point.

Write a program that uses the add() function above to output the sum of 2 numbers.


Program 3: Functions invoking functions

Write a program that computes the perimeter of a square given its area as you did in program 1. This time, however, write a function that is passed in the area and returns the perimeter. You will need to call the sqrt function from within the perimeter() function. Make sure you include the cmath library before your definition of the perimeter function.


Program 4: void functions

Many times you need a function that does not return a value, but instead just performs some action, like outputting an object or objects to the screen or the graphics window. The textbook calls these procedures rather than functions.

For these functions you specify it is not returning a value by putting the keyword void in place of the return type in the function header like this:

    void draw_ship(position)

Write a void function (a.k.a procedure) that just outputs your name to the screen. To test this function you will need to write a program (main function) that just calls this function and then ends. This function will also not use any parameters to pass anything in.

You may use the following code for your main function:


#include <iostream>

using namespace std;

//Your function definition goes here.

int main()
{
    //Your function call goes here.

    return 0;
}



Program 5: pass-by-value parameters

Write a void function that prints to the screen 2 integers passed in using value parameters. Your main() should call your void function twice. You do not need 2 functions. You will call the same function twice. The first time use int variables to pass in the values. With the second call to the function, use integer literals to pass in the values.


Program 6: pass-by-reference parameters

Now write a void function that will get 2 integers from the user and pass them back to main using reference parameters. Unlike the pass-by-value parameters in part 5, the call to this function will have to use variables and not literals or constants. Why is this?

Put this function in the same program from part 5. Your main() should now call this function to get the 2 integer values from the user. Then main() should call the function you wrote for Program 5 to output those variables.


Program 7: Putting it all together

Let's add one more function to program 5 and 6. Write a function that is passed in one integer by value and returns the square of that integer. Do not use reference parameters for this function. The program should call the input function from #6 to get 2 integers. Then, call the square function twice to get the square of each of the 2 integers. Finally, call the output function from #5 to output the square of the integers. To make the program a little nicer, change the output function to take 4 parameters. Send the original 2 inputs along with the squares of each input. Then, it should output the original value followed by its square for each input.

Example run of the program: (user input in bold)

    Please enter 2 integers: 10 4
    
    10 squared is 100
    4 squared is 16