1 / 34

ICOM 4015 Advanced Programming

ICOM 4015 Advanced Programming. Lecture 2 Procedural Abstraction Reading: LNN Chapter 4, 14. Prof. Bienvenido Velez. Procedural Abstraction Topics. Topic 1 Functions as abstract contracts Parameter passing Scoping Topic 2 Functional arguments Topic 3 Top-down modular design

greenfield
Download Presentation

ICOM 4015 Advanced Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ICOM 4015 Advanced Programming Lecture 2 Procedural Abstraction Reading: LNN Chapter 4, 14 Prof. Bienvenido Velez ICOM 4015 - Lecture 2

  2. Procedural AbstractionTopics • Topic 1 • Functions as abstract contracts • Parameter passing • Scoping • Topic 2 • Functional arguments • Topic 3 • Top-down modular design • Stepwise refinement • Topic 4 • Recursive functions • Recursion vs. Iteration • Topic 5 • Further procedural abstraction • Function overloading and templates ICOM 4015 - Lecture 2

  3. Procedural Abstraction I Outline • Functions as abstract contracts • Value/Reference parameters • Procedural Abstraction Defined • Scope Rules ICOM 4015 - Lecture 2

  4. Example 0Finding the roots of ax2 +bx + c #include <cmath> // roots(a, b, c, r1, r2) - returns the number of // real roots of ax^2 + bx + c. If two roots exists // they are returned is r1 and r2. If only one root // exists, it is returned in r1. Otherwise the value // of r1 and r2 is undetermined. int roots(float a, float b, float c, float& r1, float& r2) { float d = b * b - 4.0 * a * c; if (d < 0) { return 0; } r1 = (-b + sqrt(d)) / (2.0 * a); if (d == 0) { return 1; } r2 = (-b - sqrt(d)) / (2.0 * a); return 2; } WHAT? formal parameters HOW? roots.cc definitions int roots(float a, float b, float c,float& r1, float& r2); roots.h declarations ICOM 4015 - Lecture 2

  5. Procedural Abstraction • A function should accomplish ONEwell defined and easy to remember task • A function establishes a contract between callers and implementers • The implementer may select any implementation that satisfies the contract. • The contract should specify WHAT task the function accomplishes, NOT HOW it accomplishes it “HOW” is hidden or abstracted out, hence the name procedural abstraction ICOM 4015 - Lecture 2

  6. Scope Rules &Parameter Passing Mechanisms #include <iostream> // Forward definitions int f(int& x); // Global definitions static int x = 0; int y = 0; int main() { for (int i=0; i < 5; i++) { int arg = x; int r = f(x); cout << " f(" << arg << ") -> " << r; cout << " Glob x=" << x << endl; cout << " Glob y=" << y << endl; } } int f(int& x) { int y=0; static int z=0; y++; z+=2; x = y + z; cout << " Loc x=" << x; cout << " Loc y=" << y; cout << " Loc z=" << z; return z; } Global in Module Global Local to For Loop Local to Block Local to Function [bvelez@amadeus] ~ >> scope1 Loc x=3 Loc y=1 Loc z=2 f(0) -> 2 Glob x=3 Glob y=0 Loc x=5 Loc y=1 Loc z=4 f(3) -> 4 Glob x=5 Glob y=0 Loc x=7 Loc y=1 Loc z=6 f(5) -> 6 Glob x=7 Glob y=0 Loc x=9 Loc y=1 Loc z=8 f(7) -> 8 Glob x=9 Glob y=0 Loc x=11 Loc y=1 Loc z=10 f(9) -> 10 Glob x=11 Glob y=0 [bvelez@amadeus] ~ >> ICOM 4015 - Lecture 2

  7. Diagramas de Bloques x: y: main: for: i: arg: r: f: x: y: z: ICOM 4015 - Lecture 2

  8. Procedural Abstraction ISummary of Concepts • Value parameters – changes remain local to function. Function works with a copy of the argument. • Reference parameters – changes propagate to argument. Function works with original argument. • Procedural abstraction – a function establishes a contract with its callers on what it accomplishes, hiding how it accomplishes it. ICOM 4015 - Lecture 2

  9. Procedural Abstraction I - ScopingSummary of Concepts II • Definition: Scope of a declaration • region of code where declaration is active • Scope rules allow better control over the namespace • Local namespaces (e.g. functions, blocks) independent of each other • Local declarations take precedence over global declarations ICOM 4015 - Lecture 2

  10. Procedural Abstraction II Outline • Procedural arguments ICOM 4015 - Lecture 2

  11. IntegrationWithout Procedural Arguments #include <iostream> // Forward definitions double integrateSqr(double a, double b, double n); double integrateCube(double a, double b, double n); int main() { cout << "Integral of x^2 in [0,1] = " << integrateSqr(0.0, 1.0, 10000) << endl; cout << "Integral of x^3 in [0,1] = " << integrateCube(0.0, 1.0, 10000) << endl; } double integrateSqr(double a, double b, double n) { double delta = (b-a) / double(n); double sum = 0.0; for (int i=0; i<n; i++) { float x = a + delta * i; sum += x * x * delta; } return sum; } double integrateCube(double a, double b, double n) { double delta = (b-a) / double(n); double sum = 0.0; for (int i=0; i<n; i++) { float x = a + delta * i; sum += x * x * x * delta; } return sum; } [bvelez@amadeus] ~/icom4015/lec05 >> example2 Integral of x^2 in [0,1] = 0.333283 Integral of x^3 in [0,1] = 0.24995 [bvelez@amadeus] ~/icom4015/lec05 >> ICOM 4015 - Lecture 2

  12. Example 3 IntegrationWith Procedural Arguments #include <iostream> // Forward definitions double integrate(double a, double b, double n, double f(double x)); double cube(double x); double sqr(double x); int main() { cout << "Integral of x^2 in [0,1] = " << integrate(0.0, 1.0, 10000, sqr) << endl; cout << "Integral of x^3 in [0,1] = " << integrate(0.0, 1.0, 10000, cube) << endl; } double integrate(double a, double b, double n, double f(double x)) { double delta = (b-a) / double(n); double sum = 0.0; for (int i=0; i<n; i++) { sum += f(a + delta * i) * delta; } return sum; } double cube(double x) { return x * x * x; } double sqr(double x) { return x * x; } [bvelez@amadeus] ~/icom4015/lec05 >> example2 Integral of x^2 in [0,1] = 0.333283 Integral of x^3 in [0,1] = 0.24995 [bvelez@amadeus] ~/icom4015/lec05 >> ICOM 4015 - Lecture 2

  13. Procedural Abstraction IIFunctional ArgumentsSummary of Concepts • Functional arguments • Allow abstraction over processes and functions ICOM 4015 - Lecture 2

  14. Procedural Abstraction III Outline • Top-down stepwise refinement ICOM 4015 - Lecture 2

  15. Step 0 - Outline // top-down.cc // Computes weighted average score of grades. Grades // include two assignments two midterm exams and one final exam. // All grades are input from standard input, but the weights of // each type of grade are hard coded. // C header files extern "C" { } // Standard C++ header files #include <iostream> // My own C++ header files // Macro definitions // Forward definitions of auxiliary functions // Global declarations // Main function int main() { // Read assignment grades // Read exam grades // Read final exam grade // Calculate average // Print report return 0; } // Auxiliary functions ICOM 4015 - Lecture 2

  16. Step 1 – Code + Stubs int main() { float assignment1, assignment2; float exam1, exam2; float finalExam; readAssignmentGrades(assignment1, assignment2); readExamGrades(exam1, exam2); readFinalGrade(finalExam); float avg; avg = calculateAverage(assignment1, assignment2, exam1, exam2, finalExam); printReport(assignment1, assignment2, exam1, exam2, finalExam, avg); return 0; } // Auxiliary functions void readAssignmentGrades(float& assignment1, float& assignment2) {} void readExamGrades(float& ex1, float& ex2) {} void readFinalGrade(float& final) {} float calculateAverage(float assignment1, float assignment2, float exam1, float exam2, float finalExam) {} void printReport(float assignment1, float assignment2, float exam1, float exam2, float finalExam, float average) {} ICOM 4015 - Lecture 2

  17. Step 2 - Refine // Auxiliary functions void readAssignmentGrades(float& assignment1, float& assignment2) { // Read a float in [0,100] into assignment1 // Read a float in [0,100] into assignment2 } void readExamGrades(float& ex1, float& ex2) { // Read a float in [0,100] into ex1 // Read a float in [0,100] into ex2 } void readFinalGrade(float& final) { // Read a float in [0,100] into final } float calculateAverage(float assignment1, float assignment2, float exam1, float exam2, float finalExam) { // Calculate assignments average // Calculate exams average // Calculate weighted average } void printReport(float assignment1, float assignment2, float exam1, float exam2, float finalExam, float average) { // print assignment grades // print exam grades // print final exam grades // print weighted average } ICOM 4015 - Lecture 2

  18. Top-down stepwise refinement cycle outline refine code + stubs ICOM 4015 - Lecture 2

  19. Procedural Abstraction IIITop-down design – Stepwise RefinementSummary of Concepts • Top-Down design / stepwise refinement • A cyclic development technique • Each cycle adds a level of detail to the code • We have a functioning (although incomplete) program after every iteration of the process ICOM 4015 - Lecture 2

  20. Procedural Abstraction IV Outline • Recursive Functions • Activation records, call stacks • Expressiveness of recursion vs. iteration • Efficiency concerns • function call overhead • duplication of work • process complexity ICOM 4015 - Lecture 2

  21. Example 0Factorials // factorials.cc // Implements recursive and interative versions of algorithms for // computing the factorial (N!) of a number. // Standard C++ header files #include <iostream> // Forward definitions of auxiliary functions long recFactorial(long n); long iterFactorial(long n); int main() { long number; while(true) { cout << "Please enter a positive number (or negative to end): "; cin >> number; if (number < 0) return 0; cout << "Recursive: " << number << "! = " << recFactorial(number) << endl; cout << "Iterative: " << number << "! = " << iterFactorial(number) << endl; } } long recFactorial(long n) { if (n==0) { return 1; } else { return (n * recFactorial(n - 1)); } } long iterFactorial(long n) { long product = 1; for (long i=1; i<=n; i++) { product *= i; } return product; } [bvelez@amadeus] ~/icom4015/lec07 >>factorials Please enter a positive number (or negative to end): 3 Recursive: 3! = 6 Iterative: 3! = 6 Please enter a positive number (or negative to end): 4 Recursive: 4! = 24 Iterative: 4! = 24 Please enter a positive number (or negative to end): 5 Recursive: 5! = 120 Iterative: 5! = 120 Please enter a positive number (or negative to end): 6 Recursive: 6! = 720 Iterative: 6! = 720 Please enter a positive number (or negative to end): -1 [bvelez@amadeus] ~/icom4015/lec07 >>fibonacci ICOM 4015 - Lecture 2

  22. Example 1Fibonacci Numbers // fibonacci.cc // Iterative and recursive algorithms for computing Fibonacci numbers ... // Auxiliary Functions long recFibonacci(long n) { if (n==0) { return 0; } else if (n==1) { return 1; } else { return (recFibonacci(n-1) + recFibonacci(n-2)); } } long iterFibonacci(long n) { if (n==0) { return 0; } else if (n==1) { return 1; } long F0 = 0; long F1 = 1; long FN; for (long i=1; i<n; i++) { FN = F0 + F1; F0 = F1; F1 = FN; } return FN; } [bvelez@amadeus] ~/icom4015/lec07 >>fibonacci Please enter a positive number (or negative to end): 3 Recursive: F(3) = 2 Iterative: F(3) = 2 Please enter a positive number (or negative to end): 4 Recursive: F(4) = 3 Iterative: F(4) = 3 Please enter a positive number (or negative to end): 8 Recursive: F(8) = 21 Iterative: F(8) = 21 Please enter a positive number (or negative to end): ICOM 4015 - Lecture 2

  23. Example 1Fibonacci Numbers // fibonacci.cc // Iterative and recursive algorithms for computing Fibonacci numbers // Standard C++ header files #include <iostream> // Forward definitions of auxiliary functions long recFibonacci(long n); long iterFibonacci(long n); int main() { long number; while(true) { cout << "Please enter a positive number (or negative to end): "; cin >> number; if (number < 0) return 0; cout << "Recursive: F(" << number << ") = " << recFibonacci(number) << endl; cout << "Iterative: F(" << number << ") = " << iterFibonacci(number) << endl; } } … … ... ICOM 4015 - Lecture 2

  24. Procedural Abstraction IV Iteration vs. RecursionSummary of Concepts • Recursion is as expressive as iteration • Iteration can yield faster code • less duplication of work • less function call overhead • Recursion can yield cleaner code • may rely on a “smart” optimizing compiler to minimize call overhead ICOM 4015 - Lecture 2

  25. Procedural Abstraction V Outline • Further procedural abstraction • Function overloading • Function templates ICOM 4015 - Lecture 2

  26. Function OverloadingSQR Function Family int intSqr (int x) { return x * x } long longSqr(long x) { return x * x; } float floatSqr(float x) { return x * x } Without overloading int sqr (int x) { return x * x } long sqr(long x) { return x * x; } float sqr(float x) { return x * x } With overloading ICOM 4015 - Lecture 2

  27. Function Templates SQR Function Family int sqr (int x) { return x * x } long sqr(long x) { return x * x; } float sqr(float x) { return x * x } With overloading template <class T> T sqr (T x) { return x * x } With templates ICOM 4015 - Lecture 2

  28. SQR’aring different types // Standard C++ header files #include <iostream> #include <iomanip> // Forward definitions of local auxiliary functions template <class T> T sqr(T x); // Main function int main() { cout << " i" << " sqr(i)" << " sqr(float(i))" << " sqr(double(i))" << endl; for (int i=0; i<10; i++) { cout << setw(16) << i << setw(16) << sqr(i) << setw(16) << sqr(float(i)) << setw(16) << sqr(double(i)) << endl; } } // Local auxiliary functions template <class T> T sqr(T x) { return x * x; } Templates can reduce code duplication dramatically ICOM 4015 - Lecture 2

  29. Output [bvelez@amadeus] ~/icom4015/lec09 >>sqr i sqr(i) sqr(float(i)) sqr(double(i)) 0 0 0 0 1 1 1 1 2 4 4 4 3 9 9 9 4 16 16 16 5 25 25 25 6 36 36 36 7 49 49 49 8 64 64 64 9 81 81 81 [bvelez@amadeus] ~/icom4015/lec09 >> ICOM 4015 - Lecture 2

  30. Anatomy of a Function Template T is a type parameter template <class T> function Inside this function T represents any type Templates are C++’s implementation of Parametric Polymorphism ICOM 4015 - Lecture 2

  31. Example 2 // Standard C++ header files #include <iostream> #include <iomanip> // Forward definitions of local auxiliary functions template <class T> void swap(T& a, T& b); template <class T> void doSwap(T a, T b); // Main function int main() { cout << "***** doSwap(1,0)" << endl; doSwap(1,0); cout << endl << endl << "***** doSwap(1.0/3.0, 2.0/3.0)" << endl; doSwap(1.0/3.0, 2.0/3.0); cout << endl << endl << "***** doSwap(true, false)" << endl; doSwap("hello", "world"); } // Local auxiliary functions template <class T> void doSwap(T a, T b) { T x = a; T y = b; cout << "x = " << x << " y = " << y << endl; swap(x,y); cout << "swap(x,y)" << endl; cout << "x = " << x << " y = " << y << endl; swap(x,y); cout << "swap(x,y)" << endl; cout << "x = " << x << " y = " << y << endl; } template <class T> void swap(T& a, T& b) { T temp = a; a = b; b = temp; } Variable declaration of type T ICOM 4015 - Lecture 2

  32. Example 2 Output [bvelez@amadeus] ~/icom4015/lec09 >>swap ***** doSwap(1,0) x = 1 y = 0 swap(x,y) x = 0 y = 1 swap(x,y) x = 1 y = 0 ***** doSwap(1.0/3.0, 2.0/3.0) x = 0.333333 y = 0.666667 swap(x,y) x = 0.666667 y = 0.333333 swap(x,y) x = 0.333333 y = 0.666667 ***** doSwap(true, false) x = hello y = world swap(x,y) x = world y = hello swap(x,y) x = hello y = world ICOM 4015 - Lecture 2

  33. Procedural Abstraction V Function OverloadingSummary of Concepts • Related functions can be grouped under a common name • Overloaded functions may have different return types, but must have different parameters. • The importance of overloading will become clearer when we get into classes and object-oriented programming ICOM 4015 - Lecture 2

  34. Procedural Abstraction V Function TemplatesSummary of Concepts • Programmer declares one function parameterized over some type T • Compiler instantiates potentially many functions for all the different argument types provided among all function calls • Instances must be well typed, that is, all objects should only be used according to their types. ICOM 4015 - Lecture 2

More Related