650 likes | 794 Views
Chapter 3: Top-Down Design with Functions and Classes. Jason C. H. Chen, Ph.D. Professor of MIS School of Business Administration Gonzaga University Spokane, WA 99258 chen@gonzaga.edu. 3.1 Building Programs from Existing Information. Reuse of existing programs Develop program in stages
E N D
Chapter 3: Top-Down Design with Functions and Classes Jason C. H. Chen, Ph.D. Professor of MIS School of Business Administration Gonzaga University Spokane, WA 99258 chen@gonzaga.edu
3.1 Building Programs from Existing Information • Reuse of existing programs • Develop program in stages • Compile along the way • Keep it small • Comments to describe actions
Declaration vs. Definition • A declaration specifies the properties of a variable - it specifies a type (e.g., int, float, or char) and a name. • For example, the following statements are valid declarations in C or C++: int age, count; float salary; char name[34]; //array of characters
Declaration vs. Definition (cont.) struct date { int day; int month; int year } birthday; • If a declaration also allocates storage memory for the corresponding entity, the declaration is also a definition.
Declaration vs. Definition (cont.) The following statements are valid declarations only: void compute_sum_ave // Function prototype (float, float, // IN: values used in computation float&, // OUT: sum of num1 and num2 float& ); // OUT: average of num1 and Note that: float& //CALL-BY-REFERENCE
FILE: Circle.cpp (p.107) #include <iostream> using namespace std; int main () { //Declaration section // Local data const float PI = 3.14159; float radius; float area; float circum; //Executable Statements Section // Read radius of circle cout << "Enter the circle radius: "; cin >> radius; // Compute area of circle area = PI * radius * radius; // Compute circumference of circle circum = 2 * PI * radius; // Display area and circumference cout << "The area of the circle is " << area << endl; cout << "The circumference of the circle is " << circum << endl; return 0; } Sample outpu: Enter the circle radius: 5.0 The area of the circle is 78.5397 The circumference of the circle is 31.4159 Press any key to continue
// File: washers (p.110) // Computes the weight of a batch of flat washers. #include <iostream> using namespace std; int main() { const float PI = 3.14159; float holeDiameter; // input - diameter of hole float edgeDiameter; // input - diameter of outer edge float thickness; // input - thickness of washer float density; // input - density of material used float quantity; // input - number of washers made float weight; // output - weight of washer batch float holeRadius; // radius of hole float edgeRadius; // radius of outer edge float rimArea; // area of rim float unitWeight; // weight of 1 washer // Get the inner diameter, outer diameter, and thickness. cout << "Inner diameter in centimeters: "; cin >> holeDiameter; cout << "Outer diameter in centimeters: "; cin >> edgeDiameter; cout << "Thickness in centimeters: "; cin >> thickness; // Get the material density and quantity manufactured. cout << "Material density in grams per cubic centimeter: "; cin >> density; cout << "Quantity in batch: "; cin >> quantity;
// Compute the rim area. holeRadius = holeDiameter / 2.0; edgeRadius = edgeDiameter / 2.0; rimArea = PI * edgeRadius * edgeRadius - PI * holeRadius * holeRadius; // Compute the weight of a flat washer. unitWeight = rimArea * thickness * density; // Compute the weight of the batch of washers. weight = unitWeight * quantity; // Display the weight of the batch of washers. cout << "The expected weight of the batch is " << weight; cout << " grams." << endl; return 0; } Sample Output: Inner diameter in centimeters: 1.2 Outer diameter in centimeters: 2.4 Thickness in centimeters: 0.1 Material density in grams per cubic centimeter: 7.87 Quantity in batch: 1000 The expected weight of the batch is 2670.23 grams
3.2 Library Functions • Goal of Structured Programming • Error free code • Reusability • Don’t reinvent the wheel • C ++ provides collection of functions • Organized in Libraries • Library examples Table 3.1
C++ Math Library • Functions in the Math library • sqrt cos sin pow • Examples Table 3.1 • Function use in Assignments y = sqrt (x); sqrt is function name x is function argument • Activated by a “function call” • Result of execution is assigned to variable y
Result is 4.0 C++ Math Library (cont) Function sqrt as a “black box” Square root computation • X is 16.0
C++ Library Functions • We can effectively utilize existing functions by learning to read function prototypes with the preconditions and postconditions. • Example prototype (or signature) • double sqrt(double x) • // PRE: x >= 0.0 • // POST: Returns the square root of x.
Preconditions and Postconditions • Comments that represents a contract between the implementor of a function and the user (client) of that function. • We'll look at two such comments: • Precondition: What the function requires. • Postcondition: What the function will do if the precondition is met.
Preconditions and Postconditions • The preconditions are the circumstances that must be true before the function can successfully fulfill the promised postconditions. • Example (Precondition abbreviates to PRE: double sqrt(double x); // PRE: x >= 0 // POST: Returns square root of argument X
// File: squareRoot.cpp (p.114) // Performs three square root computations #include <cmath> // sqrt function #include <iostream> // i/o functions using namespace std; int main() { float first; // input: one of two data values float second; // input: second of two data values float answer; // output: a square root value // Get first number and display its square root. cout << "Enter the first number: "; cin >> first; answer = sqrt(first); cout << "The square root of the first number is " << answer << endl; // Get second number and display its // square root. cout << "Enter the second number: "; cin >> second; answer = sqrt(second); cout << "The square root of the second number is " << answer << endl; // Display the square root of the sum of // first and second. answer = sqrt(first + second); cout << "The square root of the sum of both numbers is ” << answer << endl; return 0; } Sample Output: Enter the first number: 9 The square root of the first number is 3 Enter the second number: 16 The square root of the second number is 4 The square root of the sum of both numbers is 5
Other Mathematical Library Functions • See Table 3.1 (p.115)
Methodology • A methodology is a physical implementation of the logical system development life cycle that incorporates: • Step-by-step activities for each phase. • Individual and group roles to be played in each activity • Deliverables and quality standards for each activity, and • Tools and techniques to be used for each activity
Divide and Conquer • An old saying, “if you want to learn anything, you must not try to learn everything -- at least not all at once.” • Therefore, we should divide a system into into its subsystems in order to more easily conquer the problem and build the larger systems. • By dividing a large problem (system) into more easily managed pieces (subsystems), the analyst can simplify the problem-solving process. • A process is a set of linked activities that take an input and transform it to create an output.
Draw a Draw a Draw Circle Triangle intersecting lines Draw Draw a intersecting base lines 3.3 Top-Down Design and Structure Charts stickFigure.cpp (p.122; 126) Original Problem Draw a Level 0 figure Level 1 Detailed subproblems Level 2
3.4 Functions without Arguments • Functions used in Top-Down Design • main() is just a function • called by OS • C++ program is a collection of Functions • top level function is called the main() • lower level functions • User Defined or Libraries • Example StickFigure.cpp (p.125)
Three Major Components for the Function • Function Prototype • outside (before) the main() • Function Calls • inside the main() • Function Definition • outside (after) the main()
Function: General Form //Function Prototype: voidfunction_name (); //Function Calls: int main() { ... function_name (); … } //Function Definitions: void function_name() { //local variable declarations BODY OF FUNCTION }
// File: stickFigure.cpp (p.125) // Draws a stick figure #include <iostream> using namespace std; // Functions Prototype void drawCircle(); // Draws a circle void drawTriangle(); // Draws a triangle void drawIntersect(); // Draws intersecting lines void drawBase(); // Draws a horizontal line //Function Definitions // Draws a circle void drawCircle() { cout << " * " << endl; cout << " * *" << endl; cout << " * * " << endl; } // end drawCircle // Draws a triangle void drawTriangle() { drawIntersect(); drawBase(); } // end drawTriangle // Draws intersecting lines void drawIntersect() { cout << " / \\ " << endl; cout << " / \\ " << endl; cout << " / \\" << endl; } // end drawIntersect // draws a horizontal line void drawBase() { cout << " -------" << endl; } // end drawBase int main() { //Functions Calls // Draw a circle. drawCircle(); // Draw a triangle. drawTriangle(); // Draw intersecting lines. drawIntersect(); getch(); return 0; }
Order of Execution void drawCircle(); void … ; int main() { drawCircle(); drawTriangle(); drawIntersect(); return 0; } void drawCircle() { cout << “ * “ << endl; cout << “ * * “ << endl; cout << “ * * “ << endl; }
Function Advantages • Program team on large projects • Simplify tasks • Each Function is a separate unit • Top-down approach • Procedural abstraction • Information hiding • Reuse of functions (e.g., drawTriangle)
Displaying User Instructions • We still have not covered passing in and out of a function • Following example shows displaying info • instruct(); function call in main • see example • circle_instruct (p.128 with p.107)
3.5 Functions with Input Arguments • Functions used like building blocks • Build systems one functions at a time • Stereo Components • Use function return values and arguments to communicate between functions • Function with a single argument • stickFigure_symbol.cpp (p.133)
Function: General Form Function Prototype: void function_name (); Function Calls: int main() { ... function_name (); … } Function Definitions: void function_name() { //local variable declarations BODY OF FUNCTION }
// File: stickFigure.cpp (p.126) // Draws a stick figure #include <iostream> using namespace std; // Functions Prototype void drawCircle(); // Draws a circle void drawTriangle(); // Draws a triangle void drawIntersect(); // Draws intersecting lines void drawBase(); // Draws a horizontal line //Function Definitions // Draws a circle void drawCircle() { cout << " * " << endl; cout << " * *" << endl; cout << " * * " << endl; } // end drawCircle // Draws a triangle void drawTriangle() { drawIntersect(); drawBase(); } // end drawTriangle // Draws intersecting lines void drawIntersect() { cout << " / \\ " << endl; cout << " / \\ " << endl; cout << " / \\" << endl; } // end drawIntersect // draws a horizontal line void drawBase() { cout << " -------" << endl; } // end drawBase int main() { //Functions Calls // Draw a circle. drawCircle(); // Draw a triangle. drawTriangle(); // Draw intersecting lines. drawIntersect(); getch(); return 0; }
//Function Definitions // Draws a circle with a symobl void drawCircleChar(char symbol) { cout << " " << symbol << " " << endl; cout << " " << symbol << " " << symbol << endl; cout << " " << symbol << " " << symbol << endl; } // end drawCircle // Draws a triangle void drawTriangle() { drawIntersect(); drawBase(); } // end drawTriangle // Draws intersecting lines void drawIntersect() { cout << " / \\ " << endl; cout << " / \\ " << endl; cout << " / \\" << endl; } // end drawIntersect // draws a horizontal line void drawBase() { cout << " -------" << endl; } // end drawBase // File: stickFigure_symbol.cpp(p.131) // Draws a stick figure #include <iostream> using namespace std; // Functions Prototype // Draws a circle with a symbol void drawCircleChar(char); void drawTriangle(); // Draws a triangle void drawIntersect(); // Draws intersecting lines void drawBase(); // Draws a horizontal line int main() { //Functions Calls cout << "Please enter a symbol for drawing a circle:"; cin >> symbol; drawCircleChar(symbol); // Draw a triangle. drawTriangle(); // Draw intersecting lines. drawIntersect(); getch(); return 0; }
Function with Multiple Arguments: General Form(local variables) Function Prototype: function_type function_name (type1, type2, …); Function Calls: answer = function_name (var-1, var-2, …); Function Definitions: function_type function_name(type1 par-1, type2 par-2, …) { //local variable declarations BODY OF FUNCTION return result; } Note that 1. Order of variables and parameters are significant 2. Variable on the function calls may be: variables, expressions, or actual numbers 3. Parameters on the function definition must be: VARIABLES only 4. Only ONE value returns to calling statement.
Function with Multiple Arguments • testScale_basic.cpp (next slide and p.137) • testScale.cpp (next slide and p.137) Question: what is the difference between these two versions.
// File testScale_basic.cpp (p.137) // Tests function scale. #include <iostream> #include <cmath> using namespace std; // Function prototype float scale(float, int); //Function Definition // information flow float scale(float x, int n)// formal parameters { float scaleFactor, solution; // local variable scaleFactor = pow(10, n); solution = x * scaleFactor; return solution; } int main() { float num1, result; int num2; // Get values for num1 and num2 cout << "Enter a real number: "; cin >> num1; cout << "Enter an integer: "; cin >> num2; // Call scale and display result. result =scale(num1, num2)// actual arguments; cout << "Result of call to function scale is " <<result << endl; return 0; }
// File testScale.cpp (p.137) // Tests function scale. #include <iostream> #include <cmath> using namespace std; // Function prototype float scale(float, int); //Function Definition // information flow float scale(float x, int n)// formal parameters { float scaleFactor; // local variable scaleFactor = pow(10, n); return (x * scaleFactor); } int main() { float num1; int num2; // Get values for num1 and num2 cout << "Enter a real number: "; cin >> num1; cout << "Enter an integer: "; cin >> num2; // Call scale and display result. cout << "Result of call to function scale is " << scale(num1, num2)// actual arguments << endl; return 0; }
FILE: Circle.cpp (p.107) #include <iostream> using namespace std; int main () { //Declaration section // Local data const float PI = 3.14159; float radius; float area; float circum; //Executable Statements Section // Read radius of circle cout << "Enter the circle radius: "; cin >> radius; // Compute area of circle area = PI * radius * radius; // Compute circumference of circle circum = 2 * PI * radius; // Display area and circumference cout << "The area of the circle is " << area << endl; cout << "The circumference of the circle is " << circum << endl; return 0; } Sample output: Enter the circle radius: 5.0 The area of the circle is 78.5397 The circumference of the circle is 31.4159 Press any key to continue
Your turn … • Copy circle_instruct.cpp to your hard drive • File Save As circle_instruct_function.cpp and modify it with two functions: • compute_area • actual parameter: radius • return value: area • compute_circum • actual parameter: radius • return value: circumference • GLOBAL vs. LOCAL variable • circle_instruct_function_1.cpp • circle_instruct_function_2.cpp
Argument Actual parameter Value/expression Do not need to be the same identifier same type Formal parameter operation on value (expression) main function int main() //Function header type variable_2; type result; variable_1=5; Fname_1 result= (variable_1); Identifies the function function definition Fname_1 type (type parameter_1) type variable_2; variable_2=argument; return (variable_2);
Function Call Form: fname (actual arg list); Example: scale (3.0, z); float scale(float x, int n) Which one is a valid statement? scale (5, x+y); //? scale (2+a, b); //? scale (y,x); //?
Argument / Parameter List Correspondence • Functions can have more than 1 arg • Correspondence between Actual & Formal arguments Function call scale (3.0, z); Actual Argument Formal Argument 3.0 x z n
How about this:Parameter List Definition? Function call scale (a, b); float scale(float x+y, int n) { float scaleFactor; scaleFactor = pow(10, n); return ((x+y) * scaleFactor); } Exercises 3.5 #1 (p.140)
Key Points • The substitution of the value of an actual argument in a function call for its corresponding formal argument is strictly positional. That is, the value of the first actual argument is substituted for the first formal argument; the second and so on
Key Points • The names of these corresponding pairs of arguments are no consequence in the substitution process. The names may be different, or they may be the same. • The substituted value is used in place of the formal argument at each point where that argument appears in the called function.
3.6 Scope of Names • Variable declared in a function (including the main) has a local scope within the function • Same for variables declared in the main • Variable declared before main is global scope • may be called anywhere in program • values may be changed from anywhere • Functions declared globally
Global vs. Local For improving your understanding and debugging skills: • testScale_global_local_v1.cpp • testScale_global_local_v2.cpp • testScale_global_local_v3.cpp • (see next slide)
// File testScale.cpp (p.137) // Tests function scale. #include <iostream> #include <math> using namespace std; // Function prototype float scale(float, int); const int total = 550; //Function Definition // information flow float scale(float x, int n) // formal parameters { float scaleFactor; // local variable scaleFactor = pow(10, n); return (x * scaleFactor); } int main() { float num1; int num2; // Get values for num1 and num2 cout << "Enter a real number: "; cin >> num1; cout << "Enter an integer: "; cin >> num2; // Call scale and display result. cout << "Result of call to function scale is " << scale(num1, num2)// actual arguments << endl; return 0; } You may try to: 1. cout >> num1; (in function def.) 2. cout >>x; (in the main) 3. cout >> “Total is: “ >> total; (anywhere)
// File testScale_global_local_v1.cpp (p.140) // this version computes scale and save in the "result" // Tests function scale. #include <iostream> #include <cmath> using namespace std;3 // Function prototype float scale(float, int); int main() { float num1, result; int num2; // Get values for num1 and num2 cout << "Enter a real number: "; cin >> num1; cout << "Enter an integer: "; cin >> num2; //function call result = scale(num1, num2); // actual arguments // Call scale and display result. cout << "Result of call to function scale is " << result << endl; cout << "Test global, local in the main” << " num1 = " << num1 << " num2 = " << num2 << endl; return 0; } float scale(float x, int n) // formal parameters { float scaleFactor, solution; // local variable float num1; int num2; scaleFactor = pow(10, n); solution = x* scaleFactor; num1 = 9; num2 = 99; cout << "Test global, local in the function scale" << " num1 = " << num1 << " num2 = ” << num2 << endl; return solution; }
// File testScale_global_local_v2.cpp (p.140) // this version computes scale and save in the "result" // Tests function scale. #include <iostream> #include <cmath> using namespace std; // Function prototype float scale(float, int); //global variables float num1; int num2; int main() { float result; // changed here // Get values for num1 and num2 cout << "Enter a real number: "; cin >> num1; cout << "Enter an integer: "; cin >> num2; //function call result = scale(num1, num2); // actual arguments // Call scale and display result. cout << "Result of call to function scale is " << result << endl; cout << "Test global, local in the main” << " num1 = " << num1 << " num2 = ” << num2 <<end; return 0; } float scale(float x, int n) // formal parameters { float scaleFactor, solution; // local variable //float num1; //int num2; scaleFactor = pow(10, n); solution = x* scaleFactor; num1 = 9; num2 = 99; cout << "Test global, local in the function scale” << " num1 = " << num1 << " num2 = " << num2 << endl; return solution; }
Scope of Names • Positional correspondence • Type consistent is key because of positional correspondence • Argument types • Return types
Scope of Names • Type of a value returned by a called function must be consistent with the type expected by the caller as identified in the prototype • Type of an actual argument in a function call must be consistent with the type of its corresponding formal argument
Next Assignment • HOUSE • #include “money.cpp” • make sure that your should copy both money.cpp and money.h to the same folder that your source program resides • try to run (saved in the server) • house_Chen_Jason_money.exe