1 Generics Professor Jennifer Rexford

Slides:



Advertisements
Similar presentations
Introduction to C Programming
Advertisements

C Structures and Memory Allocation There is no class in C, but we may still want non- homogenous structures –So, we use the struct construct struct for.
Introduction to Linked Lists In your previous programming course, you saw how data is organized and processed sequentially using an array. You probably.
David Notkin Autumn 2009 CSE303 Lecture 13 This space for rent.
What is a pointer? First of all, it is a variable, just like other variables you studied So it has type, storage etc. Difference: it can only store the.
Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
Stacks Example: Stack of plates in cafeteria.
Review of Stacks and Queues Dr. Yingwu Zhu. Our Focus Only link-list based implementation of Stack class Won’t talk about different implementations of.
. Smart Pointers. Memory Management u One of the major issues in writing C/C++ code is managing dynamically allocated memory u Biggest question is how.
1 Pointers A pointer variable holds an address We may add or subtract an integer to get a different address. Adding an integer k to a pointer p with base.
ECE 353: Lab C Pointers and Structs. Basics A pointer holds an address to some variable Notation: – Dereferencing operator: * int *x is a declaration.
6/10/2015C++ for Java Programmers1 Pointers and References Timothy Budd.
CS414 C Programming Tutorial Ben Atkin
1 Abstract Data Types (ADTs) Professor Jennifer Rexford COS 217.
Stacks CS-240 Dick Steflik. Stacks Last In, First Out operation - LIFO As items are added they are chronologically ordered, items are removed in reverse.
. Plab – Tirgul 2 Const, C Strings. Pointers int main() { int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; ijx 1.
1 1 Lecture 4 Structure – Array, Records and Alignment Memory- How to allocate memory to speed up operation Structure – Array, Records and Alignment Memory-
CS 61C L03 C Arrays (1) A Carle, Summer 2005 © UCB inst.eecs.berkeley.edu/~cs61c/su05 CS61C : Machine Structures Lecture #3: C Pointers & Arrays
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
Lesson 6 Functions Also called Methods CS 1 Lesson 6 -- John Cole1.
1 Modularity The material for this lecture is drawn, in part, from The Practice of Programming (Kernighan & Pike) Chapter 4.
1 Function Pointers and Abstract Data Types Professor Jennifer Rexford COS 217.
CS 106 Introduction to Computer Science I 04 / 30 / 2010 Instructor: Michael Eckmann.
1 Procedural Concept The main program coordinates calls to procedures and hands over appropriate data as parameters.
C Arrays and Pointers In Java, pointers are easy to deal with –In fact, there is little that can go wrong in Java since pointer access is done for you.
11 Values and References Chapter Objectives You will be able to: Describe and compare value types and reference types. Write programs that use variables.
1 CISC181 Introduction to Computer Science Dr. McCoy Lecture 19 Clicker Questions November 3, 2009.
P Object type and wrapper classes p Object methods p Generic classes p Interfaces and iterators Generic Programming Data Structures and Other Objects Using.
C Programming Tutorial – Part I CS Introduction to Operating Systems.
CS212: Object Oriented Analysis and Design Lecture 6: Friends, Constructor and destructors.
Compiler Construction
Object Oriented Programming Elhanan Borenstein copyrights © Elhanan Borenstein.
224 3/30/98 CSE 143 Recursion [Sections 6.1, ]
C Functions Pepper. Objectives Create functions Function prototypes Parameters – Pass by value or reference – Sending a reference Return values Math functions.
Constructors CMSC 202. Object Creation Objects are created by using the operator new in statements such as… The following expression invokes a special.
1 Pointers and Strings Chapter 5 2 What You Will Learn...  How to use pointers Passing arguments to functions with pointers See relationship of pointers.
Java Basics.  To checkout, use: svn co scb07f12/UTORid  Before starting coding always use: svn update.
Object Oriented Programming Elhanan Borenstein Lecture #10 copyrights © Elhanan Borenstein.
1 Data Structures. 2 Motivating Quotation “Every program depends on algorithms and data structures, but few programs depend on the invention of brand.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved Stacks.
Review of Stacks and Queues Dr. Yingwu Zhu. How does a Stack Work? Last-in-First-out (LIFO) data structure Adding an item Push operation Removing an item.
Topic 3: C Basics CSE 30: Computer Organization and Systems Programming Winter 2011 Prof. Ryan Kastner Dept. of Computer Science and Engineering University.
Generic lists Vassilis Athitsos. Problems With Textbook Interface? Suppose that we fix the first problem, and we can have multiple stacks. Can we have.
Computer Organization and Design Pointers, Arrays and Strings in C Montek Singh Sep 18, 2015 Lab 5 supplement.
1 Chapter 6 Methods. 2 Motivation Find the sum of integers from 1 to 10, from 20 to 30, and from 35 to 45, respectively.
CMSC 202 Advanced Section Classes and Objects: Object Creation and Constructors.
Pointers in C++. Topics Covered  Introduction to Pointers  Pointers and arrays  Character Pointers, Arrays and Strings  Examples.
1 Modularity Heuristics The material for this lecture is drawn, in part, from The Practice of Programming (Kernighan & Pike) Chapter 4 Jennifer Rexford.
ICOM 4035 – Data Structures Dr. Manuel Rodríguez Martínez Electrical and Computer Engineering Department Lecture 2 – August 23, 2001.
Week 7 Part I Kyle Dewey. Overview Code from last time Array initialization Pointers vs. arrays Structs typedef Bubble sort (if time)
Java & C++ Comparisons How important are classes and objects?? What mechanisms exist for input and output?? Are references and pointers the same thing??
LECTURE LECTURE 17 Templates 19 An abstract recipe for producing concrete code.
Computer Organization and Design Pointers, Arrays and Strings in C
C Programming Tutorial – Part I
Learning Objectives Pointers Pointer in function call
The material for this lecture is drawn from Princeton COS217.
Arrays in C.
Lecture 6 C++ Programming
Stack ADT & Modularity 2 implementations of the Stack abstract data type: Array Linked List Program design: modularity, abstraction and information hiding.
Chapter 15 Pointers, Dynamic Data, and Reference Types
Pointers, Dynamic Data, and Reference Types
Lecture 18 Arrays and Pointer Arithmetic
CISC101 Reminders Assn 3 due tomorrow, 7pm.
Parameters and Overloading
Java Programming Language
Modularity Jennifer Rexford
Abstract Data Types (ADTs), After More on the Heap
Generics Jennifer Rexford.
ENERGY 211 / CME 211 Lecture 8 October 8, 2008.
SPL – PS2 C++ Memory Handling.
Presentation transcript:

1 Generics Professor Jennifer Rexford

2 Goals of this Lecture Help you learn about: Generic modules Data structures that can store multiple types of data Functions that can work on multiple types of data How to create generic modules in C Which wasn’t designed with generic modules in mind! Why? Reusing existing code is easier/cheaper than writing new code; reuse reduces software costs Generic modules are more reusable than non-generic ones A power programmer knows how to create generic modules A power programmer knows how to use existing generic modules to create large programs

3 Generic Data Structures Example Recall Stack module from last lecture Items are strings (type char*) /* stack.h */ typedef struct Stack *Stack_T; Stack_T Stack_new(void); void Stack_free(Stack_T s); void Stack_push(Stack_T s, const char *item); char *Stack_top(Stack_T s); void Stack_pop(Stack_T s); int Stack_isEmpty(Stack_T s);

4 Generic Data Structures Example Stack operations (push, pop, top, etc.) make sense for items other than strings too So Stack module could (and maybe should) be generic Problem: How to make Stack module generic? How to define Stack module such that a Stack object can store items of any type?

5 Generic Data Structures via typedef Solution 1: Let clients define item type /* client.c */ struct Item { char *str; /* Or whatever is appropriate */ }; … Stack_T s; struct Item item; item.str = "hello"; s = Stack_new(); Stack_push(s, item); … /* stack.h */ typedef struct Item *Item_T; typedef struct Stack *Stack_T; Stack_T Stack_new(void); void Stack_free(Stack_T s); void Stack_push(Stack_T s, Item_T item); Item_T Stack_top(Stack_T s); void Stack_pop(Stack_T s); int Stack_isEmpty(Stack_T s);

6 Generic Data Structures via typedef Problem: Awkward for client to define structure type and create structures of that type Problem: Client (or some other module in same program) might already use “Item_T” for some other purpose! Problem: Client might need two Stack objects holding different types of data!!! We need another approach…

7 Generic Data Structures via void* Solution 2: The generic pointer (void*) /* stack.h */ typedef struct Stack *Stack_T; Stack_T Stack_new(void); void Stack_free(Stack_T s); void Stack_push(Stack_T s, const void *item); void *Stack_top(Stack_T s); void Stack_pop(Stack_T s); int Stack_isEmpty(Stack_T s);

8 Generic Data Structures via void* Can assign a pointer of any type to a void pointer /* client.c */ … Stack_T s; s = Stack_new(); Stack_push(s, "hello"); … OK to match an actual parameter of type char* with a formal parameter of type void* /* stack.h */ typedef struct Stack *Stack_T; Stack_T Stack_new(void); void Stack_free(Stack_T s); void Stack_push(Stack_T s, const void *item); void *Stack_top(Stack_T s); void Stack_pop(Stack_T s); int Stack_isEmpty(Stack_T s);

9 Generic Data Structures via void* Can assign a void pointer to a pointer of any type /* client.c */ char *str; … Stack_T s; s = Stack_new(); Stack_push(s, "hello"); … str = Stack_top(s); OK to assign a void* return value to a char* /* stack.h */ typedef struct Stack *Stack_T; Stack_T Stack_new(void); void Stack_free(Stack_T s); void Stack_push(Stack_T s, const void *item); void *Stack_top(Stack_T s); void Stack_pop(Stack_T s); int Stack_isEmpty(Stack_T s);

10 Generic Data Structures via void* Problem: Client must know what type of data a void pointer is pointing to Solution: None Void pointers subvert the compiler’s type checking Programmer’s responsibility to avoid type mismatches /* client.c */ int *i; … Stack_T s; s = Stack_new(); Stack_push(s, "hello"); … i = Stack_top(s); Client pushes a string Client considers retrieved value to be a pointer to an int! Legal!!! Trouble!!!

11 Generic Data Structures via void* Problem: Stack items must be pointers E.g. Stack items cannot be of primitive types (int, double, etc.) Solution: none In C, there is no mechanism to create truly generic data structures (In C++: Use template classes and template functions) (In Java: Use generic classes) /* client.c */ … int i = 5; … Stack_T s; s = Stack_new(); … Stack_push(s, 5); … Stack_push(s, &i); Not OK to match an actual parameter of type int with a formal parameter of type void* OK, but awkward

12 Generic Algorithms Example Suppose we wish to add another function to the Stack module /* stack.h */ typedef struct Stack *Stack_T; Stack_T Stack_new(void); void Stack_free(Stack_T s); void Stack_push(Stack_T s, const void *item); void *Stack_top(Stack_T s); void Stack_pop(Stack_T s); int Stack_isEmpty(Stack_T s); int Stack_areEqual(Stack_T s1, Stack_T s2); Returns 1 (TRUE) iff s1 and s2 are equal, that is, contain equal items in the same order

13 Generic Algorithm Attempt 1 Attempt 1 Checks if s1 and s2 are identical, not equal Compares pointers, not items That’s not what we want /* stack.c */ … int Stack_areEqual(Stack_T s1, Stack_T s2) { return s1 == s2; } /* client.c */ char str1[] = "hi"; char str2[] = "hi"; Stack_T s1 = Stack_new(); Stack_T s2 = Stack_new(); Stack_push(s1, str1); Stack_push(s2, str2); if (Stack_areEqual(s1,s2)) { … } Returns 0 (FALSE) Incorrect!

14 Addresses vs. Values Suppose two locations in memory have the same value The addresses of the variables are not the same That is “(&i == &j)” is FALSE Need to compare the values themselves That is “(i == j)” is TRUE Unfortunately, comparison operation is type specific The “==“ works for integers and floating-point numbers But not for strings and more complex data structures int i=5; int j=5; 5 5 i j

15 Generic Algorithm Attempt 2 Attempt 2 Checks if nodes are identical Compares pointers, not items That is still not what we want /* stack.c */ … int Stack_areEqual(Stack_T s1, Stack_T s2) { struct Node *p1 = s1->first; struct Node *p2 = s2->first; while ((p1 != NULL) && (p2 != NULL)) { if (p1 != p2) return 0; p1 = p1->next; p2 = p2->next; } if ((p1 != NULL) || (p2 != NULL)) return 0; return 1; } /* client.c */ char str1[] = "hi"; char str2[] = "hi"; Stack_T s1 = Stack_new(); Stack_T s2 = Stack_new(); Stack_push(s1, str1); Stack_push(s2, str2); if (Stack_areEqual(s1,s2)) { … } Returns 0 (FALSE) Incorrect!

16 Generic Algorithm Attempt 3 Attempt 3 Checks if items are identical Compares pointers to items, not items themselves That is still not what we want /* stack.c */ … int Stack_areEqual(Stack_T s1, Stack_T s2) { struct Node *p1 = s1->first; struct Node *p2 = s2->first; while ((p1 != NULL) && (p2 != NULL)) { if (p1->item != p2->item) return 0; p1 = p1->next; p2 = p2->next; } if ((p1 != NULL) || (p2 != NULL)) return 0; return 1; } /* client.c */ char str1[] = "hi"; char str2[] = "hi"; Stack_T s1 = Stack_new(); Stack_T s2 = Stack_new(); Stack_push(s1, str1); Stack_push(s2, str2); if (Stack_areEqual(s1,s2)) { … } Returns 0 (FALSE) Incorrect!

17 Generic Algorithm Attempt 4 Attempt 4 Checks if items are equal That’s what we want But strcmp() works only if items are strings! We need Stack_areEqual() to be generic How to compare values when we don’t know their type? /* stack.c */ … int Stack_areEqual(Stack_T s1, Stack_T s2) { struct Node *p1 = s1->first; struct Node *p2 = s2->first; while ((p1 != NULL) && (p2 != NULL)) { if (strcmp(p1->item, p2->item) != 0) return 0; p1 = p1->next; p2 = p2->next; } if ((p1 != NULL) || (p2 != NULL)) return 0; return 1; } /* client.c */ char str1[] = "hi"; char str2[] = "hi"; Stack_T s1 = Stack_new(); Stack_T s2 = Stack_new(); Stack_push(s1, str1); Stack_push(s2, str2); if (Stack_areEqual(s1,s2)) { … } Returns 1 (TRUE) Correct!

18 Generic Algorithm via Function Pointer Approach 5 Add parameter to Stack_areEqual() Pointer to a compare function, which… Accepts two const void * parameters, and… Returns an int Allows client to supply the function that Stack_areEqual() should call to compare items /* stack.h */ typedef struct Stack *Stack_T; Stack_T Stack_new(void); void Stack_free(Stack_T s); void Stack_push(Stack_T s, const void *item); void *Stack_top(Stack_T s); void Stack_pop(Stack_T s); int Stack_isEmpty(Stack_T s); int Stack_areEqual(Stack_T s1, Stack_T s2, int (*cmp)(const void *item1, const void *item2));

19 Generic Algorithm via Function Pointer Approach 5 (cont.) Definition of Stack_areEqual() uses the function pointer to call the client-supplied compare function Stack_areEqual() “calls back” into client code /* stack.c */ … int Stack_areEqual(Stack_T s1, Stack_T s2, int (*cmp)(const void *item1, const void *item2)) { struct Node *p1 = s1->first; struct Node *p2 = s2->first; while ((p1 != NULL) && (p2 != NULL)) { if ((*cmp)(p1->item, p2->item) != 0) return 0; p1 = p1->next; p2 = p2->next; } if ((p1 != NULL) || (p2 != NULL)) return 0; return 1; }

20 Generic Algorithm via Function Pointer Approach 5 (cont.) Client defines “callback function”, and passes pointer to it to Stack_areEqual() Callback function must match Stack_areEqual() parameter exactly /* client.c */ int strCompare(const void *item1, const void *item2) { char *str1 = item1; char *str2 = item2; return strcmp(str1, str2); } … char str2[] = "hi"; Stack_T s1 = Stack_new(); Stack_T s2 = Stack_new(); Stack_push(s1, str1); Stack_push(s2, str2); if (Stack_areEqual(s1,s2,strCompare)) { … } Returns 1 (TRUE) Correct! Client passes address of strCompare() to Stack_areEqual()

21 Generic Algorithm via Function Pointer Alternative: Client defines more “natural” callback function, and casts it to match Stack_areEqual() parameter Approach 5 (cont.) /* client.c */ int strCompare(const char *str1, const char *str2) { return strcmp(str1, str2); } … char str2[] = "hi"; Stack_T s1 = Stack_new(); Stack_T s2 = Stack_new(); Stack_push(s1, str1); Stack_push(s2, str2); if (Stack_areEqual(s1, s2, (int (*)(const void*, const void*))strCompare)) { … } Cast operator

22 Generic Algorithm via Function Pointer Approach 5 (cont.) Alternative (for string comparisons only): Simply use strcmp() with cast! /* client.c */ … char str2[] = "hi"; Stack_T s1 = Stack_new(); Stack_T s2 = Stack_new(); Stack_push(s1, str1); Stack_push(s2, str2); if (Stack_areEqual(s1, s2, (int (*)(const void*, const void*))strcmp)) { … } Cast operator

23 SymTable Aside Consider SymTable (from Assignment 3)… Q: Should a SymTable object own its values? A: No. The SymTable module is generic with respect to values So a SymTable object does not know the types of its values So it cannot create copies of them (unless the client supplies a “copy” function) So (by the “Resources” heuristic from the Modularity lecture) it should not free them

24 Summary Generic data structures Via item typedef Safe, but not realistic Via the generic pointer (void*) Limiting: items must be pointers Dangerous: subverts compiler type checking The best we can do in C (See C++ template classes and Java generics for other approaches) Generic algorithms Via function pointers and callback functions

25 Appendix: Wrappers Can we make void * functions safer? /* hotel.h */ Typedef struct Room Room; void RoomStack_push(Stack_T s, const Room *item); Room *RoomStack_top(Stack_T s); int RoomStack_areEqual(Stack_T s1, Stack_T s2); /* hotel.c */ void RoomStack_push(Stack_T s, const Room *item) { Stack_push(s, item); } Room *RoomStack_top(Stack_T s){ return Stack_top(s); } int RoomStack_areEqual(Stack_T s1, Stack_T s2) { return Stack_areEqual(s1, s2, RoomCompare); }

26 Faster Wrappers Move it to the header Make it static and inline Let the compiler sort it out /* hotel.h */ Typedef struct Room Room; static inline void RoomStack_push(Stack_T s, const Room *item) { Stack_push(s, item); } static inline Room *RoomStack_top(Stack_T s) { return Stack_top(s); } static inline int RoomStack_areEqual(Stack_T s1, Stack_T s2) { return Stack_areEqual(s1, s2, RoomCompare); }

27 What About The Stack Itself? Previous approach only protected Room Only rooms could be pushed Stack was not specific Any valid stack could be provided to functions Still possible to confuse stacks Result: stacks of mixed types Worse: gives impression that output always a Room Solution: typecast the stack /* stack.h */ typedef struct Stack *Stack_T; Typedef struct RoomStack *RoomStack_T Stack_T Stack_new(void); static inline RoomStack_T RoomStack_new(void) { return ((RoomStack_T) Stack_new()); }