Chapter 3 Procedural Abstraction and Functions That Return a Value

50
Chapter 3 Chapter 3 Procedural Abstraction and Procedural Abstraction and Functions That Return a Value Functions That Return a Value Goals: Goals: To examine the advantages of top-down design To examine the advantages of top-down design To survey the available C++ library functions To survey the available C++ library functions To define the typecasting functions that have been set up To define the typecasting functions that have been set up To explore the use of programmer-defined functions To explore the use of programmer-defined functions To distinguish between constants, global & local variables To distinguish between constants, global & local variables To introduce the concept of function overloading To introduce the concept of function overloading

description

Chapter 3 Procedural Abstraction and Functions That Return a Value. Goals:. To examine the advantages of top-down design. To survey the available C++ library functions. To define the typecasting functions that have been set up. To explore the use of programmer-defined functions. - PowerPoint PPT Presentation

Transcript of Chapter 3 Procedural Abstraction and Functions That Return a Value

Page 1: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3Procedural Abstraction and Procedural Abstraction and Functions That Return a ValueFunctions That Return a Value

Goals:Goals:

• To examine the advantages of top-down designTo examine the advantages of top-down design

• To survey the available C++ library functionsTo survey the available C++ library functions

• To define the typecasting functions that have been To define the typecasting functions that have been set upset up• To explore the use of programmer-defined functionsTo explore the use of programmer-defined functions

• To distinguish between constants, global & local To distinguish between constants, global & local variablesvariables• To introduce the concept of function overloadingTo introduce the concept of function overloading

Page 2: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 22

Top-Down DesignTop-Down DesignOne of the most effective ways to design a program is One of the most effective ways to design a program is by means of by means of top-down designtop-down design..

Page 3: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 33

Library FunctionsLibrary FunctionsNote that a number of predefined functions exist in C+Note that a number of predefined functions exist in C++ libraries that a programmer can access via include + libraries that a programmer can access via include directives.directives.

math.hmath.h

Computes common mathematical functionsComputes common mathematical functions

limits.hlimits.h

Tests integer type propertiesTests integer type properties

time.htime.h

Converts time and date formatsConverts time and date formatsAnd m

any more

!

Page 4: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 44

#include <iostream>

#include <iomanip>

#include <math.h>

using namespace std;

void main()

{

double number;

cout << "SIMPLE ARITHMETIC CALCULATOR" << endl;

cout << "(Does a mess o'math to a user-specified value)" << endl << endl;

cout << "Enter the number you\'re using: ";

cin >> number;

cout.setf(ios::fixed);

cout.setf(ios::showpoint);

cout.precision(5);

cout << endl << endl << "ARITHMETIC RESULTS:" << endl << endl;

cout << "NUMBER: " << setw(10) << number << endl;

cout << "NUMBER SQUARED: " << setw(10) << pow(number,2) << endl;

cout << "NUMBER CUBED: " << setw(10) << pow(number,3) << endl;

if (number >= 0.0)

cout << "SQUARE ROOT OF NUMBER: " << setw(10) << sqrt(number) << endl;

if (number > 0.0)

{

cout << "NATURAL LOG OF NUMBER: " << setw(10) << log(number) << endl;

cout << "LOG (BASE 2) OF NUMBER: " << setw(10) << log(number) / log(2.0) << endl;

}

cout << "SINE OF NUMBER: " << setw(10) << sin(number) << endl;

cout << "COSINE OF NUMBER: " << setw(10) << cos(number) << endl;

cout << "FLOOR OF NUMBER: " << setw(10) << floor(number) << endl;

cout << "CEILING OF NUMBER: " << setw(10) << ceil(number) << endl;

cout << "ABSOLUTE VALUE OF NUMBER: " << setw(10) << fabs(number) << endl;

cout << endl << endl;

return;

}

Page 5: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 55

TypecastingTypecasting

With so many With so many different different numerical numerical types in C++, it types in C++, it is sometimes is sometimes useful to useful to convert from convert from one type to one type to another.another.

C++ provides C++ provides built-in built-in functions to functions to perform this perform this sort of sort of typecastingtypecasting..

#include <iostream>using namespace std;

void main(){ int nbr1, nbr2, nbr3, nbr4, nbr5; double mean; cout << "Enter five integers: "; cin >> nbr1 >> nbr2 >> nbr3 >> nbr4 >> nbr5; mean = (nbr1 + nbr2 + nbr3 + nbr4 + nbr5) / 5; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(2); cout << "\nThe average is: " << mean << ”\n\n"; return;}

#include <iostream>using namespace std;

void main(){ int nbr1, nbr2, nbr3, nbr4, nbr5; double mean; cout << "Enter five integers: "; cin >> nbr1 >> nbr2 >> nbr3 >> nbr4 >> nbr5; mean = double(nbr1 + nbr2 + nbr3 + nbr4 + nbr5) / 5; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(2); cout << "\nThe average is: " << mean << ”\n\n"; return;}

Page 6: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 66

Programmer-Programmer-Defined Defined FunctionsFunctionsIn addition to In addition to using using predefined predefined library library functions, a functions, a programmer programmer can implement can implement a top-down a top-down design by design by means of means of programmer-programmer-defined defined functions.functions.

main functionmain function• query user for yearquery user for year• query user for query user for monthmonth• query user for dayquery user for day• calculate day-of-calculate day-of-yearyear• output day-of-yearoutput day-of-year

retrieveYear functionretrieveYear function• query user for yearquery user for year• ensure year is in 1950-ensure year is in 1950-20502050• return yearreturn yearretrieveMonth retrieveMonth

functionfunction• query user for monthquery user for month• ensure month is in 1-ensure month is in 1-1212• return monthreturn monthretrieveDay functionretrieveDay function

• query user for dayquery user for day• ensure day is in proper range for ensure day is in proper range for month/yearmonth/year• return dayreturn day

calculateDayOfYear functioncalculateDayOfYear function• cycle through months, adding # of days to cycle through months, adding # of days to DOYDOY• add this month’s # of days to DOYadd this month’s # of days to DOY• return DOYreturn DOY

Example:Example:Compute Compute today’s day of today’s day of the year.the year.

Page 7: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 77

///////////////////////////////////////////// This program queries the user for the //// current date and then calculates and //// outputs the current day of the year. /////////////////////////////////////////////#include <iostream>using namespace std;

int retrieveYear();int retrieveMonth();int retrieveDay(int mo, int yr);int calculateDayOfYear(int theDay, int theMonth, int theYear);

// The main function serves a supervisory capacity, //// calling the other functions to interact with the //// user and to do the day-of-year calculations. It //// then outputs the result. //void main(){ int day, month, year, dayOfYear;

year = retrieveYear(); month = retrieveMonth(); day = retrieveDay(month, year); dayOfYear = calculateDayOfYear(day, month, year);

cout << "It\'s day #" << dayOfYear << " of the year " << year << endl << endl;

return;}

Function Prototypes

Before examining the main function, the compiler needs to

know the format of every function in the

program, including the name of the function, the type of value that it will return, and the

types of the parameters that are

being sent to it.

Function CallsJust like the

predefined library function calls, calls to

the programmer-defined functions can

be sent values as parameters to help the

function do its job, and can return a single value to be used by the calling

function (in this case, main).

Page 8: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 88

// The retrieveYear function queries the user for the current year and verifies that the user's //// response is legitimate (i.e., in the range between 1950 and 2050). The user is forced to //// respond repeatedly until the answer is legitimate. That legitimate year is returned. //int retrieveYear(){ int thisYear;

cout << "Enter the current year: "; cin >> thisYear; while ((thisYear < 1950) || (thisYear > 2050)) { cout << "Sorry! This program can only handle years in the 1950-2050 range." << endl; cout << "Enter a year in the proper range: "; cin >> thisYear; }

return thisYear;}

// The retrieveMonth function queries the user for the current month and verifies that the //// user's response is legitimate (i.e., in the range between 1 and 12). The user is forced //// to respond repeatedly until the answer is legitimate. That legitimate month is returned. //int retrieveMonth(){ int thisMonth; cout << "Enter the current month: "; cin >> thisMonth; while ((thisMonth < 1) || (thisMonth > 12)) { cout << "Sorry! This program can only handle months in the 1-12 range." << endl; cout << "Enter a month in the proper range: "; cin >> thisMonth; } return thisMonth;}

Function HeadingThis line is identical to the prototype,

except for the semicolon at the end of the prototype.

Return StatementReturns the value to be used by the calling function (i.e.,

main).

Local VariableCan only be used by this function. Not even main knows about this

variable!

Page 9: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 99

// The retrieveDay function queries the user for the //// current day and verifies that the user's response is //// legitimate (i.e., in the proper range for the para- //// meterized month and year). The user is forced to //// respond repeatedly until the answer is legitimate. //// That legitimate day is returned. //int retrieveDay(int mo, int yr){ int today; int lastDay;

if (mo == 2) { if (yr % 4 == 0) lastDay = 29; else lastDay = 28; } else if ((mo == 4) || (mo ==6) || (mo == 9) || (mo == 11)) lastDay = 30; else lastDay = 31;

cout << "Enter the current day: "; cin >> today; while ((today < 1) || (today > lastDay)) { cout << "Sorry! This program can only handle days " << "in the 1-" << lastDay << " range." << endl; cout << "Enter a day in the proper range: "; cin >> today; } return today;}

Parameter ListThese are copies of the variables in the calling function (in this case, main). Changes to their

values will have no effect on the original variables!

(That’s why it’s a good idea to give them new names – it decreases confusion when reading

the code!)

Page 10: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1010

// The calculateDayOfYear function uses the para- //// meterized day, month, and year to calculate the //// corresponding day of the year, which it returns. //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;}

Function Comment

It’s always a good idea to precede each

function with a descriptive comment.

If the programmer revisits this program at a later date, or if another programmer needs to adjust the

code, such documentation can

be priceless!

And what happens And what happens when you when you runrun this this

program?program?

Page 11: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1111

Another Another Example - Example - A Digital A Digital Numerics Numerics CountdowCountdownn

main functionmain function• print a headerprint a header• print the print the countdowncountdown

printHeader functionprintHeader function• output a simple headeroutput a simple header

printTimedDigits functionprintTimedDigits function• cycle through the digits from 9 down to 0cycle through the digits from 9 down to 0• output the digital numeric for each digit when a output the digital numeric for each digit when a second elapsessecond elapses• sound a beeping alarm with each digitsound a beeping alarm with each digit

printDigitalNumeric functionprintDigitalNumeric function• output the top three characters of the digital output the top three characters of the digital numericnumeric• output the middle three characters of the digital output the middle three characters of the digital numericnumeric• output the bottom three characters of the digital output the bottom three characters of the digital numericnumeric

printTopLine functionprintTopLine function• based upon the based upon the number being number being represented, print the represented, print the three-character three-character sequence representing sequence representing its top lineits top line

printMiddleLine printMiddleLine functionfunction

• based upon the based upon the number being number being represented, print the represented, print the three-character three-character sequence representing sequence representing its middle lineits middle line

printBottomLine printBottomLine functionfunction

• based upon the based upon the number being number being represented, print the represented, print the three-character three-character sequence representing sequence representing its bottom lineits bottom line

Notice thatNotice that main main is not the is not the onlyonly function function capable of capable of calling other calling other functions!functions!

Page 12: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1212

/////////////////////////////////////////////////////////////////////////////// This program illustrates what the ten numerical digits from nine down //// to zero would look like if displayed using horizontal and vertical //// bars, similar to what the digital display of a clock uses. To simplify //// the computations, a little Boolean algebra is utilized. One-second //// intervals elapse between consecutive numerical digit displays. ///////////////////////////////////////////////////////////////////////////////#include <iostream>#include <time.h>using namespace std;

void printHeader();void printTimedDigits();void printDigitalNumeric(int number);void printTopLine(int number);void printMiddleLine(int number);void printBottomLine(int number);

const char BLANK = ' ', HORIZONTAL_BAR = '_', VERTICAL_BAR = '|';

Void FunctionsIf a function is not going to return a value, then it should be made a void

function.

Global ConstantsBy being defined outside any

function, these values may be used by any function defined below their

declaration.

Page 13: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1313

//////////////////////////////////////////////////////////////////// The main function coordinates the use of the other routines, //// specifically, the routines to output a header and to output //// the numerical digits in a timed fashion. ////////////////////////////////////////////////////////////////////void main(){ printHeader(); printTimedDigits(); return;}

////////////////////////////////////////////////////////////// The printHeader function outputs a small header which //// concisely informs the user what this program is doing. //////////////////////////////////////////////////////////////void printHeader(){ cout << "\"TIMED DISPLAY OF DIGITAL NUMERICS\"" << endl; return;}

Void Function CallsSince the functions return no values, their

function calls require no assignment statements.

Page 14: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1414

/////////////////////////////////////////////////////////////////// The printTimed Digits function cycles through the numerical //// digits from 9 down to 0, outputting them one at a time, in //// one-second intervals, in a digital format. ///////////////////////////////////////////////////////////////////void printTimedDigits(){ int i = 9; // Iterative loop variable for indexing digit. long int initTime; // System time at beginning of timed process. long int currTime; // Current system time. long int elapsedTime; // Number of seconds since process began. time(&initTime); while (i >= 0) { time(&currTime); elapsedTime = currTime - initTime; while (elapsedTime < 10-i) { time(&currTime); elapsedTime = currTime - initTime; } cout << '\a'; printDigitalNumeric(i); i--; } cout << "\a\a\a" << endl; return;}

Function CallThis function calls another function within the program, just like main

can do.

Page 15: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1515

/////////////////////////////////////////////////////////////////// The printDigitalNumeric function generates three lines of //// output to show the vertical and horizontal bars which would //// comprise a digital display of the input parameter number. ///////////////////////////////////////////////////////////////////void printDigitalNumeric(int number){ printTopLine(number); printMiddleLine(number); printBottomLine(number);

return;}

////////////////////////////////////////////////////////////// The printTopLine function determines which characters //// should be placed in the uppermost line of the 3x3 grid //// used to "digitally" represent the parameter number. //////////////////////////////////////////////////////////////void printTopLine(int number){ if ((number == 1) || (number == 4)) cout << BLANK << BLANK << BLANK << endl; else cout << BLANK << HORIZONTAL_BAR << BLANK << endl;

return;}

Function CallsThis function calls three

functions within the program.

Page 16: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1616

//////////////////////////////////////////////////////////////// The printMiddleLine function determines which characters //// should be placed in the center line of the 3x3 grid used //// to "digitally" represent the parameter number. ////////////////////////////////////////////////////////////////void printMiddleLine(int number){ if ((number == 1) || (number == 2) || (number == 3) || (number == 7)) cout << BLANK; else cout << VERTICAL_BAR;

if ((number == 0) || (number == 1) || (number == 7)) cout << BLANK; else cout << HORIZONTAL_BAR;

if ((number == 5) || (number == 6)) cout << BLANK; else cout << VERTICAL_BAR;

cout << endl;

return;}

Page 17: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1717

//////////////////////////////////////////////////////////////// The printBottomLine function determines which characters //// should be placed in the bottom line of the 3x3 grid used //// to "digitally" represent the parameter number. ////////////////////////////////////////////////////////////////void printBottomLine(int number){ if ((number == 0) || (number == 2) || (number == 6) || (number == 8)) cout << VERTICAL_BAR; else cout << BLANK;

if ((number == 1) || (number == 4) || (number == 7)) cout << BLANK; else cout << HORIZONTAL_BAR;

if (number == 2) cout << BLANK; else cout << VERTICAL_BAR;

cout << endl;

return;}

Page 18: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1818

Page 19: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 1919

Information HidingInformation HidingOne of the principles behind top-down design is the One of the principles behind top-down design is the concept of concept of information hidinginformation hiding, in which the programmer , in which the programmer makes functions “aware” of data or methods on a makes functions “aware” of data or methods on a “need-to-know” basis.“need-to-know” basis.

mainmain

printHeadeprintHeaderr

printTimedDigitprintTimedDigitss

printDigitalNumeprintDigitalNumericric

printTopLiprintTopLinene

printMiddleLiprintMiddleLinene

printBottomLiprintBottomLinene

Which functions need to Which functions need to know the contents of the know the contents of the header?header?

Which functions Which functions need to know which need to know which digit is being digit is being handled currently?handled currently?

Which functions need Which functions need to know how the to know how the middle line for a zero middle line for a zero digit is output?digit is output?

Page 20: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 2020

Procedural AbstractionProcedural AbstractionOne means of bringing about information hiding is One means of bringing about information hiding is procedural abstractionprocedural abstraction, in which the programmer makes , in which the programmer makes the details of how a function operates “abstract” from the details of how a function operates “abstract” from the rest of the program.the rest of the program.

Thus, for example, we’re unaware of Thus, for example, we’re unaware of howhow the the sqrt sqrt function infunction in math.h math.h does its job. All that concerns us is does its job. All that concerns us is that the job gets done.that the job gets done.

Page 21: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 2121

Computer Graphics ExampleComputer Graphics Examplemainmain

generatgeneratee

polygonpolygonssgeneratgeneratee

torustorusgeneratgenerat

eecubecube

generatgeneratee

teapotteapotgeneratgenerat

eespherespheregeneratgenerat

eeconecone

drawdrawpolygonpolygon

ss

shadeshadepolygonpolygon

drawdrawpixelspixels

mainmain

generatgeneratee

polygonpolygonssgeneratgeneratee

torustorusgeneratgenerat

eecubecube

generatgeneratee

teapotteapotgeneratgenerat

eespherespheregeneratgenerat

eeconecone

drawdrawpolygonpolygon

ss

blendblendpolygonpolygon

ss

computecomputereflectreflect

drawdrawpixelspixels

mainmain

generatgeneratee

polygonpolygonssgeneratgeneratee

torustorusgeneratgenerat

eecubecube

generatgeneratee

teapotteapotgeneratgenerat

eespherespheregeneratgenerat

eeconecone

drawdrawpolygonpolygon

ss

blendblendpolygonpolygon

ss

computecomputereflectreflect

drawdrawpixelspixels

computecomputecurvedcurved

surfacessurfaces

Page 22: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 2222

#include <iostream>using namespace std;

int i;

void echo();

void main(){ i = 0; while (i <= 9) { i++; cout << i << "(main) "; echo(); }

return;}

void echo(){ i++; cout << i << "(echo)\n";

return;}

Global VariablesGlobal VariablesWhile it’s While it’s possible to possible to declare a declare a global global variablevariable that is that is accessible accessible throughout the throughout the program’s program’s functions, such functions, such variables damage variables damage information information hiding and limit hiding and limit readability, readability, modifiability, modifiability, debuggability, debuggability, etc.etc.

Page 23: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 2323

#include <iostream>using namespace std;

void echo();

void main(){ int i; i = 0; while (i <= 9) { i++; cout << i << "(main) "; echo(); }

return;}

void echo(){ int i; i++; cout << i << "(echo)\n";

return;}

Local VariablesLocal Variables

Local variables Local variables are declared are declared inside a inside a particular particular function and can function and can onlyonly be be accessed within accessed within that function.that function.

Page 24: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 2424

#include <iostream>using namespace std;

void echo(int i);

void main(){ int i; i = 0; while (i <= 9) { i++; cout << i << "(main) "; echo(i); }

return;}

void echo(int i){ i++; cout << i << "(echo)\n";

return;}

Function Function ParametersParametersFunction Function parameters are parameters are basically local basically local variables that variables that have been have been initialized with initialized with the value of the the value of the corresponding corresponding argument in the argument in the calling function.calling function.

Page 25: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 3Chapter 3CS 140CS 140 Page Page 2525

#include <iostream>#include <math.h>using namespace std;

double roundoff(double nbr, int digits);int roundoff(int value, int factor);

void main(){ double x = 425.709256; int i = 425; int n = 3; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(10); cout << "Rounding off " << x << "\n with integer " << n << ": "; cout << roundoff(x, n) << endl << endl; cout << "Rounding off " << i << "\n with integer " << n << ": "; cout << roundoff(i, n) << endl << endl; return;}

// Round off the parameterized number //// to the parameterized decimal place. //double roundoff(double nbr, int digits){ int expandedNbr; expandedNbr = int(nbr * pow(10, digits)); return (double(expandedNbr) / pow(10, digits));}

// Round off the parameterized value to the next //// lower multiple of the parameterized factor. //int roundoff(int value, int factor){ return (value - value % factor);}

Function Function OverloadinOverloadingg

It’s possible to It’s possible to have more than have more than one function one function with the same with the same name, as long name, as long as the compiler as the compiler can distinguish can distinguish between them between them (via the (via the returned type returned type and/or and/or parameter parameter types).types).

Page 26: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4Functions 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 27: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 2727

void void FunctionsFunctionsWhen 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!

The Most Common UseThe Most Common Use

ForFor void void Functions IsFunctions Is

Pure Output.Pure Output.

The Most Common UseThe Most Common Use

ForFor void void Functions IsFunctions Is

Pure Output.Pure Output.

Page 28: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 2828

CallingCalling void void FunctionsFunctions

When calling When calling aa void void function, no function, no return value return value is expected.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 Call

Non-Non-voidvoidFunction CallFunction Call

Page 29: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 2929

Call-by-Reference Call-by-Reference ParametersParametersWhen a function isn’t supposed to return When a function isn’t supposed to return anyany values, it can be made a values, it can be made a void void function.function.When a function is supposed to return a When a function is supposed to return a single value, it can be made a non-single value, it can be made a non-void void function, using the same type as the value function, using the same type as the value being returned.being returned.

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

Page 30: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3030

#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); return;}

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; return;}

Note that the ampersand (&) in front of the Note that the ampersand (&) in front of the variable name signifies that the parameter is variable name signifies that the parameter is

being passed by reference instead of by value.being passed by reference instead of by 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 obtain The three parameters here are supposed to obtain new values in this function, and those three values new values in this function, and those three values

are needed in the calling function.are needed in the calling function.

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

automatically affectautomatically affect x x,, y y, and, and z z inin main main..

Page 31: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3131

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 in three values so they’ll be in numerical order when this numerical order when this

function ends.function ends.

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

are passed by reference.are passed by reference.

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

values of the values of the incoming incoming

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

value.value.

Page 32: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3232

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 33: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3333

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

return toreturn to mainmain from fromretrieveThreeNumbersretrieveThreeNumbers

RAMRAM

mainmain

xx yy zz

mainmain calls callsreorderThreeNumbersreorderThreeNumbers return toreturn to mainmain from from

reorderThreeNumbersreorderThreeNumbers

RAMRAM

mainmain

xx yy zz

RAMRAM

mainmainreorderThreeNumbersreorderThreeNumbers

nbrAnbrAnbrCnbrC

temptemp

nbrBnbrB

Page 34: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3434

RAMRAM

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

outputThreeNumbersoutputThreeNumbers

return toreturn to mainmain fromfrom

outputThreeNumbersoutputThreeNumbers

RAMRAM

mainmainoutputThreeNumbersoutputThreeNumbers

middlemiddle smallestsmallest

largestlargest

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

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

RAMRAM

mainmain

xx yy zz

mainmain endend

ss

Page 35: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3535

/////////////////////////////////////////////////////////////// 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;}

Page 36: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3636

// 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 37: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3737

// 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 has three parameters.This function has three parameters.

The first parameter is the value The first parameter is the value entered by the user, which won’t be entered by the user, which won’t be

changed in this function, so it’s changed in this function, so it’s passed by value.passed by value.

The second and third parameters The second and third parameters are values being calculated in this are values being calculated in this

function; they’re needed in the function; they’re needed in the calling function, so they’re passed calling function, so they’re passed

by reference.by reference.

Page 38: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3838

// 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;}

Page 39: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 3939

NestedNestedFunctionsFunctions

Just likeJust like main main, any function , any function may contain a call to another may contain a call to another function within its body.function within its body.

#include <iostream>#include <iomanip>#include <math.h>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(char 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);

return;}

Page 40: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4040

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 41: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4141

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(char 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 42: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4242

Testing FunctionsTesting Functions

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

Page 43: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4343

#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 function and theand the outputResults outputResults function are function are working correctly, working correctly, the other the other functions are functions are temporarily 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 44: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4444

#include <iostream>using namespace std;

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

void main(){ cout << 1 << '/' << 1 << '/' << 2005 << ": DAY #" << calculateDayOfYear(1, 1, 2005) << " (Should be 1)" << endl; cout << 2 << '/' << 28 << '/' << 2005 << ": DAY #" << calculateDayOfYear(28, 2, 2005) << " (Should be 59)" << endl; cout << 2 << '/' << 28 << '/' << 2004 << ": DAY #" << calculateDayOfYear(28, 2, 2004) << " (Should be 59)" << endl; cout << 2 << '/' << 29 << '/' << 2004 << ": DAY #" << calculateDayOfYear(29, 2, 2004) << " (Should be 60)" << endl; cout << 7 << '/' << 4 << '/' << 2005 << ": DAY #" << calculateDayOfYear(4, 7, 2005) << " (Should be 185)" << endl; cout << 12 << '/' << 31 << '/' << 2005 << ": DAY #" << calculateDayOfYear(31, 12, 2005) << " (Should be 365)" << endl; cout << 12 << '/' << 31 << '/' << 2004 << ": DAY #" << calculateDayOfYear(31, 12, 2004) << " (Should be 366)" << endl << endl; return;}

A Driver A Driver FunctionFunction

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 45: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4545

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 46: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4646

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

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

#include <iostream>

using namespace std;

void main()

{

int value;

cout << "Enter a non-zero value: ";

cin >> value;

while (value = 0)

{

cout << "No, enter a NON-ZERO value: ";

cin >> value;

}

cout << "You entered the non-zero value "

<< value << endl;

}

This program’s supposed to keep asking for a value until a non-zero value is entered.

What went wrong?

Page 47: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4747

Setting Up The DebuggerSetting Up The Debugger

Set a “breakpoint” where you want Set a “breakpoint” where you want the program to stop.the program to stop.

Starting at the breakpoint, you’ll be Starting at the breakpoint, you’ll be able to step through the program as able to step through the program as

it executes each line of code.it executes each line of code.

Page 48: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4848

Starting The DebuggerStarting The Debugger

Page 49: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 4949

Using The DebuggerUsing The Debugger

Page 50: Chapter 3 Procedural Abstraction and Functions That Return a Value

Chapter 4Chapter 4CS 140CS 140 Page Page 5050

Stepping Through The ProgramStepping Through The Program

Notice that the program got past the loop without going inside it.

So entering zero for value doesn’t cause the loop to be entered!

Why is that…?