Abstract Data Type C and Data Structures Baojian Hua

Slides:



Advertisements
Similar presentations
C and Data Structures Baojian Hua
Advertisements

The C ++ Language BY Shery khan. The C++ Language Bjarne Stroupstrup, the language’s creator C++ was designed to provide Simula’s facilities for program.
Data Structure & Abstract Data Type
Department of Computer Engineering Faculty of Engineering, Prince of Songkla University 1 5 – Abstract Data Types.
1 Classes and Data Abstraction Chapter What a Class ! ! Specification and implementation Private and public elements Declaring classes data and.
C Module System C and Data Structures Baojian Hua
Data Structure & Abstract Data Type C and Data Structures Baojian Hua
COMPSCI 105 S Principles of Computer Science 12 Abstract Data Type.
INF 212 ANALYSIS OF PROG. LANGS Type Systems Instructors: Crista Lopes Copyright © Instructors.
Polymorphism Discrete Mathematics and Its Applications Baojian Hua
Map, Set & Bit-Vector Discrete Mathematics and Its Applications Baojian Hua
Functions C and Data Structures Baojian Hua
1 Chapter 11 Structured Types, Data Abstraction and Classes Dale/Weems/Headington.
C and Data Structures Baojian Hua
Elaboration or: Semantic Analysis Compiler Baojian Hua
C Module System C and Data Structures Baojian Hua
C and Data Structures Baojian Hua
Standard ML- Part II Compiler Baojian Hua
String C and Data Structures Baojian Hua
Pointers and Arrays C and Data Structures Baojian Hua
C and Data Structures Baojian Hua
Linked List C and Data Structures Baojian Hua
Set, Map & Bit-Vector Discrete Mathematics and Its Applications Baojian Hua
Functional List C and Data Structures Baojian Hua
String C and Data Structures Baojian Hua
String C and Data Structures Baojian Hua
Structures, Unions, and Typedefs CS-2303, C-Term Structures, Unions, and Typedefs CS-2303 System Programming Concepts (Slides include materials from.
Set & Bit-Vector Discrete Mathematics and Its Applications Baojian Hua
Polymorphism C and Data Structures Baojian Hua
Generic Subroutines and Exceptions CS351 – Programming Paradigms.
Polymorphism Discrete Mathematics and Its Applications Baojian Hua
C++ fundamentals.
1 Using Classes Object-Oriented Programming Using C++ Second Edition 5.
Classes Mark Hennessy Dept. Computer Science NUI Maynooth C++ Workshop 18 th – 22 nd Spetember 2006.
Abstract Data Types Using Classes Lecture-5. Abstract Data Types Using Classes Representing abstract data types using C++ We need the following C++ keywords.
C++ Object Oriented 1. Class and Object The main purpose of C++ programming is to add object orientation to the C programming language and classes are.
CS (CCN 27241) Software Engineering for Scientific Computing Lecture 5: C++ Key Concepts.
Chapter 3 Introduction to Collections – Stacks Modified
Computer Science and Engineering College of Engineering The Ohio State University Interfaces The credit for these slides goes to Professor Paul Sivilotti.
Chapter 06 (Part I) Functions and an Introduction to Recursion.
Review C Language Features –control flow –C operators –program structure –data types –I/O and files Problem Solving Abilities.
Inheritance - Polymorphism ITI 1121 Nour El Kadri.
ABSTRACT DATA TYPES Data types, data structures, abstract data types, Java/C++ classes, C++ structs.
CSE 425: Data Types I Data and Data Types Data may be more abstract than their representation –E.g., integer (unbounded) vs. 64-bit int (bounded) A language.
CSC3315 (Spring 2008)1 CSC 3315 Subprograms Hamid Harroud School of Science and Engineering, Akhawayn University
ADTs and C++ Classes Classes and Members Constructors The header file and the implementation file Classes and Parameters Operator Overloading.
Simple Classes. ADTs A specification for a real world data item –defines types and valid ranges –defines valid operations on the data. Specification is.
Introduction to c++ programming - object oriented programming concepts - Structured Vs OOP. Classes and objects - class definition - Objects - class scope.
Abstraction ADTs, Information Hiding and Encapsulation.
CS Introduction to Data Structures Spring Term 2004 Franz Hiergeist.
Modularity Computer Science 3. What is Modularity? Computer systems are organized into components called modules. The extent to which this is done is.
Polymorphism Discrete Mathematics and Its Applications Baojian Hua
Separate Compilation Bryce Boe 2013/10/09 CS24, Fall 2013.
Slide 1 Chapter 6 Structures and Classes. Slide 2 Learning Objectives  Structures  Structure types  Structures as function arguments  Initializing.
72 4/11/98 CSE 143 Abstract Data Types [Sections , ]
ENEE150 – 0102 ANDREW GOFFIN Abstract Data Types.
Structs in C Computer Organization I 1 November 2009 © McQuain, Feng & Ribbens struct Properties The C struct mechanism is vaguely similar.
Structure A Data structure is a collection of variable which can be same or different types. You can refer to a structure as a single variable, and to.
Prof. I. J. Chung Data Structure #1 Professor I. J. Chung.
1 Chapter 12 Classes and Abstraction. 2 Chapter 12 Topics Meaning of an Abstract Data Type Declaring and Using a class Data Type Using Separate Specification.
Chapter 12 Classes and Abstraction
Inheritance Modern object-oriented (OO) programming languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design,
Structures and Classes
Classes C++ representation of an object
INTRODUCTION TO OBJECT-ORIENTED PROGRAMMING (OOP) & CONCEPTS
PRINCIPALES OF OBJECT ORIENTED PROGRAMMING
Classes and Data Abstraction
Object Oriented Practices
COP 3330 Object-oriented Programming in C++
Classes C++ representation of an object
Presentation transcript:

Abstract Data Type C and Data Structures Baojian Hua

Data Types A data type consists of: A collection of data elements (a type) A set of operations on these data elements Data types in languages: predefined: any language defines a group of predefined data types C e.g.: int, char, float, double, … user-defined: allow programmers to define their own (new) data types C e.g.: struct, union, …

Data Type Examples Predefined: type: int elements: …, -2, -1, 0, 1, 2, … operations: +, -, *, /, %, … User-defined: type: complex elements: 1+3i, -5+8i, … operations: new, add, sub, distance, …

Concrete Data Types (CDT) An concrete data type: both concrete representations and their operations are available Almost all C predefined types are CDT For instance, “ int ” is a 32-bit double-word, and +, -, … Knowing this can do dirty hacks See demo …

Abstract Data Types (ADT) An abstract data type: separates data type declaration from representation separates function declaration (prototypes) from implementation (definitions) A language must some form of mechanism to support ADT interfaces in Java signatures in ML (roughly) header files & typedef in C

Case Study Suppose we ’ d design a new data type to represent complex number c: a data type “ complex ” elements: 3+4i, -5-8i, … operations: new, add, sub, distance, … How to represent this data type in C (CDT, ADT or … )?

Complex Number // Recall the definition of a complex number c: c = x + yi, where x,y \in R, and i=sqrt(-1); // Some typical operations: complex Complex_new (double x, double y); complex Complex_add (complex c1, complex c2); complex Complex_sub (complex c1, complex c2); complex Complex_mult (complex c1, complex c2); complex Complex_divide (complex c1, complex c2); // Next, we’d discuss several variants of rep’s: // CDT, ADT.

CDT of Complex: Interface — Types // In file “complex.h”: #ifndef COMPLEX_H #define COMPLEX_H struct Complex_t { double x; double y; }; typedef struct Complex_t Complex_t; Complex_t Complex_new (double x, double y); // other function prototypes are similar … #endif

Client Code // With this interface, we can write client codes // that manipulate complex numbers. File “main.c”: #include “complex.h” int main () { Complex_t c1, c2, c3; c1 = Complex_new (3.0, 4.0); c2 = Complex_new (7.0, 6.0); c3 = Complex_add (c1, c2); Complex_output (c3); return 0; } Do we know c1, c2, c3’s concrete representation? How?

CDT Complex: Implementation // In a file “complex.c”: #include “complex.h” Complex_t Complex_new (double x, double y) { Complex_t c = {.x = x,.y = y}; return c; } // other functions are similar. See Lab1

Problem #1 int main () { Complex_t c; c = Complex_new (3.0, 4.0); // Want to do this: c = c + (5+i6); // Ooooops, this is legal: c.x += 5; c.y += 6; return 0; }

Problem #2 #ifndef COMPLEX_H #define COMPLEX_H struct Complex_t { // change to a more fancy one? Anger “main”… double a[2]; }; typedef struct Complex_t Complex_t; Complex_t Complex_new (double x, double y); // other function prototypes are similar … #endif

Problems with CDT? Operations are transparent. user code have no idea of the algorithm Good! Data representations dependence Problem #1: Client code can access data directly kick away the interface safe? Problem #2: make code rigid easy to change or evolve?

ADT of Complex: Interface — Types // In file “complex.h”: #ifndef COMPLEX_H #define COMPLEX_H // note that “struct complexStruct” not given typedef struct Complex_t *Complex_t; Complex_t Complex_new (double x, double y); // other function prototypes are similar … #endif

Client Code // With this interface, we can write client codes // that manipulate complex numbers. File “main.c”: #include “complex.h” int main () { Complex_t c1, c2, c3; c1 = Complex_new (3.0, 4.0); c2 = Complex_new (7.0, 6.0); c3 = Complex_add (c1, c2); Complex_output (c3); return 0; } Can we still know c1, c2, c3’s concrete representation? Why?

ADT Complex: Implementation#1 — Types // In a file “complex.c”: #include “complex.h” // We may choose to define complex type as: struct Complex_t { double x; double y; }; // which is hidden in implementation.

ADT Complex: Implementation Continued // In a file “complex.c”: #include “complex.h” Complex_t Complex_new (double x, double y) { Complex_t c; c = malloc (sizeof (*c)); c->x = x; c->y = y; return c; } // other functions are similar. See Lab1

ADT Summary Yes, that ’ s ADT! Algorithm is hidden Data representation is hidden client code can NOT access it thus, client code independent of the impl ’ Interface and implementation Do Lab1

Polymorphism To explain polymorphism, we start with a new data type “ tuple ” A tuple is of the form: (x, y) x  A, y  B (aka: A*B) A, B may be unknown in advance and may be different E.g: A=int, B=int: (2, 3), (4, 6), (9, 7), … A=char *, B=double: ( “ Bob ”, 145.8), ( “ Alice ”, 90.5), …

Polymorphism From the data type point of view, two types: A, B operations: new (x, y); // create a new tuple with x and y equals (t1, t2); // equality testing first (t); // get the first element of t second (t); // get the second element of t … How to represent this type in computers (using C)?

Monomorphic Version We start by studying a monomorphic tuple type called “ intTuple ” : both the first and second components are of “ int ” type (2, 3), (8, 9), … The intTuple ADT: type: intTuple elements: (2, 3), (8, 9), … Operations: tuple new (int x, int y); int first (int t); int second (tuple t); int equals (tuple t1, tuple t2); …

“ IntTuple ” CDT // in a file “int-tuple.h” #ifndef INT_TUPLE_H #define INT_TUPLE_H struct IntTuple_t { int x; int y; }; typedef struct IntTuple_t IntTuple_t; IntTuple_t IntTuple_new (int n1, int n2); int IntTuple_first (IntTuple_t t); … #endif

Or the “ IntTuple ” ADT // in a file “int-tuple.h” #ifndef INT_TUPLE_H #define INT_TUPLE_H typedef struct IntTuple_t *IntTuple_t; IntTuple_t IntTuple_new (int n1, int n2); int IntTuple_first (IntTuple_t t); int IntTuple_equals (IntTuple_t t1, IntTuple_t t2); … #endif // We only discuss “tupleEquals ()”. All others // functions left to you.

Equality Testing // in a file “int-tuple.c” int Tuple_equals (IntTuple_t t1, IntTuple_t t2) { return ((t1->x == t2->x) && (t1->y==t2->y)); } x y t1 x y t2

Problems? It ’ s ok if we only design “ IntTuple ” But we if we ’ ll design these tuples: (int, double), (int, char *), (double, double), … Same code exists everywhere, no means to maintain and evolve Nightmares for programmers Remember: never duplicate code!

Polymorphism Now, we consider a polymorphic tuple type called “ tuple ” : “ poly ” : may take various forms Every element of the type “ tuple ” may be of different types (2, 3.14), ( “ 8 ”, ‘ a ’ ), ( ‘ \0 ’, 99), … The “ tuple ” ADT: type: tuple elements: (2, 3.14), ( “ 8 ”, ‘ a ’ ), ( ‘ \0 ’, 99), …

The Tuple ADT What about operations? tuple new (??? x, ??? y); ??? first (tuple t); ??? second (tuple t); int equals (tuple t1, tuple t2); …

Polymorphic Type To resove this, C dedicates a special polymorphic type “ void * ” “ void * ” is a pointer which can point to “ any ” concrete types (i.e., it ’ s compatible with any pointer type), very poly … long history of practice, initially “ char * ” can not be used directly, use ugly cast similar to constructs in others language, such as “ Object ”

The Tuple ADT What about operations? tuple newTuple (void *x, void *y); void *first (tuple t); void *second (tuple t); int equals (tuple t1, tuple t2); …

“ tuple ” Interface // in a file “tuple.h” #ifndef TUPLE_H #define TUPLE_H typedef void *poly; typedef struct Tuple_t * Tuple_t; Tuple_t Tuple_new (poly x, poly y); poly first (Tuple_t t); poly second (Tuple_t t); int equals (Tuple_t t1, Tuple_t t2); #endif TUPLE_H

Client Code // file “main.c” #include “tuple.h” int main () { int i = 8; Tuple_t t1 = Tuple_new (&i, “hello”); return 0; }

“ tuple ” ADT Implementation // in a file “tuple.c” #include #include “tuple.h” struct Tuple_t { poly x; poly y; }; Tuple_t Tuple_new (poly x, poly y) { tuple t = malloc (sizeof (*t)); t->x = x; t->y = y; return t; } x y t

“ tuple ” ADT Implementation // in a file “tuple.c” #include #include “tuple.h” struct Tuple_t { poly x; poly y; }; poly Tuple_first (Tuple_t t) { return t->x; } x y t

Client Code #include “complex.h” // ADT version #include “tuple.h” int main () { int i = 8; Tuple_t t1 = Tuple_new (&i, “hello”); // type cast int *p = (int *)Tuple_first (t1); return 0; }

Equality Testing struct Tuple_t { poly x; poly y; }; // The #1 try: int Tuple_equals (Tuple_t t1, Tuple_t t2) { return ((t1->x == t2->x) && (t1->y == t2->y)); // Wrong!! } x y t

Equality Testing struct Tuple_t { poly x; poly y; }; // The #2 try: int Tuple_equals (Tuple_t t1, Tuple_t t2) { return (*(t1->x) == *(t2->x) && *(t1->y) == *(t2->y)); // Problem? } x y t

Equality Testing struct Tuple_t { poly x; poly y; }; // The #3 try: int Tuple_equals (Tuple_t t1, Tuple_t t2) { return (equalsXXX (t1->x, t2->x) && equalsYYY (t1->y, t2->y)); // but what are “equalsXXX” and “equalsYYY”? } x y t

Function as Arguments // So in the body of “equals” function, instead // of guessing the types of t->x and t->y, we // require the callers of “equals” supply the // necessary equality testing functions. // The #4 try: typedef int (*tf)(poly, poly); int Tuple_equals (tuple t1, tuple t2, tf eqx, tf eqy) { return (eqx (t1->x, t2->x) && eqy (t1->y, t2->y)); }

Change to “ tuple ” Interface // in file “tuple.h” #ifndef TUPLE_H #define TUPLE_H typedef void *poly; typedef int (*tf)(poly, poly); typedef struct Tuple_t *Tuple_t; Tuple_t Tuple_new (poly x, poly y); poly Tuple_first (Tuple_t t); poly Tuple_second (Tuple_t t); int Tuple_equals (Tuple_t t1, Tuple_t t2, tf eqx, tf eqy); #endif TUPLE_H

Client Code // in file “main.c” #include “tuple.h” int main () { int i=8, j=8, k=7, m=7; Tuple_t t1 = Tuple_new (&i, &k); Tuple_t t2 = Tuple_new (&j, &k); Tuple_equals (t1, t2, Int_equals, Int_equals); return 0; }

Moral void* serves as polymorphic type in C mask all pointer types (think Object type in Java) Pros: code reuse: write once, used in arbitrary context we ’ d see more examples later in this course Cons: Polymorphism doesn ’ t come for free boxed data: data heap-allocated (to cope with void *) no static or runtime checking (at least in C) clumsy code extra function pointer arguments

Function-Carrying Data Why we can NOT make use of data, such as passed as function arguments, when it ’ s of type “ void * ” ? Better idea: Let data carry functions themselves, instead passing function pointers such kind of data called objects

Function Pointer in Data int Tuple_equals (Tuple_t t1, Tuple_t t2) { // note that if t1->x or t1->y has carried the // equality testing functions, then the code // could just be written as: return (t1->x->equals (t1->x, t2->x) && t1->y->equals (t1->y, t2->y)); } equals …… equals_y x y t1 equals …… equals_x

Function Pointer in Data // To cope with this, we should modify other // modules. For instance, the “complex” ADT: struct Complex_t { int (*equals) (poly, poly); double a[2]; }; Complex_t Complex_new (double x, double y) { Complex_t c = malloc (sizeof (*c)); c->equals = Complex_equals; …; return n; } x n equals y

Function Call int Tuple_equals (Tuple_t t1, Tuple_t t2) { return (t1->x->equals (t1->x, t2->x) && t1->y->equals (t1->y,t2->y)); } a[0] equals a[0] t2 a[1] x y t1 x y

Client Code // in file “main.c” #include “complex.h” #include “tuple.h” int main () { Complex_t c1 = Complex_new (1.0, 2.0); Complex_t c2 = Complex_new (1.0, 2.0); Tuple_t t1 = Tuple_new (c1, c2); Tuple_t t2 = Tuple_new (c1, c2); Tuple_equals (t1, t2); // dirty simple! :-P return 0; }

Object Data elements with function pointers is the simplest form of objects object = virtual functions + private data With such facilities, we can in principal model object oriented programming In fact, early C++ compilers compiles to C That ’ s partly why I don ’ t love object- oriented languages

Summary Abstract data types enable modular programming clear separation between interface and implementation interface and implementation should design and evolve together Polymorphism enables code reuse Object = data + function pointers