- Lab Activity # GSP115-A6
- Lab6 of 7: Learning More About Functions
- Lab Overview – Scenario / Summary:
TCO(s) that the lab supports:
5 / Given a game problem, develop a solution algorithmthat employs:- Functions and methods that pass arguments by value and by reference.
- A function prototype andoverloaded functions, which vary the scope and duration of theuse of a variable.
- The string class and emphasizes string manipulation.
6 / Given a programming task that requires iteration (looping) and simple data structures, design, code, and test a solution algorithm that uses arrays (two dimensional, static, dynamic, and character).
Summary:
You will experiment with using “passing by reference” in functions. You will also learn how to create and understand the behavior of default arguments. You will experiment with function overloading. You practice organizing and managing your code using header files and preprocessor commands.
Learning outcomes:
- To be able to create and use pass by reference.
- To be able to create functions with default arguments.
- To be able to understand the use of function overloading.
- To be able to organize and manage code using header files and preprocessor commands.
- Deliverables:
Section / Deliverable
Part A / Step 5. Program Listing and Output
Part B / Step 5. Program Listing and Output
Part C / Step 5. Program Listing and Output
Part D / Step 5. Program Listing and Output
- Lab Steps:
Preparation:
This lab requires Visual Studio 2012.
Lab Activity:
Part A: Programming Exercise 1Step 1: Start Visual Studio 2012
□Start Visual Studio 2012
□Click File | New | Project on the menu bar or click the New Project icon on the toolbar.
□Click the black triangles to open choices on the left pane, if needed. Click on Visual C++. On the right pane, select Empty Project.
□Give the project a name in the Name field near the bottom. For example, Week 6iLab Part A would be an appropriate name.
□Change the location of the project to your Desktop or USB drive or other appropriate location. You can change the location by clicking the Browse button on the right side of the Location field.
□Click the OK button to create your project.
□Open your Solution Explorer by clicking View | Solution Explorer on the menu bar.
□Right-click on the Source Files folder and select Add | New Item.
□Click on C++ File (.cpp) and then give the file a name using the Name box near the bottom. For example, main.cppwould be an appropriate name.
- Step 2: Creating and using “pass by reference”.
□First, let’s revisit what passing by value looks like. Type or copy this code into main.cpp.
//Week 6 iLab Part A-1
// Passing by value_vs_Passing by reference
#includeiostream
#include<string>
#includetime.h
usingnamespacestd;
//******Global constants******
//******End of Global Constants******
//******Function Prototypes******
intshowEffects( int );
//******End of Function Prototypes******
//------
//******Program starts here******
//------
int main()
{
// Seed the random number generator
srand(time(0));
// Initialize Variables
int X = rand()%10;
cout"The address of the variable X in main is [" < &X < "]"endl;
cout" X before function call is " < X < endl;
cout"The function returns "showEffects(X) < endl"X after function call is " < X < endl;
// Wait for user input to close program when debugging.
cin.get();
return 0;
}
//******End of Main******
//******Function Definitions******
intshowEffects( int X )
{
X++;
cout"{In showEffects}"endl;
cout"{The address of the variable X in showEffects is [" < &X < "] and has the value " < X < "}"endl;
return X;
}
//******End of Function Definitions******
□Before you build and run this code, pay attention to a couple of features.
- Notice that we create a variable X in main() and that our function parameter’s name is also X. We previously mentioned that you shouldn’t do this, as it can be confusing. We’re ignoring that very good advice to make a point. Observe that we print out the address of both variables (and they are separate variables, as you will see when you run the code.)
- We print out the value X before we pass it to showEffects() and again after returning. We are doing this to see if X, the variable local to main, has been changed by the function.
- Notice that “The function returns“ is printed in coutbefore we call showEffects(). When you run the code, check out when it is printed in comparison to the output printed within showEffects(). You may be surprised.
□Review the following.
- The value of the X variable that is local to main() is not changed by the function.
- The text in showEffects() printed before the text in the cout command that called showEffects(). This is evidence that before cout starts printing, it builds the string to print internally, which means it processes all function calls before it prints anything. When you know what cout does, this is logical and easy to understand, but if you didn’t know how cout works, it would be counter-intuitive. This is why it is good to know how the code you are using actually works.
- The X variable in main() has a different address than the X variable in showEffects(). This proves they are different variables and the fact that we gave them the same name did not link them in any way. The only thing that links them is that we passed main()’s local variable X as an argument to showEffects(). Hopefully, you are beginning to see why giving them the same name can lead to confusion. We’ll make a small correction to our code to drive this point home.
intshowEffects( int A )
{
A++;
cout"{In showEffects}"endl;
cout"{The address of the variable A in showEffects is [" < &A < "] and has the value " < A < "}"endl;
return A;
}
□Build and run the code to verify that nothing has changed in the code’s behavior, except the memory addresses will probably be different every time you run the program and the text printing from the function refer to “A” instead of “X”.
□Now we will modify this program to pass by reference. We can do this by changing two things. We’ll add an “&” to the prototype and function definition signature.
- Change the prototype from “intshowEffects(int );” to “intshowEffects( int &);”.
- Change the signature in the function definition from “intshowEffects(int A )” to “intshowEffects( int &A )”.
This would indicate that main()’s local variable X wasn’t changed by the function, but if we passed by reference, it has to be changed. This is the kind of bug that can be very hard to spot if you don’t know what to look for. Here are some clues. You know the variable has to be changed (you could run the debugger, set a breakpoint at the last line of code in main(), and check the value there if you aren’t certain). We have recently seen something that tells us where the problem is. Remember the explanation of how cout works? What if cout grabbed the value of X before it called the showEffects() function? Let’s see if that is the problem. Put the “X after function call is” on a separate line.
cout"The function returns "showEffects(X) < endl;
cout"X after function call is " < X < endl;
□If you build and run the code, you should see that we now have the output we expected. X has been changed by the function.
□There is one additional way to pass by reference and that’s by using pointers. Let’s change our program to see what that looks like. Modify your previous code to look like the following.
□Now build and run the program. You should see something similar to the following.
□Although our code is significantly different, the results are the same as when we just used the “&” in our prototype and function definition. In general, using reference variables creates cleaner code when passing by references than does using pointers. One of the questions you’ll be asked is to research the internet to find how other programmers view the question of whether to use pointers or reference variables. There are a lot of varied opinions, but a few cases are almost universally discussed where the choice is clear.
Step 3: Save program
Save your program by clicking File on the menu bar and then clicking Save All, or by clicking the Save All button on the toolbar, or Ctrl + Shift + S.
Step 4: Build and execute the solution
To build and run the program, click Debug on the menu bar and then click the Start Debugging option. You should receive no error messages. If you see some error messages, check the code above to make sure you didn’t key in something wrong. Once you make your corrections to the code, go ahead and click Debug > Start Debugging again to see your output.
Step 5: Capture the output
□Type your name, GSP115, Lab6 at the top of the new Word document.
□Capture a screen print of the output from your program [Hold down the Alt key while you press the PrtScn (printscreen) button]. If you are using a notebook computer, you may need to hold down the Fn key and the Alt key while you press and release the PrtScr button.
□Paste the screen copy into the Word document.
□Under the screen copy, answer the following questions:
- What are the two ways to pass by reference?
- What behavior can be confusion when calling a function directly within a coutstatement?
- If you name a local variable in a calling program the same name used as a parameter name, will their addresses be the same? Under what conditions would a local variable and an argument in a function have the same address?
- Research the internet looking for opinions posted by other programmers on when to use pointers and when to use reference variables. Could you find any advice that seemed useful and/or was commonly suggested?
□Save the Word document as GSP115_Lab6_YourLastName.docx. Be sure that the course number, your last name, and the lab number are part of the file name.
END OF PART A
Part B: Programming Exercise 2
Step 1: Start Visual Studio 2012
□Start Visual Studio 2012
□Click File | New | Project on the menu bar or click the New Project icon on the toolbar.
□Click the black triangles to open choices on the left pane, if needed. Click on Visual C++. On the right pane, select Empty Project.
□Give the project a name in the Name field near the bottom. For example, Week 6iLab Part B would be an appropriate name.
□Change the location of the project to your Desktop or USB drive or other appropriate location. You can change the location by clicking the Browse button on the right side of the Location field.
□Click the OK button to create your project.
□Open your Solution Explorer by clicking View | Solution Explorer on the menu bar.
□Right-click on the Source Files folder and select Add | New Item.
□Click on C++ File (.cpp) and then give the file a name using the Name box near the bottom. For example, main.cpp would be an appropriate name.
Step 2: Using default arguments in functions
□Default arguments are not the difficult to create or use, but there are a few rules that need to be followed. Type of copy the following code in main.cpp.
//Week 6 iLab Part B-1
// Default arguments
#includeiostream
#include<string>
#includetime.h
usingnamespacestd;
//******Global constants******
constintloopCount = 5;
//******End of Global Constants******
//******Function Prototypes******
intgetRand(unsignedint = 10, unsignedint = 0);
//******End of Function Prototypes******
//------
//******Program starts here******
//------
int main()
{
// Seed the random number generator
srand(time(0));
cout"Calling with no parameters: Range is 0 to 10"endl;
for (inti = 0; iloopCount ; i++)
{
cout" "getRand() < endl;
}
coutendl;
cout"Calling with one parameter 20: Range is 0 to 20"endl;
for (inti = 0; iloopCount ; i++)
{
cout" "getRand(20) < endl;
}
coutendl;
cout"Calling with two parameters 20, 10 : Range is 10 to 20"endl;
for (inti = 0; iloopCount ; i++)
{
cout" "getRand(20,10) < endl;
}
// Wait for user input to close program when debugging.
cin.get();
return 0;
}
//******End of Main******
//******Function Definitions******
intgetRand(unsignedintmaxNum , unsignedintminNum)
{
return (rand()%((maxNum+1) - minNum)) + minNum;
}
//******End of Function Definitions******
□We have created a function that returns a random number between 0 and 10 when called with no parameters. If called with one parameter, it returns a random number between 0 and whatever value is passed. If called with two parameters, it returns a random number between the second value passed and the first value passed. Build and run this code. Now check to see if the function is working correctly—which it should if you didn’t have a transcription error.
□Notice the following key points about the code:
- The default values are in the prototype, not the definition signature.
- Notice the order in which we left out values. From the right to the left.
- It doesn’t show here, because every parameter has a default value. Moving from left to right, once we add a default value, we have to have default values for the remaining parameters.
□Let’s try to fix this issue by removing the default values from the prototype. Change the prototype from “intgetRand(unsignedint = 10, unsignedint = 0);” to “intgetRand(unsignedint, unsignedint);”. Try to build the project. Note any error code.
□Restore both the function definition signature and the prototype to their original state.
□Next, we’ll see what happens when we change the order in which we leave out values. In the second loop, change the function call from “getRand(20)” to “getRand(,5)” as if we were looking for random numbers between 5 and 10. Build the project. Note any errors.
□Change the function call back to its original state.
□The last change will be to remove the “=0” in the last prototype parameter as if we only want a default value for the first parameter. Build the project and note any errors.
□Restore the code to its original state. You may want to play with values to test your understanding. Just remember the three points list above.
Step 3: Save program
Save your program by clicking File on the menu bar and then clicking Save All, or by clicking the Save All button on the toolbar, or Ctrl + Shift + S.
Step 4: Build and execute the solution
To build and run the program, click Debug on the menu bar and then click the Start Debugging option. You should receive no error messages. If you see some error messages, check the code above to make sure you didn’t key in something wrong. Once you make your corrections to the code, go ahead and click Debug > Start Debugging again to see your output.
Step 5: Capture the output
□Open the file that you created for Part A called GSP115_Lab6_YourLastName.docx. Go to the bottom of the file (after the Part A section). Leave a few blank lines and then type your name, GSP115, Lab6Part B.
□Capture a screen print of your program’s output [Hold down the Alt key while you press the PrtScn (printscreen) button]. If you are using a notebook computer, you may need to hold down the Fn key and the Alt key while you press and release the PrtScr button.
□Paste the screen copy into the Word document under the Part B section title.
□Under the screen copy, answer the following questions:
- What errors did you see when you tried to add default values in the function signature?
- What errors did you see when you tried to remove the default values from the prototype?
- What errors did you see when you didn’t follow the rule to only leave out values from right to left without holes?
- What errors did you see when you didn’t follow the rule to add default values consecutively from right to left without holes?
□Save the Word document that now contains Part A and Part B.