Notes3 - Chapter 3 Procedural Abstraction and Functions That Return a Value Goals To examine the advantages of topdown design To survey the

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 3 Procedural Abstraction and Functions That Return a Value Goals: To examine the advantages of topdown design To survey the available C++ library functions To define the typecasting functions that have been set up To explore the use of programmerdefined functions To distinguish between constants, global & local variables To introduce the concept of function overloading TopDown Design One of the most effective ways to design a program is by means of topdown design. CS 140 Chapter 3 Page 2 Library Functions Note that a number of predefined functions exist in C++ libraries that a programmer can access via include directives. cmath Computes common mathematical functions limits Tests integer type properties ctime Converts time and date formats nd A ny ma re! mo CS 140 Chapter 3 Page 3 #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; CS 140 } Chapter 3 Page 4 Typecasting With so many different numerical types in C++, it is sometimes useful to convert from one type to another. C++ provides builtin functions to perform this sort of typecasting. #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 3 Page 5 CS 140 Programmer Defined Functions Example: Compute today's day of the year. retrieveYear function query user for year main function query user for month query user for day calculate day-of-year output day-of-year query user for year In addition to using predefined library retrieveMonth function query user for month functions, a ensure month is in 1-12 programmer can return month implement a top retrieveDay function down design by query user for day means of ensure day is in proper range for month/year return day programmerdefined functions. calculateDayOfYear function add this month's # of days to DOY return DOY CS 140 Chapter 3 ensure year is in 1950-2050 return year cycle through months, adding # of days to DOY Page 6 /////////////////////////////////////////// // 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 Calls Just 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 7 CS 140 Chapter 3 // 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; Function Heading Identical to prototype, except for the cout << "Enter the current year: "; semicolon at the end of the prototype. 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 Statement return thisYear; } Returns the value to be used by the calling function (i.e., main). // 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: "; Can only be used by this function. Not cin >> thisMonth; even main knows about this variable! 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; } Local Variable CS 140 Chapter 3 Page 8 // 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; // // // // // // Parameter List 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; } These 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!) CS 140 Chapter 3 Page 9 // 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 when you run this program? CS 140 Chapter 3 Page 10 print the countdown Another Example A printHeader function Digital output a simple header Numerics printTimedDigits function Countdown cycle through the digits from 9 down to 0 print a header main function Notice that main is not the only function capable of calling other functions! printTopLine function output the digital numeric for each digit when a second elapses sound a beeping alarm with each digit output the top three characters of the digital numeric output the middle three characters of the digital numeric output the bottom three characters of the digital numeric printMiddleLine function based upon the number being represented, print the three-character sequence representing its middle line Chapter 3 printDigitalNumeric function based upon the number being represented, print the three-character sequence representing its top line CS 140 printBottomLine function based upon the number being represented, print the three-character sequence representing its bottom line Page 11 ///////////////////////////////////////////////////////////////////////////// // 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; If a function is not going to void printHeader(); return a value, then it should void printTimedDigits(); void printDigitalNumeric(int number); be made a void function. void printTopLine(int number); void printMiddleLine(int number); void printBottomLine(int number); Void Functions Global Constants const char BLANK = ' ', HORIZONTAL_BAR = '_', VERTICAL_BAR = '|'; By being defined outside any function, these values may be used by any function defined below their declaration. ////////////////////////////////////////////////////////////////// // 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(); Since the functions return no values, their printTimedDigits(); return; function calls require no assignment statements. } Void Function Calls CS 140 Chapter 3 Page 12 //////////////////////////////////////////////////////////// // 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--; This function calls another function within } the program, just like main can do. cout << "\a\a\a" <<endl; return; } Function Call CS 140 Chapter 3 Page 13 ///////////////////////////////////////////////////////////////// // 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); This function calls 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 Calls three functions within the program. CS 140 Chapter 3 Page 14 ////////////////////////////////////////////////////////////// // 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; } CS 140 Chapter 3 Page 15 ////////////////////////////////////////////////////////////// // 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; } CS 140 Chapter 3 Page 16 CS 140 Chapter 3 Page 17 Information Hiding One of the principles behind topdown design is the concept of information hiding, in which the programmer makes functions "aware" of data or methods on a "needtoknow" basis. main printHeader printTimedDigits printDigitalNumeric printTopLine printMiddleLine Which functions need to know the contents of the header? Which functions need to know how the middle line for a zero digit is output? printBottomLine Which functions need to know which digit is being handled currently? Page 18 CS 140 Chapter 3 Procedural Abstraction One means of bringing about information hiding is procedural abstraction, in which the programmer makes the details of how a function operates "abstract" from the rest of the program. Thus, for example, we're unaware of how the sqrt function in cmath does its job. All that concerns us is that the job gets done. CS 140 Chapter 3 Page 19 Computer Graphics Example main main main generate polygons generate torus generate cube generate teapot generate sphere generate cone CS 140 draw polygons shade polygon draw pixels generate polygons generate torus generate cube generate teapot generate sphere generate cone Chapter 3 draw polygons blend polygons compute reflect draw pixels generate polygons generate torus generate cube generate teapot generate sphere generate cone Page 20 compute curved surfaces draw polygons blend polygons compute reflect draw pixels #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 Variables While it's possible to declare a global variable that is accessible throughout the program's functions, such variables damage information hiding and limit readability, modifiability, debuggability, etc. "; CS 140 Chapter 3 Page 21 #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 Variables Local variables are declared inside a particular function and can only be accessed within that function. "; CS 140 Chapter 3 Page 22 #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 Parameters Function parameters are basically local variables that have been initialized with the value of the corresponding argument in the calling function. "; CS 140 Chapter 3 Page 23 #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 Overloading It's possible to have more than one function with the same name, as long as the compiler can distinguish between them (via the returned type and/or parameter types). CS 140 Chapter 3 Page 24 ...
View Full Document

This note was uploaded on 08/26/2009 for the course CS 140 taught by Professor Staff during the Fall '08 term at Southern Illinois University Edwardsville.

Ask a homework question - tutors are online