Title: CS31012 Programming Languages C Lecture 5
1CS3101-2Programming Languages CLecture 5
- Matthew P. Johnson
- Columbia University
- Fall 2003
2Agenda
- hw3 was due last night
- Today
- Templates
- Exceptions
- Other odds and ends
- The STL
- Grading and the final
- hw4 TBA tonight
3Templates
- Often want to do basically the same thing with
different things - functions work on variables
- only types specified
- ? algorithmic thinking
- ? computer science
- ? functionalism in phil. of mind
- ? abstraction
- human the rational animal (Aristotle)
- Sometimes want to do basically the same thing
with different types of things - Queue of ints, queue of widgets
- abstract data types
4max functions
- Suppose want the max of two numbers
- What kind of numbers?
- ints
- chars
- floats
- doubles
- All!
- How?
5max functions
- Soln 1 Write one, maxly general function
- double max(double a, double b)
- return a gt b ? a b
-
- double x max(2.5, 3.5)
- char c (char)max(A,B)
- This works but its not nice
- All four types can widen to doubles
- but must be cast back
6max functions
- Soln 2 Write one function for each type
- int max(int a, int b)
- return a gt b ? a b
-
- double max(
- etc.
- Is allowed in C (though not in C)
- But manually duplicating code
- for nontrivial ftns bad
- hard to maintain
7max functions
- Soln 3 Use the C preprocessor macros
- define max(a,b) (a gt b ? a b)
- C source code is preprocessed
- includes replaced with header files
- ifndef, etc.
- macro calls replaced with macro content
- int c max(2,3) ?
- int c (2 gt 3 ? 2 3)
- Works too, but complications, e.g.
- z max(x, y) ?
- z (x gt y ? x y)
- x, y inc-ed twice
- Need many parens sq(ab), etc.
8max functions
- Soln 4 Use the CPP in a more sophisticated way
- Dont use the CPP to generate expressions but to
generate functions - define define_max(t) \
- t max(t a, t b) \
- return a gt b ? a b\
-
- define_max(char)
- define_max(int) etc. no
- Avoids prev. CPP problems
- But reqs code for all poss types
- Done manually
9Templates
- template ltclass Tgt result ftn(param-list)
- The place-holder for the substituted type is t
- template and class are used as keywords
- can use typename in place of class
- T is a type
- Primitive or class
- All occurrences in ftn replaced with real type
10max functions
- Soln 5 use templates
- parameterized function
- expands per type as necessary
- templatelttypename Tgt
- T max(T a, T b)
- return a gt b ? a b
-
- Now can simply call the ftn
- x max(2.5,3.5)
- Compiler autoly creates only the
- ftn specializations needed
11Sorting things
- Consider problem of sorting
- Sorting ints
- Sorting doubles
- Sorting strings
- Sorting widgets
- Point of sorting put list in order
- Q What does in order mean?
- A Given an ordering relation lt on the members
- For x and y, tells whether x lt y
- Reorder s.t. x is before y iff x lt y
12Generic sorting
- Sort alg doesnt depend of element type
- Merge sort, quick sort, etc.
- Need only give means to compare to elms
- How?
- In C we pass in a pointer to a compare ftn
- void qsort(void base, int n, int size, int
(cmp)(const void , void )) - Pass in pointer to ftn
- int cmp(const void a, void b)
- Widget w1 (Widget)a
-
- Works, but very awkward
13Generic sorting
- In Java, we pass a Comparable implementer
- In the sort ftn we say
- if (a.compareTo(b) lt 0)
- // means a lt b
- Objects must implement this interface
- compare with ftn call
- Primitives cant implement
- Compared with ops
- could put in wrappers
14Generic sorting
- C soln 1 Define our own Comparable analog
abstract class - Has virtual compareTo
- Or, better has virtual lt gt operators
- Any class extending our class can now be sorted
- Pass in array of Comparable-extending objects
- Sort uses polymorphism to treat as (mere)
Comparables - Downside can only sort objects if they extend
Comparable - Mult inher can always add Comp parent,
- but must do so
- To sort primitives
- must create wrapper classes
15Generic sorting
- C soln 2 use templates!
- Let sort take an array of some arb. kind
- Dont need Comparable
- Dont need compareTo
- In sort, just say
- if (a lt b)
- If these are numbers, this works
- If these are objects that overload
- ops, this works
- Only requirement
- kind supports lt gt ops
16Templates swapping
- Remember our swap-with-ptrs ftn?
- void swap(int a, int b)
- int temp c a
- a b
- b a
-
- Suppose we want to swap other types
- ? templates
17Generic swapping
- template ltclass Tgtvoid swap(T a, T
b) - T temp c a
- a b
- b a
-
- Now can swap any prim
- Can also swap any objects
- As long as op is public
18Fancier swapping
- Remember our fancier swap ftn?
- void swap(int a, int b)
- a b a b
-
- Fancier template function
- template ltclass Tgtvoid swap(T a, T b)
- a b a b
-
- Now can swap ints, chars, longs
- But cannot swap objects
- Unless their is overloaded unlikely
19Template specialization
- string s,t max(s,t) works
- But max(hi,there) doesnt
- if (hi lt there) compares two pointers -
where the chars start - Not what we mean
- Soln create a specialization
- special version for this case
- We check for spec. before template
- char max(char a, char b)
- return strcmp(a,b) gt 0 ?
- a b
20Class templates
- Couple weeks ago wrote a stack class
- supported only integers
- Well abstract element type away
- Abstract data types
- Only changes to declar
- prepend on class dfn
- template ltclass Tgtclass className
- 2. Replace int ? T
- For ftn implems, we
- prepend the same
- replace className with classNameltTgt
- Replace int ? T
- template ltclass Tgt
- void StackltTgtpush(const T elm)
- To instantiate
- Stackltstringgt strStack
21Class specialization
- Similarly, can specialize member functions of
class templates - void stackltchargtpush(const char const item)
- datacount item
-
22Templates statics
- Review static data members
- one inst shared by all class insts
- What about statics in templates classes?
- Q Could one inst be shared by all insts?
- A No consider
- template ltclass Tgt class C
- static T mem
-
- mem couldnt me shared by all insts
- shared by all insts
- But for Cltintgt, mem shared by
- all Cltintgt insts
23Templates friends
- Given class, can declare some outside ftn or
class its friend - We have a stack class
- Suppose want to declare external sort ftn its
friend - Before had stack with ints
- could use sort ftn based on ints
- Now have StackltTgt
- friend is template too
- template ltclass Tgt
- class Stack
- friend void CltTgtf5(XltTgt)
24Odds and ends Forward declarations
- Suppose classes Cat and Dog each depend on each
other - class Cat
- void look(Dog d) cout ltlt Meow!\n
- class Dog
- void look(Cat c) cout ltlt Bark!\n
- Q Will this compile?
- A No - Dog is referenced before declared
- Soln a forward declaration
- Put class Dog before Cat def
- Dog not yet complete but
- Dog will now be recognized, w/o Cat depend.
25Namespaces
- int i
- namespace Example
- double PI 3.14 int i 8
- void printVals()
- namespace Inner int i 9
- // no semi-colon!
- Can access
- Examplei, ExampleInneri
- printVals implementation
- void ExampleprintVals()
- i is Examplei
- i is the global I
-
26Namespaces
- Now can use
- Example
- ExampleInner
- ExampleInneri
- Examplei
- Nested namespaces Java packages
- Unfortly include (CPP) / using (C)
independent - In general, use maximally narrow ranges
- Prevent ambiguity
- Dont say using namespace std
- Or can fully specify reference
- stdstd ltlt stdendl
27assert
- Old days bad thing happens
- writing to bad memory address
- divide by 0, etc.
- ? core dump, maybe dont notice, etc.
- void Stackpush(const int item)
- datacount item
-
- no room ? overwrite wrong data, crash, etc.
- Somewhat better assert that everything is okay
- assert(count gt 0 count lt sizeof(data)/sizeof(
data0)) - Everythings okay, right?
- If false, we quit with message of
- false expression
28Exceptions
- Now to some extent
- bad behavior is prevented
- attempt ? exception
- If bad things happen
- we halt, tell calling ftn
- maybe it halts, tells its calling ftn
- eventually, either
- someone responds accordingly or
- main ftn passes to OS
- try throw catch
- try to do something
- maybe an exception gets thrown
- if so, we may catch it, and go on
29Exception handling
- void Stackpush(const int item) throws
BoundExp - if (count lt 0 count gt
- sizeof(data)/sizeof(data0))
- throw BoundExp(stack overflow)
- datacount data //ok if here
-
- What is BoundExp?
- A class we define
30Our exception
- class BoundExp exception
- public
- BoundExp(const string s) exception(s)
-
- NB Its just a class
- Its parent is exception but neednt be
- Exception has what()
- maybe other info
31Throwing and catching
- try
- Stack s
- s.push(25)
-
- catch (BoundExp exp) cout ltlt Error ltlt
exp.what() ltlt \n - catch (ExpType2 exp)
- // can catch mult kinds
- // only catch lt 1
-
- catch () // is a wildcard!
- cout ltlt Unknown exception
- caught.\n
-
32Exception classes
- ltexceptiongt exception
- ltstdexceptgt
- runtime_error, logic_error
- bad_alloc new failed
- bad_cast dynamic_cast failed
- Can throw non-exception objs
- And even primitives
- But handling easer if dont
33STL
- Ceteris paribus, libraries are good
- Hard, subtle problems ? many mistakes
- dont re-invent the wheel
- Unless were wheel artists
- better to commodify the wheel
- Use an off-the-shelf wheel like everyone else
- The standard wheel is reliable and efficient
- STL Starbucks of programming
- Lots of important algorithms,
- data structures in CS
- Barring good reason
- use std versions
34Standard Template Library
- Many template classes, functions
- Abstract data types
- Three general categories
- Containers
- Iterators
- Algorithms
- Three kinds of containers
- Sequences
- Associative
- Adapted
35STL first-class containers
- Sequences
- vector Dynamic-array-backed
- const-time random-access
- const-time insert/delete at back
- deque double-ended queue
- fast random-access - how?
- fast insert/delete at front and back
- list doubly-linked list
- fast insert/delete anywhere
- Associative
- set non-sequential, unique
- multiset non-sequential, non-unique
- map maps from keys to unique values
- multimap maps to non-unique values
36STL containers
- Container adapters
- use first-class containers by composition
- stack LIFO
- queue FIFO
- priority_queue
- Near-containers
- arrays
- string
- bitset
- valarray
37Container member ops ftns
- copy constructor
- empty()
- size()
- swap
- First-class
- begin()
- end()
- rbegin()
- rend()
- erase
- clear()
NB These are allow very simple - little more
than getters
38STL Iterators
- Standard way to traverse through container
iteration - Abstraction of both index and pointer
- just means of iterating
- forward, back, etc.
- Iterator direction types
- Forward iterator
- Reverse iterator
- both supported by vector, list, etc.
- Random-access iterator
- supported by vector
- Also its can be const or not
39Types of iterators
- I/O iterators are one-pass
- can only move in one direction
- can only traverse once p
- Other types
- bidirectional p, p--
- random-access p i, p - i, pi (pi), p1 lt p2
- vector random-access
- deque random-access
- list bidirectional
- set/multiset bidirectional
- map/multimap bidirectional
40vector class
- Most commonly used container class
- Fast random access
- random-access iterators
- Can access mems
- with s like arrays unsafe
- with at(i) checks bounds, throws exception
safer - Essentially dynamic array hidden in obj
- add to/delete from back const time
- unless run out of space
- ? autoly copy to larger array
- insert/del from middle linear time
- must move half of mems forward/back
41Vectors ltvectorgt
- Similar to Javas Vector in that
- dynamic-array-backed list
- same complexities
- Different in that
- takes insts of specified type
- vectorltintgt nums
- vectorltdoublegt vals(20)
- size-20 vector of doubles
- vectorltBasegt objs
- takes Base objects
- vectorltBasegt ptrs
- takes Bases or Extendeds
42Template errors can be illegible
- Consider this ftn
- template ltclass Tgt
- void printReverse(const vectorltTgt vect)
- for (vectorltTgtreverse_iterator curr
vect.rbegin() - curr ! vect.rend() curr)
- cout ltlt curr ltlt ","
-
- Slightly different from before
- how?
43Template errors can be illegible
- When compiled
- Error E2034 c\Borland\Bcc55\include\rw/iterator.h
442 Cannot convert 'const int ' to 'int ' in
function reverse_iteratorltint gtreverse_iterator
(const reverse_iteratorltconst int gt ) - Error E2094 vect.cpp 19 'operator!' not
implemented intype 'reverse_iteratorltint gt' for
arguments of type 'reverse_iteratorltconst int gt'
in function printReverseltintgt(const
vectorltint,allocatorltintgt gt ) - Error E2034 c\Borland\Bcc55\include\rw/iterator.h
442 Cannot convert 'const int ' to 'int ' in
function reverse_iteratorltint gtreverse_iterator
(const reverse_iteratorltconst int gt ) - Warning W8057 c\Borland\Bcc55\include\rw/iterator
.h 442 Parameter 'x' is never used in function
reverse_iteratorltint gtreverse_iterator(const
reverse_iteratorltconst int gt ) - 3 errors in Compile
- Why? reverse_iterator not const_reverse_iterator
44Vectors e.g. vect.cpp
- template ltclass Tgt
- ostream opltlt(ostream out, const vectorltTgt
vect) - out ltlt "("
- for (int i 0 i lt vect.size() i)
- out ltlt vecti ltlt ","
- out ltlt ")" return out
- template ltclass Tgt
- void printReverse(const vectorltTgt vect)
- cout ltlt "("
- for (vectorltTgtconst_reverse_iterator
- curr vect.rbegin()
- curr ! vect.rend() curr)
- cout ltlt curr ltlt ","
- cout ltlt ")"
-
45Vectors e.g. vect.cpp
- void main()
- srand(time(NULL))
- vectorltintgt ints
- cout ltlt "Initial size " ltlt ints.size()
- ltlt "\nInitial capacity " ltlt
ints.capacity() - for (int i 0 i lt 5 i)
- ints.push_back(rand() 20)
- cout ltlt "\nNow, size " ltlt ints.size()
- ltlt "\nCapacity " ltlt ints.capacity()
- cout ltlt "\nvector " ltlt ints
- cout ltlt "\nvector reversed "
- printReverse(ints)
46Vectors e.g. vect.cpp
- try
- ints.at(100) 20
- catch (out_of_range oor)
- cout ltlt "\nTried to set mem 100,"
- cout ltlt "\nbut caught exception " ltlt
oor.what() -
- sort(ints.begin(), ints.end())
- cout ltlt "\nAfter sort, vect
- ltlt ints
-
47Vectors e.g. vect.cpp
- Initial size 0
- Initial capacity 0
- Now, size 5 Capacity 256
- vector (7,3,16,14,17,)
- vector reversed (17,14,16,3,7,)
- Tried to set mem 100 to 20,
- but caught exception index out of range in
function vector at(size_t) index 100 is
greater than max_index 5 - After sort, vector (3,7,14,16,17,)
48STL interators iterio.cpp
- Access set of values from one place
- Usually, place is a container
- But input stream may be construed as a place
- include ltiostreamgt include ltiteratorgt
- using namespace std
- void main()
- cout ltlt Enter two nums
- istream_iteratorltintgt intIn(cin)
- int x intIn
- intIn x intIn
- ostream_iteratorltintgt intOut(cout)
- cout ltlt The sum is
- intOut x cout ltlt endl
49I/O iterators ioiter.cpp
- Code
- int x intIn
- intIn x intIn
- Output
- C\3101-2\lec5gtioiter
- Enter two nums 5 6
- The sum is 11
- But if code
- int x intIn
- /intIn/ x intIn
- Then output
- C\3101-2\lec5gtioiter
- Enter two nums 5 6
- The sum is 10
50copy function vect2.cpp
- Another way to print container
- use copy function
- if (!vect.empty())
- ostream_iteratorltTgt out(cout, " ")
- copy(vect.begin(), vect.end(), out)
-
- copy(src begin it, src end it, dest it)
- src begin it vect.begin()
- src end it vect.end()
- dest it ostream_iteratorltTgt out(cout, " ")
- its an ostream_iterator
- its wrapping around cout
- its outputting Ts
- its printing between the Ts
51shuffle, sort, search, min vect2.cpp
- void sort(begin it, end it)
- it-s must be random-access
- members must support , lt
- void random_shuffle(begin it, end it)
- same reqs
- bool binary_search(begin, end, target)
- same reqs
- also assumes sorted
- min_element(v.begin(), v.end())
- returns iterator
52shuffle, sort, search, min vect3.cpp
- All ftns translate automatically to strings
- transform ftn vect4.cpp
- transform(begin it, end it, dest it, ftn)
- transform(v.begin(), v.end(), v.begin(),
square) - cout ltlt "\nAfter squaring, vector " ltlt v ltlt
endl
53for_each ftn vect4.cpp
- Another way to print container
- use for_each function
- for_each(begin it, end it, ftn)
- Our subroutine
- templateltclass Tgt
- void print(T val)
- cout ltlt val ltlt "/"
-
- if (!vect.empty())
- for_each(vect.begin(),
- vect.end(), printltTgt)
-
- NB printltTgt is a function pointer
54Other containers
- list doubly linked list
- insert/delete anywhere const time
- access linear time
- bidirectional iterators
- deque double-ended queue
- insert/delete at front/back const time
- insert/delete in middle linear time
- access constant time
- random-access iterators
55strings as containers
- Can traverse strings in the usual way
- for (int i 0 i lt i.length() i)
- cout ltlt si
- Also
- for (chariterator curr s.begin() curr !
s.end() curr) - cout ltlt curr
56STL Algorithms - ltalgorithmgt
- binary_search
- sort
- count count(list.begin(), listend(), val,
num) - equal compares containers
- for_each applies ftn to each element
- copy copies container
- reverse
- min/max
- Some in ltnumericgt
57Other algorithms
- Set-theoretic
- set_union
- set_intersection
- set_difference
- set_symmetric_difference
- Sorting
- sort_heap
- stable_sort
- And many more
58Algorithms in STL
- Important observation STL class live in own
headers - ltvectorgt, ltlistgt, but - STL algs live in places like ltalgorithmgt and
ltnumericgt - To sort, we pass access (it) to our obj to the
sort ftn - We dont call obj.sort()
- Why?
- The STL doesnt use inheritance!
- Why not?
- virtual functions are slow(er)
- No inher ? would have to dup. ftns
- No inher ? no encapsulation
- ? algorithms on their own
59STL e.g. grades
- Goal store grades for group of students
- ordered set of assignments
- maybe students with same name
- For each student, have grades
- want fast access to each grade
- use vector of chars
- typedef vectorltintgt Grades
- First, create map of students
- mapltstring, Gradesgt roster
60STL add a student to map
- map represents a function key maps to value
- map, basically set of ordered pairs
- pairltx,ygt template
- void RosteraddStudent(const string name)
- //check if already exists
- if (roster.find(name) ! roster.end())
- return
- //check for room
- if (roster.size() MAX)
- waitList.push_back(name)
- else
- Grades grades
- roster.insert(
- pairltstring,Gradesgt(name,grades))
-
61STL add a student to map
- Notice find line
- if (rost.find(name) ! rost.end())
- return
- find function searches for an elm with our key
- if found, returns pointer to it
- if not, returns pointer to end()
- points past, not to last member
- like for (int i 0 I lt n i)
- More precisely these ptrs are
- iterators inc/dec to step through seq
- More precisely these ptrs are iterators
- ops overloaded as though moving thru mem
62STL add a student to map
- Notice insert line
- roster.insert(
- pairltstring,Gradesgt(name,grades))
- Dissection
- Add a member to a roster
- The member is a pair of two things
- member ftns first(), second()
- The things are string and Grades
- pairltX,Ygt(x,y) is a constr call
- passes x and y
- to constr for type pairltX,Ygt
63STL drop a student
- void RosterdropStudent(String name)
- if (roster.find(name) roster.end())
- return
- roster.erase(name)
- if (waitList.size() gt 0)
- string wait waitList.pop_front()
- waitList.pop()
- Grades grades
- roster.insert(
- pairltstring,Gradesgt(name,grades))
-
-
64STL set a grade
- void RostersetGrade(const string name,
const int assign, const char grade) - mapltstring,Gradesgt stud roster.find(name)
- if (stud roster.end())
- cerr ltlt not found\n
- return
-
- if (stud-gtsecond().size() lt assign)
- stud-gtsecond().resize(assign1)
- stud-gtsecondassign grade
-
65STL print grades
- void Rosterprint()
- Already saw many print/ltlt functions
- Thats all well cover of STL
- Many more classes, algs in STL
- Much more to C itself
- But you now know enough
- About the most import. Features
- To learn remaining details on own
66Next time final exam
- Closed books/notes/everything
- 2 hours/class time
- Questions
- Vocab protected, static, etc.
- Find errors/read code/predict output
- Write code
- See web for a semi-definitive list of topics
- Jake will be proctoring the exams
- But well have OH next week(end)
- Come in if you have questions!
67Grading
- Final will be hard/challenging
- Ave score probably near 70
- Final grades are curved
- Rule of thumb mean stdev
- Mean B/B-
- -stdev one letter grade
- See mean/stdevs on web to estimate your grade
68The future
- Q What happens when backward-compat is removed
from C? - A C
- less complexity
- Microsoft approves
- Better or worse than C, Java?
- Find out in CS3101-4 C, next spring
- Tonight hw4 TBA due by final
- Please fill out course evals!
- Link will be on classpage tonight
- Available until beginning of finals
- Get valuable extra credit on final
- Sign in and good luck!
- Happy Thanksgiving!