C++ Primer C++ is a major extension of c. It is similar to Java. The lectures in this course use pseudo-code (not C++). The textbook contains C++. The labs involve C++ programming. This lecture covers the C++ extensions needed for the course. More details appear in chapters 1 2 of the textbook.
Topics bool and string types input/output library functions comments memory allocation templates classes
Types bool and string The type bool stores a Boolean. The values are true and false. These values are equivalent to 1 and 0. The type string stores a character string. A string literal looks like this: string. We will use strings for output formatting. The string library provides many other operations.
iostream Input/output is performed with the iostream library. Operator >> reads inputs separated by white space. Operator << writes outputs. Standard streams are cin, cout, and cerr. File redirection applies to cin and cout. cerr always writes to the screen. File i/o is similar.
Example 1 #i n c l u de <i ostream > using namespace s t d ; main ( ) { double x, y, z ; c i n >> x >> y >> z ; bool f l a g 1 = x < y, f l a g 2 = y < z ; bool f l a g 3 = f l a g 1 && f l a g 2 ; cout << c o n j u n c t i o n o f << x << < << y << and << y << < << z << i s << f l a g 3 << e n d l ;
Output 1 % g++ primer1.c % a.out 1 2 3 conjunction of 1 < 2 and 2 < 3 is 1 % a.out 2.5 1 3.5 conjunction of 2.5 < 1 and 1 < 3.5 is 0
Functions A function can declare an empty argument list. A function must declare a return type, possibly void. Arguments can be passed by reference, e.g int &x. This is an alternative to a pointer, e.g. int *x. A reference can be immutable, e.g. const int &x. This avoids copying large arguments. Function names can be overloaded if the argument lists differ.
Comments Comments can begin with /* and end with */. The rest of a line is commented with //.
Example 2 I #i n c l u de <i ostream > using namespace s t d ; double f ( double x ) { x += 1. 0 ; return x ; // i n t f ( double x ) cannot be d e c l a r e d double g ( double &x ) { x += 1. 0 ; return x ;
Example 2 II main ( ) { double y = 1. 0, z = 1. 0, ny = f ( y ), nz = g ( z ) ; cout << y = << y << ny = << ny << z = << z << nz = << nz << e n d l ; % a.out y = 1 ny = 2 z = 2 nz = 2
Memory Allocation Memory is allocated with new and is freed with delete. These functions are type safe. // a l l o c a t e a double double x = new double ; // f r e e i t delete x ; // a l l o c a t e an a r r a y o f ten d o u b l e s double x = new double [ 1 0 ] ; // f r e e i t delete [ ] x ;
Function Templates Typed languages are awkward for type independent functions. C++ partially fixes this problem with templates. A function template is a parameterized function definition. The parameters can be instantiated with legal types. The compiler creates one function for each instantiation.
Example 3 I #i n c l u de <i ostream > using namespace s t d ; template<typename T> void exchange (T& x, T& y ) { T tmp = x ; x = y ; y = tmp ; main ( ) { i n t x = 1, y = 2 ; exchange<int >(x, y ) ; cout << x << << y << e n d l ;
Example 3 II s t r i n g s = y e s, t = no ; exchange<s t r i n g >(s, t ) ; cout << s << << t << e n d l ; % a.out 2 1 no yes
Classes C++ supports object-oriented programming through classes. A class is an extension of a c struct. It resembles a class in Jave or Python. Classes define local variables and functions, called methods. A class can be a specialization of another class. We will survey the basics and leave the rest to the book.
Example 4 I #i n c l u de <i ostream > using namespace s t d ; c l a s s Palindrome { // l o c a l v a r i a b l e s i n t n ; char c ; bool odd ; p u b l i c : // c o n s t r u c t o r Palindrome ( s t r i n g s ) { odd = s. s i z e ()%2 == 1 ; n = odd? 1+s. s i z e ()/2 : s. s i z e ( ) / 2 ; c = new char [ n ] ; f o r ( i n t i = 0 ; i < n ; ++i ) c [ i ] = s [ i ] ;
Example 4 II // d e s t r u c t o r Palindrome ( ) { delete [ ] c ; // method s t r i n g output ( ) const { s t r i n g s ; f o r ( i n t i = 0 ; i < n ; ++i ) s. push back ( c [ i ] ) ; i n t m = odd? n 2 : n 1 ; f o r ( i n t i = m; i >= 0 ; i ) s. push back ( c [ i ] ) ; return s ;
Example 4 III // c l a s s wide method s t a t i c bool v a l i d ( const s t r i n g &s ) { i n t n = s. s i z e ( ), nn = n / 2 ; f o r ( i n t i = 0 ; i < nn ; ++i ) i f ( s [ i ]!= s [ n i 1]) return f a l s e ; return true ; ; main ( ) { s t r i n g s t [ ] = { abcb, abcba, abccba ; f o r ( i n t i = 0 ; i < 3 ; ++i ) cout << s t [ i ] << << Palindrome : : v a l i d ( s t [ i ] ) << e n d l ;
Example 4 IV Palindrome p ( s t [ 1 ] ), q ( s t [ 2 ] ) ; cout << p. output ( ) << << q. output ( ) << e n d l ; % a.out abcb 0 abcba 1 abccba 1 abcba abccba
Templated Classes Classes can be templated just like functions. The Standard Template Library (STL) contains many useful classes. The classic example is vector. The STL is used in the textbook. It cannot be used in homework.
Example 5 The powerset of a set is the set of its subsets. Example: the powerset of {1, 2, 3 is {{, {1, {2, {3, {1, 2, {1, 3, {2, 3, {1, 2, 3. We compute the powerset with a recursive algorithm. The powerset of the empty set is {. To compute the powerset of {a 1,..., a n, Compute the powerset P of {a 1,..., a n 1. Compute Q by adding an to each element of P. Return P Q. Top-level recursion in our example: P = {{, {1, {2, {1, 2, Q = {{3, {1, 3, {2, 3, {1, 2, 3.
Example 5 I #i n c l u de <v e c t o r > #i n c l u de <i ostream > using namespace s t d ; template<typename T> c l a s s Vector { v e c t o r <T> v ; p u b l i c : // c o n s t r u c t o r Vector ( ) { // c o n s t r u c t o r Vector (T t ) { v. push back ( t ) ; // c o n s t r u c t o r Vector ( i n t n, T t ) { f o r ( i n t i = 0 ; i < n ; ++i ) v. push back ( t [ i ] ) ;
Example 5 II // methods i n t s i z e ( ) const { return v. s i z e ( ) ; void push back (T t ) { v. push back ( t ) ; T & operator [ ] ( i n t i ) { return v [ i ] ; ; template<typename T> Vector<Vector<T> > p o w e rset ( Vector<T> v, i n t n ) { i f ( n == 0) return Vector<Vector<T> >(Vector<T> ( ) ) ; Vector<Vector<T> > ops = p o w e r s e t ( v, n 1 ), ps ( ops ) ; f o r ( i n t i = 0 ; i < ops. s i z e ( ) ; ++i ) { Vector<T> w = ops [ i ] ;
Example 5 III w. push back ( v [ n 1 ] ) ; ps. push back (w ) ; return ps ; template<typename T> ostream& operator<< ( ostream &os, Vector<T>& t ) { os << ( ; f o r ( i n t i = 0 ; i + 1 < t. s i z e ( ) ; ++i ) os << t [ i ] << ; i f ( t. s i z e ( ) > 0) os << t [ t. s i z e () 1]; os << ) << e n d l ; return os ;
Example 5 IV main ( ) { i n t vd [ ] = {1, 2, 3, 4 ; Vector<int > v ( 4, vd ) ; Vector<Vector<int > > ps = p o w e r s et ( v, v. s i z e ( ) ) ; cout << ps ;
Output 5 (() (1) (2) (1 2) (3) (1 3) (2 3) (1 2 3) (4) (1 4) (2 4) (1 2 4) (3 4) (1 3 4) (2 3 4) (1 2 3 4) )