Chapter 5 Functions for All Subtasks

19
Chapter 5 Chapter 5 Functions for All Subtasks Functions for All Subtasks Goals: Goals: To explore the use of To explore the use of void void functions functions To distinguish between call-by-reference and call-by-value To distinguish between call-by-reference and call-by-value To examine how functions can be nested To examine how functions can be nested To introduce testing via stubs and drivers To introduce testing via stubs and drivers To gain some familiarity with the Visual C++ debugger To gain some familiarity with the Visual C++ debugger

description

Chapter 5 Functions for All Subtasks. Goals:. To explore the use of void functions. To distinguish between call-by-reference and call-by-value. To examine how functions can be nested. To introduce testing via stubs and drivers. To gain some familiarity with the Visual C++ debugger. - PowerPoint PPT Presentation

Transcript of Chapter 5 Functions for All Subtasks

Page 1: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5Functions for All SubtasksFunctions for All Subtasks

Goals:Goals:

• To explore the use ofTo explore the use of void void functionsfunctions

• To distinguish between call-by-reference and call-To distinguish between call-by-reference and call-by-valueby-value• To examine how functions can be nestedTo examine how functions can be nested

• To introduce testing via stubs and driversTo introduce testing via stubs and drivers

• To gain some familiarity with the Visual C++ To gain some familiarity with the Visual C++ debuggerdebugger

Page 2: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 22

void void FunctionsFunctions

When a function returns When a function returns nono value, then it is a value, then it is a void void function.function.

void outputResults(int high, int low, int mean){ cout << “High Value: ” << high << endl; cout << “Low Value: ” << low << endl; cout << “Mean Value: ” << mean << endl;

return;}

void printHeader(){ cout << “RUDIMENTARY INTEGER LIST ANALYSIS AND SUMMARY” << endl << endl; cout << “Enter a list of positive integers, ending with -1.” << endl; cout << “Afterwards, the maximum, minimum, and mean will be displayed.\n\n”;

return;} No Returned Value!No Returned Value!

Most Common UseMost Common Use

ForFor void void Functions:Functions:

Pure Output.Pure Output.

Most Common UseMost Common Use

ForFor void void Functions:Functions:

Pure Output.Pure Output.

Page 3: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 33

CallingCalling void void FunctionsFunctionsWhen calling aWhen calling a void void function, no return function, no return value is expected.value is expected.

void main(){ int value; int max = -1; int min = INT_MAX; int total = 0; int count = 0;

printHeader();

cout << “Enter value: ”; cin >> value;

while (value >= 0) { max = higher(value, max); min = lower(value, min); total += value; count++;

cout << “Enter value: ”; cin >> value; } outputResults(max, min, average(total, count));

return;}

void void Function CallFunction Call

Non-Non-voidvoidFunction CallFunction Call

Non-Non-voidvoidFunction CallFunction Call

void void Function CallFunction CallNon-Non-voidvoid

Function CallFunction Call

Page 4: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 44

Call-by-Reference Call-by-Reference ParametersParametersWhen a function isn’t supposed to generate When a function isn’t supposed to generate anyany values, it can be made avalues, it can be made a void void function.function.

When a function is supposed to generate a single When a function is supposed to generate a single value, it can be made a non-value, it can be made a non-void void function, using function, using the same type as the value being returned.the same type as the value being returned.

When a function is supposed to generate When a function is supposed to generate multiplemultiple values that are needed in the calling function, then values that are needed in the calling function, then the two functions are allowed to the two functions are allowed to share the same share the same memorymemory by means of by means of call-by-reference parameterscall-by-reference parameters..

Page 5: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 55

#include <iostream>using namespace std;

void retrieveThreeNumbers(int &firstNbr, int &secondNbr, int &thirdNbr);void reorderThreeNumbers(int &nbrA, int &nbrB, int &nbrC);void outputThreeNumbers(int smallest, int middle, int largest);

void main(){ int x, y, z;

retrieveThreeNumbers(x, y, z); reorderThreeNumbers(x, y, z); outputThreeNumbers(x, y, z);}

void retrieveThreeNumbers(int &firstNbr, int &secondNbr, int &thirdNbr){ cout << "Enter three integers." << endl;

cout << "First integer: "; cin >> firstNbr;

cout << "Second integer: "; cin >> secondNbr;

cout << "Third integer: "; cin >> thirdNbr;}

Note that the ampersand (&) in front of the Note that the ampersand (&) in front of the variable name signifies that the parameter variable name signifies that the parameter is being passed by reference instead of by is being passed by reference instead of by

value.value.

In other words, the function will not make a In other words, the function will not make a copycopy of the value being passed, but will, in of the value being passed, but will, in

fact, be using the fact, be using the originaloriginal memory. memory.

The three parameters here are supposed to The three parameters here are supposed to obtain new values in this function, and those obtain new values in this function, and those

three values are needed in the calling function.three values are needed in the calling function.

Therefore, all three values are passed by Therefore, all three values are passed by reference, and any changes made to them in reference, and any changes made to them in

this function automatically affectthis function automatically affect x x,, y y, and, and z z inin mainmain..

Page 6: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 66

void reorderThreeNumbers(int &nbrA, int &nbrB, int &nbrC){ int temp; if ((nbrB <= nbrA) && (nbrB <= nbrC)) { temp = nbrA; nbrA = nbrB; nbrB = temp; } else if ((nbrC <= nbrA) && (nbrC <= nbrB)) { temp = nbrA; nbrA = nbrC; nbrC = temp; } if (nbrC < nbrB) { temp = nbrB; nbrB = nbrC; nbrC = temp; } return;}

void outputThreeNumbers(int smallest, int middle, int largest){ cout << endl << endl; cout << "The smallest number is: " << smallest << endl; cout << "The middle number is: " << middle << endl; cout << "The largest number is: " << largest << endl; cout << endl << endl; return;}

This function reorders the This function reorders the three values so they’ll be three values so they’ll be in numerical order when in numerical order when

this function ends.this function ends.

Thus, the function Thus, the function mightmight change the values of the change the values of the three parameters, so the three parameters, so the

parameters are passed by parameters are passed by reference.reference.

The last function The last function will not alter any will not alter any of the values of of the values of the incoming the incoming

parameters, so parameters, so they’re passed by they’re passed by

value.value.

Page 7: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 77

What’s Happening In What’s Happening In Memory?Memory?

mainmainbeginbegin

ss

RAMRAM

mainmain

xx yy zz

mainmain calls callsretrieveThreeNumbersretrieveThreeNumbers

RAMRAM

mainmainretrieveThreeNumbersretrieveThreeNumbers

firstNbrfirstNbrsecondNbrsecondNbr

thirdNbrthirdNbr

Data HeapData Heap

Keeps Keeps track of track of

variables in variables in use.use.

The The same same

memory memory is being is being used, used,

but with but with different different variable variable names!names!

Run-Time Run-Time StackStack

Keeps track of Keeps track of function calls; function calls; the function the function

that is on top that is on top of the stack is of the stack is

the active the active function.function.

Page 8: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 88

What’s Happening In Memory? (Part What’s Happening In Memory? (Part 2)2)

return toreturn to mainmain from fromretrieveThreeNumbersretrieveThreeNumbers

RAMRAM

mainmain

xx yy zz

mainmain calls callsreorderThreeNumbersreorderThreeNumbers

return toreturn to mainmain from fromreorderThreeNumbersreorderThreeNumbers

RAMRAM

mainmain

xx yy zz

RAMRAM

mainmainreorderThreeNumbersreorderThreeNumbers

nbrAnbrAnbrCnbrC

temptemp

nbrBnbrB

Page 9: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 99

RAMRAM

What’s Happening In Memory? (Part What’s Happening In Memory? (Part 3)3)mainmain calls calls

outputThreeNumbersoutputThreeNumbersreturn toreturn to mainmain

fromfromoutputThreeNumbersoutputThreeNumbersRAMRAM

mainmainoutputThreeNumbersoutputThreeNumbers

middlemiddle smallestsmallest

largestlargest

The parameters are The parameters are passed by value, so passed by value, so they do they do notnot share share

memory withmemory with main main’s ’s variables!variables!

RAMRAM

mainmain

xx yy zzmainmain endend

ss

Page 10: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1010

////////////////////////////////////////////////////////////////////////////////// This program computes the value to which a power series converges, and the //// number of iterations required before the series can be said to converge. //////////////////////////////////////////////////////////////////////////////////#include <iostream>using namespace std;double queryUserForValue();void computeSeries(double x, double &sum, int &nbrLoops);void outputResults(double result, int iterations);

// The main function coordinates the retrieval of the value to be used in the power //// series, the calculation of the series limit, and the output of the results. //void main(){ double number, convergentValue; int nbrIterations; number = queryUserForValue(); computeSeries(number, convergentValue, nbrIterations); outputResults(convergentValue, nbrIterations); return;}

// This function queries the user for the power series //// generator value, which must be strictly between 0 and 1. //double queryUserForValue(){ double nbr; cout << "Enter the number to be tested: "; cin >> nbr; while ((nbr <= 0.0) || (nbr >= 1.0)) { cout << "The number must be greater than 0 and less than 1." << endl << "Enter the number to be tested: "; cin >> nbr; } return nbr;}

Page 11: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1111

// This function repeatedly adds the next power of the generator value to the series expansion, // // until two consecutive sums are equal, at which time the series is considered to converge. //void computeSeries(double x, double &sum, int &nbrLoops){ double powerOfX, previousSum = 0.0; nbrLoops = 0; sum = x; powerOfX = x; while (previousSum < sum) { nbrLoops++; previousSum = sum; powerOfX *= x; sum += powerOfX; } return;}

// This function outputs the power series final value, as //// well as the number of iterations required to obtain it. //void outputResults(double result, int iterations){ cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(8); cout << "The series converges to " << result << " in " << iterations << " iterations." << endl << endl; return;}

This function has three parameters.This function has three parameters.

The first parameter is the value entered by the The first parameter is the value entered by the user, which won’t be changed in this function, so user, which won’t be changed in this function, so

it’s passed by value.it’s passed by value.

The second and third parameters are values The second and third parameters are values being calculated in this function; they’re needed being calculated in this function; they’re needed

in the calling function, so they’re passed by in the calling function, so they’re passed by reference.reference.

Page 12: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1212

NestedNestedFunctionsFunctions

Just likeJust like main main, any function may , any function may contain a call to another function contain a call to another function within its body.within its body.#include <iostream>

#include <iomanip>#include <cmath>#include <string>using namespace std;

double queryUserForValue();bool testValueBounds(double value);void outputWarning(double value);void generateResults(double val, double &sinVal, double &cosVal, double &logVal);void outputResults(double val, double sinVal, double cosVal, double logVal);void outputOneResult(string resultName, double value, double result);

void main(){ double userValue; double sine, cosine, logarithm;

userValue = queryUserForValue(); generateResults(userValue, sine, cosine, logarithm); outputResults(userValue, sine, cosine, logarithm);}

Page 13: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1313

double queryUserForValue(){ double nbr;

cout << "Enter the number to be tested: "; cin >> nbr; while (!testValueBounds(nbr)) cin >> nbr;

return nbr;}

bool testValueBounds(double value){ if (value <= 0.0) { outputWarning(value); return false; } return true;}

void outputWarning(double value){ cout << "BAD VALUE: " << value << endl; cout << "(Only positive values are allowed!)" << endl << endl; return;}

queryUserForValue

queryUserForValue

calls calls

testValueBounds

testValueBoundstestValueBounds

testValueBounds

calls calls

outputWarning

outputWarning

Page 14: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1414

void generateResults(double val, double &sinVal, double &cosVal, double &logVal){ double valAsRadians = val * 3.1415926535 / 180; sinVal = sin(valAsRadians); cosVal = cos(valAsRadians); logVal = log(val); return;}

void outputResults(double val, double sinVal, double cosVal, double logVal){ cout << endl << endl << "The Mathematical Results:" << endl << endl; outputOneResult("Sine", val, sinVal); outputOneResult("Cosine", val, cosVal); outputOneResult("Logarithm", val, logVal); cout << endl << endl; return;}

void outputOneResult(string resultName, double value, double result){ cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(5); cout << setw(9) << resultName << " of " << value << " = " << setw(10) << result << endl; return;}

outputResults

outputResults calls calls outputOneResult

outputOneResult

Page 15: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1515

Testing FunctionsTesting Functions

When writing a program, it’s a good idea to test When writing a program, it’s a good idea to test individual functions as they’re written, rather than individual functions as they’re written, rather than waiting until the entire program is complete.waiting until the entire program is complete.

Page 16: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1616

#include <iostream>using namespace std;

double queryUserForValue();void computeSeries(double x, double &sum, int &nbrLoops);void outputResults(double result, int iterations);

void main(){ double number, convergentValue; int nbrIterations; number = queryUserForValue(); computeSeries(number, convergentValue, nbrIterations); outputResults(convergentValue, nbrIterations);}

double queryUserForValue(){ return 0.00;}

void computeSeries(double x, double &sum, int &nbrLoops){ sum = 1.234567899; nbrLoops = 999;}

void outputResults(double result, int iterations){ cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(8); cout << "The series converges to " << result << endl << " in " << iterations << " iterations." << endl << endl;}

Stub Stub FunctionFunctionssTo test whether To test whether thethe main main function and thefunction and the outputResults outputResults function are function are working working correctly, the correctly, the other functions other functions are temporarily are temporarily written as stubs.written as stubs.

When the output When the output is satisfactory, is satisfactory, the programmer the programmer can proceed to can proceed to write the write the realreal functions.functions.

Page 17: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1717

#include <iostream>using namespace std;

int calculateDayOfYear(int theDay, int theMonth, int theYear);

void main(){ cout << 1 << '/' << 1 << '/' << 1967 << ": DAY #" << calculateDayOfYear(1, 1, 1967 ) << " (Should be 1)" << endl; cout << 2 << '/' << 28 << '/' << 2033 << ": DAY #" << calculateDayOfYear(28, 2, 2033 ) << " (Should be 59)" << endl; cout << 2 << '/' << 28 << '/' << 1984 << ": DAY #" << calculateDayOfYear(28, 2, 1984 ) << " (Should be 59)" << endl; cout << 2 << '/' << 29 << '/' << 2028 << ": DAY #" << calculateDayOfYear(29, 2, 2028 ) << " (Should be 60)" << endl; cout << 7 << '/' << 4 << '/' << 1999 << ": DAY #" << calculateDayOfYear(4, 7, 1999) << " (Should be 185)" << endl; cout << 12 << '/' << 31 << '/' << 2017 << ": DAY #" << calculateDayOfYear(31, 12, 2017 ) << " (Should be 365)" << endl; cout << 12 << '/' << 31 << '/' << 1996 << ": DAY #" << calculateDayOfYear(31, 12, 1996) << " (Should be 366)" << endl << endl; return;}

A Driver FunctionA Driver Function

TheThe main main function below is function below is notnot the desired the desired mainmain function.function.

It was designed to It was designed to testtest the the calculateDayOfYear calculateDayOfYear function!function!

Page 18: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1818

int calculateDayOfYear(int theDay, int theMonth, int theYear){ int daysSoFar = 0; int cyclingMonth = 1;

while (cyclingMonth < theMonth) { if (cyclingMonth == 2) { if (theYear % 4 == 0) daysSoFar += 29; else daysSoFar += 28; } else if ((cyclingMonth == 4) || (cyclingMonth == 6) || (cyclingMonth == 9) || (cyclingMonth == 11)) daysSoFar += 30; else daysSoFar += 31;

cyclingMonth++; }

daysSoFar += theDay;

return daysSoFar;}

The results of the test are The results of the test are favorable, with every program-favorable, with every program-calculated value identical to the calculated value identical to the corresponding programmer-corresponding programmer-calculated value.calculated value.

Thus, theThus, the calculateDayOfYear calculateDayOfYear function seems to work and the function seems to work and the rest of the rest of the realreal program can be program can be written!written!

Page 19: Chapter 5 Functions for All Subtasks

Chapter 5Chapter 5CS 140CS 140 Page Page 1919

Debugging in Debugging in Visual C++Visual C++When a program When a program compiles but does not compiles but does not produce the expected produce the expected results, the problem results, the problem isn’t syntax but isn’t syntax but semanticssemantics, i.e., the logic , i.e., the logic of the program is faulty.of the program is faulty.

Visual C++ has a Visual C++ has a debugger that allows a debugger that allows a programmer to step programmer to step through the program through the program and determine what’s and determine what’s wrong.wrong.

#include <iostream>using namespace std;void main(){ int i; int value; cout << "Enter three values:" << endl; while (i < 3) { cin >> value; i++; cout << "You entered " << value << endl; } return;} In this

program, only three

input values were

supposed to be

accepted.What went

wrong?