1 / 45

Data Structures and Algorithms Week 3 Data Abstraction Part I: Modules and Information Hiding

Data Structures and Algorithms Week 3 Data Abstraction Part I: Modules and Information Hiding. A Module. The use of modularization is part of the process of decomposing a single, large program. Modularization happens naturally when using stepwise refinement

Download Presentation

Data Structures and Algorithms Week 3 Data Abstraction Part I: Modules and Information Hiding

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. Data Structures and Algorithms Week 3Data Abstraction Part I:Modules and Information Hiding

  2. A Module • The use of modularization is part of the process of decomposing a single, large program. • Modularization happens naturally when using stepwise refinement • A function is a type of modularity. It is a collection of instructions and local data, all contributing to achieve the purpose of the function • A module is a collection of related items (functions, types, constants, and variables) packed into a separate compiled unit • It is organized so that programs and other functions can use all or part of the module

  3. Modules • A module normally has two parts: • The public view: It consists of the client programs can see from the module. It is sometimes called the interface. • The private view: Consists of the internal implementation of the functions and auxiliary functions that are used by the main ones • The goal when using modules is to encapsulate the internals of the functions and private data. • Encapsulation is the bundling together of all the information, capabilities, and responsibilities of an entity into a single unit • Encapsulation ensure that clients do not depend on implementation details

  4. Advantages of Separate Compilation of Modules • Modularization is only achievable if the language allows separate compilation • RE-USE: One module may be used by many clients. • EASE OF MODIFICATION: • Modules can be recompiled without recompiling the whole system • Conversely, clients can be modified and the modules do not need to be recompiled. • CONFIDENTIALITY: The module’s .cpp file may be removed and just its .obj code is left.

  5. module1.h module2.h module3.h mainprog.cpp module1.cpp module2.cpp module3.cpp COMPILER COMPILER COMPILER COMPILER Program with several modules

  6. mainprog.obj module1.obj module2.obj module3.obj LINKER mainprog.exe Object files are linked to form one executable file

  7. Modules in C++ • A module is represented by two files • <file>.h: This file is a C++ header file. It contains only declarations. Sometimes called the specification file • <file>.cpp: This file contains the executable instructions (the implementation of the header defined in the .hfile) and date. Normally called implementation file • The specification file is inserted into some other file via the #include directive. • It has to be included in the client and the module implementation file • Should be included using "filename.h" instead of <filename.h>

  8. Specification file ( .h) contains preprocessor directives #include “bool.h” #ifndef RAND_H constant declarations const float PI = 3.14159; const int TRUE = 1; type declarations typedef int Boolean; typedef char String20[21]; typedef String20 Names[100]; function prototypes with formal parameters including comments /* in */, /* out */, /* inout */, and PRE and POST assertions

  9. Specification file ( .h) does not contain • What should not appear in a specification file • Functions with bodies • Variable definitions

  10. Modules use 2 separate files // SPECIFICATION FILE ( power.h ) // // Specifies this module’s constants, types, // and functions. . . . // IMPLEMENTATION FILE ( power.cpp ) // // Implements this module’s functions. #include “power.h” . . .

  11. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // SPECIFICATION FILE ( power.h ) // This module provides exponentiation functions // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int power( /* in */ int someInt, /* in */ int exp ); //------------------------------------------------------------------------------------ // PRE: Assigned(someInt) && exp >= 0 // POST: FCTVAL == someInt raised to the power "exp" // (NOTE: Large exponents may produce overflow) //------------------------------------------------------------------------------------ float power( /* in */ float someFloat, /* in */ int exp ); //------------------------------------------------------------------------------------ // PRE: Assigned(someFloat) && Assigned(exp) // && (exp < 0) --> someFloat != 0.0 // POST: FCTVAL == someFloat raised to the power "exp" // (NOTE: Large exponents may produce overflow) //------------------------------------------------------------------------------------

  12. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // IMPLEMENTATION FILE ( power.cpp ) // This module provides exponentiation functions. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #include “ power.h” // also must appear in client code int power( /* in */ int someInt, /* in */ int exp ) { //------------------------------------------------------------------------------------ // PRE: Assigned(someInt) && exp >= 0 // POST: FCTVAL == someInt raised to the power "exp" // (NOTE: Large exponents may produce overflow) //------------------------------------------------------------------------------------ int i; int partialVal = 1; for (i = 1; i <= exp; i++) //----------------------------------------------------------------------------------- // INV (prior to test): // partialVal == someInt raised to power (i-1) // && i <= exp+1 //------------------------------------------------------------------------------------ partialVal *= someInt; return partialVal; }

  13. //------------------------------------------------------------------------------------//------------------------------------------------------------------------------------ // PRE: Assigned(someFloat) && Assigned(exp) && (exp < 0) --> someFloat != 0.0 // POST: FCTVAL == someFloat raised to the power "exp" // (NOTE: Large exponents may produce overflow) //------------------------------------------------------------------------------------ float power(/* in */float someFloat,/* in */int exp ) { if(exp < 0) {// Negative exponent means someFloat = (float)1.0/someFloat;// repeated division exp = -exp; } int i; float partialVal = 1.0; for (i = 1; i <= exp; i++) //------------------------------------------------------------------------------------ // INV (prior to test): // partialVal == someFloat<entry> raised to power (i-1) // && i <= abs(exp<entry>)+1 //------------------------------------------------------------------------------------ partialVal *= someFloat; return partialVal; }

  14. Using the Power Module //----------------------------------------------------------------------// powsof2.cpp// This program outputs the powers of 2 from 1 through 10.// NOTE: 2^n denotes 2 raised to the nth power//----------------------------------------------------------------------#include <iostream.h>#include <iomanip.h> // For setw()#include "powers.h" // For PowerOfInt()int main(){ int power; cout << " Power 2 ^ Power \n" << " ----- --------- \n"; for (power = 1; power <= 10; power++) // INV (prior to test): // 2^1, 2^2, ..., 2^(power-1) have been output // && power <= 11 cout << setw(10) << power << setw(13) << PowerOfInt(2, power) << '\n'; return 0;}

  15. Information Hiding • A consequence of using modules in C++ • The use of specification files (.h) and implementation files improves the concept of black boxes. • The black box idea is called in the OO world information hiding • The advantages of such an idea has been discussed in our previous classes • Software reuse • Improved communication among the developers • To improve information hiding avoid global variables and use the static keyword only when necessary

  16. A Case StudyA Password Module • The purpose is to manage password access • We'll try to use the main concepts discussed thus far. • Use of internal documentation • Use of modules • Specification file • Implementation file • Extending the language. Providing features for password as if it were a built in facility • Using information hiding

  17. Specification FilePassword.h #include "bool.h" // Defined later // PRE: Input is coming from the keyboard // POST: After a prompt, the user has supplied a password void getPassword(); // PRE: getPassword has been invoked previously && // Input is coming from the keyboard // POST: The user has been prompted to repeat the most // recently supplied password && // FCTVAL == TRUE, if the passwords are identical // == FALSE, otherwise Boolean validUser();

  18. Implementation FilePassword.cpp #include "bool.h" // Defined later #include "password.h" // Specification file #include <iostream> using std::cin; using std::cout; const int MAXLEN = 10; // Max password length static char passStr[MAXLEN+1]; // Updated as a global variable // PRE: Input is coming from the keyboard // POST: The user has typed a password which is, say, // "len" characters long (up to '\n') // && (len <= MAXLEN ) --> (passStr[0..len-1] == input string // && passStr[len] == '\0')&& (len > MAXLEN ) --> (passStr[0..MAXLEN-1] // == start of input string&& passStr[MAXLEN] == '\0') void getPassword() { cout << "Type password then <RETURN> (Max: " << MAXLEN << " --> "; cin.get(passStr, MAXLEN+1); cin.ignore(100, '\n'); // Previous "get" doesn't consume '\n' }

  19. Implementation File Password.cpp // PRE: passStr contains a string terminated by '\0'&& Input is coming from the // keyboard // POST: A user-input sequence of chars (thru '\n') has been read // && FCTVAL == TRUE, if the input chars up to '\n' equal the chars of // // passStr up to '\0'. FALSE, otherwise Boolean validUser() { char inChar; int i = 0; cout << "Type password then <RETURN> --> "; cin.get(inChar); while (inChar == passStr[i]) { // INV All passStr[0..i-1] match input i++; cin.get(inChar); } // ASSERT: inChar != passStr[i] if (inChar == '\n') // ASSERT: Input password may be valid return (passStr[i] == '\0'); else { // ASSERT: Input password definitely invalid cin.ignore(100, '\n'); // Consume chars through '\n' return FALSE; }

  20. Test File (Bottom-Up Test)TestPass.cpp #include "password.h" #include <iostream> using std::cout; int main() { getPassword(); // ASSERT: User has entered an initial password cout << "Please verify the password:\n"; if ( !validUser() ) { cout << "Verification failed!\n"; return 1; } return 0; }

  21. Specification file ( .h) purpose It is public interface of the module. It lists the module items that a client can use. We say the module exports these items.

  22. Implementation ( .cpp) file Must contain a function definition (both heading and body) for each function declared in the .h file of the module. It is considered the black box of the module which hides information details that the client does not need to know.

  23. C++ Standard Library • C++ is small • Most of the functions are not part of the language • Most of C++ environments follow some standard (ANSI/ISO) in what functions the provide. • C++ has a set of specification files, but the implementations are put together into Libraries (.lib files)

  24. C++ Standard Library • The most common specification files are: • iostream.h: Contains functions prototypes for the standard input and standard output functions. The header file for this is <iostream> • math.h: Contains function prototypes for math library functions. The header file is <cmath> • ctype.h: Contains function prototypes for functions that test characters for certain properties and for functions that can be used to convert lowercase letters to uppercase and vice versa. The header file is <cctype> • string.h: Contains functions prototypes for string processing functions. The header file is <cstring>

  25. C++ Standard Library • Some other specification files: • assert.h: Contains macros and information for adding diagnostics that aid debugging. The header file is <cassert> • time.h: Contains function prototypes for manipulating date and time. The header file is <ctime> • stdlib.h: Contains function prototypes for conversion of numbers to text, text to numbers and other utility functions. The header file is <cstdlib> • fstream.h: Contains function prototypes for functions that perform input from files on disk and output to files on disk. The header file is <fstream>

  26. Module interface diagram lists exported items Power module Implementation is hidden from view. Int Power Float Power

  27. Avoiding Multiple Inclusion of Header Files • Often several program files use the same header file containing typedef statements, constants, or type declarations. It is a compile-time error to define the same identifier twice. • This preprocessor directive syntax is used to avoid the compilation error that would otherwise occur from multiple uses of #include for the same header file. #ifndef Preprocessor_Identifier #define Preprocessor_Identifier . . . #endif

  28. Using Preprocessor Directive #ifndef FOR COMPILATION THE DECLARATIONS IN FILE bool.h WILL BE INCLUDED ONLY ONCE // bool.h // password.h // client.cpp // SPECIFICATION FILE // SPECIFICATION FILE // Main program #include “bool.h” #include “bool.h” #ifndef BOOL_H #include “password.h” #define BOOL_H int main ( void) typedef int Boolean; { const int TRUE = 1; . . . . . . const int FALSE = 0; } #endif

  29. Reserved word static • It is possible to declare within a function defination a local object that will persist for the entire duration of the program. • When the value of a local object must persist across invocations of the function, an ordinary automatic object cannot be used. • The solution is to declare the local object as static. • Though its value persists across invocations of it’s function, the visibility remains limited to it’s local scope.

  30. ctypemodule interface diagram ctype module isalpha isdigit islower tolower . . .

  31. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // SPECIFICATION FILE ( ctype.h ) // PRE: Assigned (ch) // - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int isalpha ( int ch ) ; // POST: FCTVAL is nonzero, if ch is a letter: ‘A’. .’Z’, ‘a’. .’z’ // == 0, otherwise int isdigit ( int ch ) ; // POST: FCTVAL is nonzero, if ch is a digit: ‘0’ . . ‘9’ // == 0, otherwise int islower ( int ch ) ; // POST: FCTVAL is nonzero, if ch is lowercase: ‘a’ . . ‘z’ // == 0, otherwise int tolower ( int ch ) ; // POST: FCTVAL == lowercase equivalent, if ch is uppercase // == ch, otherwise

  32. 6000 ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’ str [0] [1] [2] [3] [4] [5] [6] [7] Recall that . . . char str [ 8 ]; stris thebase addressof the array. We say str is a pointer because its value is an address. It “points” to the memory location of a char.

  33. 6000 ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’ str [0] [1] [2] [3] [4] [5] [6] [7] These are equivalent void SomeFunc ( char str[ ] ); // str is the base address of an array of char void SomeFunc( char* str ); // str is a pointer to an object of type char

  34. string module interface diagram string module strlen strcmp strcpy strcat

  35. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // SPECIFICATION FILE ( string.h ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unsigned strlen ( const char* str ) ; // PRE: str is a null-terminated string // POST: FCTVAL == length of str (not counting ‘\0’ ) int strcmp ( const char* str1, const char* str2 ) ; // PRE: str1 and str2 are null-terminated strings // POST: FCTVAL < 0, if str1 < str2 lexicographically // == 0, if str1 == str2 “ // > 0, if str1 > str2 “

  36. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // SPECIFICATION FILE continued ( string.h ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - char* strcpy ( char* toStr, const char* fromStr ) ; // PRE: fromStr is a null-terminated string // && toStr is large enough to hold the result // POST: fromStr, including ‘\0’ has overwritten toStr, // && FCTVAL == base address of toStr char* strcat ( char* toStr, const char* fromStr ) ; // PRE: toStr and fromStr are null-terminated strings // && toStr is large enough to hold the result // POST: fromStr, including ‘\0’ is joined to end of toStr, // && FCTVAL == base address of toStr

  37. Address pointer reference C++ Data Types Simple Structured Integral Floating array struct union class char short int long enum float double long double unsigned

  38. Data Abstraction • We've said already that algorithms depend on control abstraction and data abstraction • We've learned that control abstraction has to do with the order the instructions are executed. • Functional abstraction is important and separate the what from the how • Data abstraction consists in separating the data type (values and operations) from how the data type is implemented. Again we are separating the what from the how • It lets the programmer create data types that are not originally available in the language

  39. Abstract Data Types • Every data type has two characteristics: • A set of values • A collection of operations on these values • Take for instance the C++ int type • It has a set of values: -32768 to +32767 • It has a collection of operations: addition, subtraction, multiplication, etc. • The standard types do not include real world data such as a list of employees, a circle, a stack, etc. • Modern languages allow the implementation of ADTs which are programmer-defined types

  40. Abstract Data Types • The operations have to be appropriate to the type. • Take for instance a EmployeeList data type • Probably arithmetic operations are not appropriate • We need operations like • AddEmployee • DeleteEmployee • etc • To implement an ADT, the programmer must • choose a concrete data representation of the abstract data, using data types that already exist. These may include other ADTs • Implement each allowable operation in terms of program instructions

  41. Why our Password Module is NOT an ADT • It uses a concrete data representation • It has a set of operations defined • getPassword() • validUser() Why it is not considered an ADT? • Because the module export only a single password object • It is not possible for the importer to declare and manipulate several instances of password

  42. Data Abstraction is . . . • the separation of the properties of a data type (its value and operations) from the implementation of that data type. • PURPOSE -- to create new data types not built into the language and to create valid operations for objects (instances) of that type.

  43. LOGICAL PROPERTIES IMPLEMENTATION What are the possible values? How can this be done in C++? What operations will be needed? How can data types be used? Data Abstraction • Separates the logical properties of a data type from its implementation.

  44. Abstract Data Type Is a programmer-defined type with a set of values and allowable operations for the type. Some ways to define a new C++ type are: using typedef using struct using class

  45. Using typedef typedef int Boolean; typedef char String20 [21] ; String20 message; // variable declarations Boolean seniorCitizen;

More Related