chapter 4 procedural abstraction and functions that return a value goals: to examine the advantages...
TRANSCRIPT
Chapter 4Chapter 4Procedural 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
Chapter 4Chapter 4CS 140CS 140 Page Page 22
Top-Down DesignTop-Down Design
One 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..
Chapter 4Chapter 4CS 140CS 140 Page Page 33
Library FunctionsLibrary Functions
Note 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.
cmathComputes common mathematical functions
limitsTests integer type properties
ctimeConverts time and date formats
And many m
ore!
Chapter 4Chapter 4CS 140CS 140 Page Page 44
#include <iostream>#include <iomanip>#include <cmath>using namespace std;void main(){ double number;
cout << "SIMPLE ARITHMETIC CALCULATOR" << 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) << 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;}
Chapter 4Chapter 4CS 140CS 140 Page Page 55
TypecastingTypecasting
With so many With so many different different numerical types numerical types in C++, it is in C++, it is sometimes useful sometimes useful to convert from to convert from one type to one type to another.another.
C++ provides C++ provides built-in functions built-in functions to perform this to 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;}
Chapter 4Chapter 4CS 140CS 140 Page Page 66
Programmer-Programmer-Defined Defined FunctionsFunctions
In addition to In addition to using predefined using predefined library functions, library functions, a programmer a programmer can implement a can implement a top-down design top-down design by means of by means of programmer-programmer-defined functions.defined 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.
Chapter 4Chapter 4CS 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).
Chapter 4Chapter 4CS 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 HeadingIdentical to 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!
Chapter 4Chapter 4CS 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!)
Chapter 4Chapter 4CS 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?
Chapter 4Chapter 4CS 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!
Chapter 4Chapter 4CS 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 <ctime>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 = '|';
//////////////////////////////////////////////////////////////////// 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;}
Void FunctionsIf a function is not going to return a value, then it should be made a void
function.Global Constants
By being defined outside any function, these values may be used by any function defined below their
declaration.
Void Function CallsSince the functions return no values, their
function calls require no assignment statements.
Chapter 4Chapter 4CS 140CS 140 Page Page 1313
////////////////////////////////////////////////////////////// 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;}
///////////////////////////////////////////////////////////////////////////////////////// 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. time_t initTime; // System time at beginning of timed process. time_t currTime; // Current system time. time_t elapsedTime; // Number of seconds since process began. initTime = time(&initTime); while (i >= 0) { currTime = time(&currTime); elapsedTime = currTime - initTime; while (elapsedTime < 10-i) { currTime = 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.
Chapter 4Chapter 4CS 140CS 140 Page Page 1414
/////////////////////////////////////////////////////////////////// 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.
Chapter 4Chapter 4CS 140CS 140 Page Page 1515
//////////////////////////////////////////////////////////////// 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;}
Chapter 4Chapter 4CS 140CS 140 Page Page 1616
//////////////////////////////////////////////////////////////// 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;}
Chapter 4Chapter 4CS 140CS 140 Page Page 1717
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?
Chapter 4Chapter 4CS 140CS 140 Page Page 1818
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 the details of how a function operates “abstract” from the rest of the program.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 cmath cmath does its job. All that concerns us is that does its job. All that concerns us is that the job gets done.the job gets done.
Chapter 4Chapter 4CS 140CS 140 Page Page 1919
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
Chapter 4Chapter 4CS 140CS 140 Page Page 2020
#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 possible to declare While it’s possible to declare a a global variableglobal variable that is that is accessible throughout the accessible throughout the program’s functions, such program’s functions, such variables damage information variables damage information hiding and limit readability, hiding and limit readability, modifiability, debuggability, modifiability, debuggability, etc.etc.
Chapter 4Chapter 4CS 140CS 140 Page Page 2121
#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 VariablesLocal variables are declared Local variables are declared inside a particular function inside a particular function and can and can onlyonly be accessed be accessed within that function.within that function.
Chapter 4Chapter 4CS 140CS 140 Page Page 2222
#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 ParametersParameters
Function parameters are Function parameters are basically local variables that basically local variables that have been initialized with the have been initialized with the value of the corresponding value of the corresponding argument in the calling argument in the calling function.function.
Chapter 4Chapter 4CS 140CS 140 Page Page 2323
#include <iostream>#include <cmath>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 OverloadinOverloadinggIt’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).