Download presentation
Presentation is loading. Please wait.
Published byPresley Stobbe Modified over 9 years ago
1
Abstraction, Modularity, Interfaces and Pointers Original slides by Noah Mendelsohn, including content from Mark Sheldon, Noah Daniels, Norman Ramsey COMP 40: Machine Structure and Assembly Language Programming
2
© 2010 Noah Mendelsohn We will weave together a story about Abstraction, modularity, reuse, clean interfaces, information hiding C Language Pointers Is it obvious these are related at all?
3
© 2010 Noah Mendelsohn Abstract and Concrete Types
4
© 2010 Noah Mendelsohn Software structures model real world objects and concepts Integers Students Bank statements Photographic images Sound recordings Etc. 4 These things aren’t bits They don’t live in computers, but…
5
© 2010 Noah Mendelsohn Software structures model real world objects and concepts Integers Students Bank statements Photographic images Sound recordings Etc. 5 We build data structures that model them
6
© 2010 Noah Mendelsohn Collections are especially interesting Arrays of Integer temperature measurements Queues of Students waiting to register for classes Sorted lists of Bank statements Etc. 6
7
© 2010 Noah Mendelsohn 7 Today we will focus on good ways of modeling Abstract Data Types like lists, sets, queues, etc. Doing that, we’ll learn a lot about programming with pointers and types in C
8
© 2010 Noah Mendelsohn Key principles to watch for Abstraction –Refers to the act of “pulling away from” something so that unimportant details are hidden” 1 Modularity & clean interfaces –Each module “does one thing well” 2 Information hiding –Modules keep details of their internals secret –This makes them more modular: why? Generalization –When practical, each module or service should be as generally useful as possible 8 1 Prof. Mark Sheldon – COMP 11 Big IdeasCOMP 11 Big Ideas 2 Ken Thompson, co-inventor of Unix – The Unix PhilosophyThe Unix Philosophy
9
© 2010 Noah Mendelsohn What are the benefits of software like this? Easier to use Easier to reuse Easier to replace Easier to reason about correctness Easer to test Easier to maintain Etc., etc. 9
10
© 2010 Noah Mendelsohn Abstraction Clean Interfaces Information Hiding
11
© 2010 Noah Mendelsohn Interfaces (Recall picture from Comp 11) 11 Interface Implementation Client E.g. your fgroups program E.g. implementation of Hanson Table_T E.g. methods in Hanson table.h
12
© 2010 Noah Mendelsohn Interfaces 12 Interface Implementation Client Many different programs can re-use the interface and the implementation!
13
© 2010 Noah Mendelsohn Interfaces 13 Interface Implementation Client The implementation chooses a representation … NOT visible to the client
14
© 2010 Noah Mendelsohn Interfaces 14 Interface Implementation Client We can build different implementations without the client knowing Why reimplement? One might be small, one might be fast, etc. Bug fixes We might figure out a better way next year
15
© 2010 Noah Mendelsohn Information Hiding
16
© 2010 Noah Mendelsohn Interfaces 16 Interface Implementation Client To make this work we must… …hide details of the implementation from the client!
17
© 2010 Noah Mendelsohn Interfaces 17 Interface Implementation Client To make this work we must… …hide details of the client from the implementation!
18
© 2010 Noah Mendelsohn Interfaces 18 Interface Implementation Client Build interfaces that cleanly model the service or abstract data…
19
© 2010 Noah Mendelsohn 19 In your COMP 40 design documents, we expect you to carefully observe these distinctions… …your description of an interface should never mention implementation details …your description of use of an interface should never mention implementation details.
20
© 2010 Noah Mendelsohn Using Pointers to Represent Objects and Keep Secrets
21
© 2010 Noah Mendelsohn Most pointer declarations include type of the referent 21 #include int main(int argc, char *argv[]) { (void)argc; (void)argv; int x = 3; int y; int *ptr; ptr = &x; y = *ptr; printf("y = %d\n", y); exit(EXIT_SUCCESS); } Pointer to an integer
22
© 2010 Noah Mendelsohn 22 #include int main(int argc, char *argv[]) { (void)argc; (void)argv; int x = 3; int y; void *ptr; ptr = &x; y = *ptr; printf("y = %d\n", y); exit(EXIT_SUCCESS); } Void pointers are to unknown type void * Compiler knows it’s a pointer. Compiler does not know what type it points to.
23
© 2010 Noah Mendelsohn Void pointers are to unknown type 23 #include int main(int argc, char *argv[]) { (void)argc; (void)argv; int x = 3; int y; void *ptr; ptr = &x; y = *ptr; printf("y = %d\n", y); exit(EXIT_SUCCESS); } Compile error!! Can’t assign value of unknown type (*ptr) to integer y. void * Compiler knows it’s a pointer. Compiler does not know what type it points to.
24
© 2010 Noah Mendelsohn But we can tell the compiler the type 24 #include int main(int argc, char *argv[]) { (void)argc; (void)argv; int x = 3; int y; void *ptr; ptr = &x; y = *((int *)ptr); printf("y = %d\n", y); exit(EXIT_SUCCESS); } FIXED! We can use a cast (in this case ((int *)ptr) to tell the compiler the type it should assume
25
© 2010 Noah Mendelsohn Void pointers let us do some very important things! Make our code more general – work with any type of data Keep secrets 25 But why would we want to keep secrets?
26
© 2010 Noah Mendelsohn Interfaces 26 Interface Implementation Client E.g. your fgroups program E.g. implementation of Hanson Table_T E.g. methods in Hanson table.h My client isn’t supposed to see internals of Hanson’s table, but Hanson needs to give us something….what can we use?
27
© 2010 Noah Mendelsohn Interfaces 27 Interface Implementation Client E.g. your fgroups program E.g. implementation of Hanson Table_T E.g. methods in Hanson table.h My_table = Table_new(… … …) Q. What can Table_new return? I will show you two ways of doing this A.A pointer to data you can’t look at You will use this pointer to identify the new table
28
© 2010 Noah Mendelsohn Using void * pointers 28 /* Declare the type Table_t to be a (void *) */ typedef void *Table_t; /* Define Table_new to return one of those (void *) */ Table_t Table_new(… … … …); This is a pretty good solution: Client can’t see details of what’s in Hanson’s structure When Hanson gets the pointer back, he can assign it to a Table_T and use it
29
© 2010 Noah Mendelsohn Client doesn’t know secret implementation 29 Interface Implementation Client my_table = Table_new(… … …) Struct Table_t { …data declartions… } struct Table_T *table_ptr; void *table_ptr;
30
© 2010 Noah Mendelsohn Using void * pointers 30 /* Declare the type Table_t to be a (void *) */ typedef void *Table_t; /* Define Table_new to return a (void *) */ Table_t Table_new(… … … …); This is a pretty good solution: Client can’t see details of what’s in Hanson’s structure When Hanson gets the pointer back, he can assign it to a Table_T and use it But it doesn’t catch this mistake in the client… myTable = List_new(…); Table_put(myTable, … … …)
31
© 2010 Noah Mendelsohn We can do better with incomplete structures 31 typedef struct Table_T *Table_t; Tricky…we’re exposing the structure’s name, but not it’s contents…C calls this an incomplete structure. You cannot declare a variable with an incomplete type. You can declare a variable that’s a pointer to an incomplete type! Declare the type Table_t to be a pointer to a struct whose contents are unspecified:
32
© 2010 Noah Mendelsohn We can do better with incomplete structures 32 typedef struct Table_T *Table_t; /* Table_new returns ptr to incomplete struct */ Table_t Table_new(… … … …); Tricky…we’re exposing the structure’s name, but not it’s contents…C calls this an incomplete structure.
33
© 2010 Noah Mendelsohn Client doesn’t know secret implementation 33 Interface Implementation Client my_table = Table_new(… … …) Struct Table_t { …data declartions… } struct Table_T *table_ptr; struct Table_t *table_ptr; Client has incomplete declaration of the struct
34
© 2010 Noah Mendelsohn We can do better with incomplete structures 34 typedef struct Table_T *Table_t; Table_t Table_new(… … … …); This is a better solution: Client can’t see details of what’s in Hanson’s structure When Hanson gets the pointer back, it just works It does catch this mistake…you should figure out why! myTable = List_new(…); Table_put(myTable, … … …)
35
© 2010 Noah Mendelsohn Generalization
36
© 2010 Noah Mendelsohn You’ve already seen some generalization 36 int square3() { return 3 * 3; } We don’t do this int square(int n) { return n * n; } We do this! Generalize over input value Can we generalize over the type of information?
37
© 2010 Noah Mendelsohn We need to generalize over types 37 List_of_students_new(…); List_of_cars_new(…); List_of_bank_stmts_new(…); We don’t want this List_new(…); We want this! How do we declare the input to List_push()? (after all, its type could be anything) Can we generalize over the type of information?
38
© 2010 Noah Mendelsohn Void * allows us to generalize over types 38 void List_push(List_T list, void *x); Hanson’s declaration for List_push The list will remember a pointer to anything. struct Car {char *brand; int weight;}; typedef struct Car Car; List_T mylist = List_list(NULL); Car *retrieved_car; Car mycar = {"ford", 2000}; mylist = List_push(mylist, &mycar); mylist = List_pop(mylist, (void **)&retrieved_car); List_free(&mylist); Any pointer can be passed to a pointer-to-void parameter
39
© 2010 Noah Mendelsohn Void * allows us to generalize over types 39 void List_push(List_T list, void *x); Hanson’s declaration for List_push struct Car {char *brand; int weight;}; typedef struct Car Car; List_T mylist = List_list(NULL); Car *retrieved_car; Car mycar = {"ford", 2000}; mylist = List_push(mylist, &mycar); mylist = List_pop(mylist, (void **)&retrieved_car); List_free(&mylist); IMPORTANT: Retrieved_car_p is already a pointer. Why do we have to pass the address of retrieved_car_p?
40
© 2010 Noah Mendelsohn Void * allows us to generalize over types 40 void List_push(List_T list, void *x); Hanson’s declaration for List_push struct Car {char *brand; int weight;}; typedef struct Car Car; List_T mylist = List_list(NULL); Car *retrieved_car; Car mycar = {"ford", 2000}; mylist = List_push(mylist, &mycar); mylist = List_pop(mylist, (void **)&retrieved_car); List_free(&mylist); This generalization is known as universal polymorphism
41
© 2010 Noah Mendelsohn Review Abstraction, modularity, reuse, clean interfaces, information hiding C Language Pointers It should be clear now that these are related
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.