The programs below are discussed in Ammeraal, L. (2000) C++ for Programmers, 3rd Edition, Chichester: John Wiley, ISBN 0-471-60697-9. See also http://home.wxs.nl/~ammeraal/ For some programs (or header files) there are special versions for GNU C++ (gcc) at the bottom of this document. (If you are using an editor, search for GNU.) Chapter 1 ========= // example1.cpp: A program to compute the squares of both // the sum and the difference of two given // integers. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 3. #include using namespace std; int main() { cout << "Enter two integers: "; // Displays input request. int a, b; cin >> a >> b; // Reads a and b. int sum = a + b, diff = a - b, u = sum * sum, v = diff * diff; cout << "Square of sum : " << u << endl; cout << "Square of difference: " << v << endl; return 0; } // twolines.cpp: Application of type string. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 15. #include #include using namespace std; int main() { cout << " Enter two lines of text: \n"; string s, t; getline(cin, s); getline(cin, t); cout << " Output in alphabetic order:\n"; if (s <= t) cout << s << endl << t << endl; else cout << t << endl << s << endl; return 0; } // introstl.cpp: Introduction to STL. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 16. #include #include #include #include using namespace std; int main() { vector v; cout << " Enter lines of text to be sorted,\n"; cout << " followed by the word stop:\n"; for (;;) { string s; getline(cin, s); if (s == "stop") break; v.push_back(s); } sort(v.begin(), v.end()); cout << " The same lines after sorting:\n"; for (int i=0; i #include using namespace std; int main() { char ch = 'A'; double ff = 5.0/3; float f = ff; bool b = (f > 1); int i, j; j = 2 * (i = 5.0/3); // i = 1, j = 2 cout << "ch = " << ch << " ASCII value: " << int(ch) << endl; cout << fixed << setprecision(10); cout << "f = " << f << " ff = " << ff << endl; cout << "i = " << i << " j = " << j << endl; if (b) cout << "The variable b is equal to true.\n"; cout << "Number of bytes for type 'bool': " << sizeof(bool) << endl; cout << "Number of bytes for type 'char': " << sizeof(char) << endl; cout << "Number of bytes for type 'int': " << sizeof(int) << endl; cout << "Number of bytes for type 'float': " << sizeof(float) << endl; cout << "Number of bytes for type 'double': " << sizeof(double) << endl; return 0; } // scope.cpp: Illustration of 'scope' and 'visibility'. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 34. #include using namespace std; int main() { double x = 3.4; { cout << x << " "; // 3.4 int x = 7; { cout << x << " "; // 7 char x = 'A'; cout << x << " "; // A } cout << x << " "; // 7 } cout << x << endl; // 3.4 return 0; } // table.cpp: This program produces a table. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 41. // There is a version adapted for gcc below. #include #include using namespace std; int main() { cout << " x f(x)\n\n"; cout << fixed; for (int i=20; i<=40; i+=2) { double x = i/10.0; cout << setw(3) << setprecision(1) << x << " " << setw(15) << setprecision(10) << x * x + x + 1/x << endl; } return 0; } // break.cpp: Demonstration of the break-statement. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 43. #include using namespace std; int main() { double s = 0, x; cout << "Enter numbers, separated by blanks.\n"; cout << "They are added up as long as they are positive.\n\n"; for (;;) { cin >> x; if (x <= 0) break; s += x; } cout << "Sum of the positive numbers that have " "been read: " << s << endl; return 0; } // even1.cpp: Solution without goto-statements. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 45. #include using namespace std; int main() { int x, s = 0; cout << "Enter positive integers, followed by -1:\n"; for (;;) { cin >> x; // Read x. if (x == -1) break; // Exit if x is -1. if (x % 2 == 0) s += x; // Use x only if it is even. } cout << "Sum of even integers: " << s << endl; return 0; } // even2.cpp: Solution with goto-statements. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 45. #include using namespace std; int main() { int x, s = 0; cout << "Enter positive integers, followed by -1:\n"; l1: cin >> x; // Read x. if (x == -1) goto l2; // Exit if x is -1. if (x % 2 == 0) s += x; // Use x only if it is even. goto l1; // Back to start of loop. l2: cout << "Sum of even integers: " << s << endl; return 0; } Chapter 3 ========= // hexadec.cpp: Hexadecimal and decimal input and output. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 57. #include using namespace std; int main() { cout << "Enter a hexadecimal integer x (for example, 1F) and a " "decimal integer y:\n"; int x, y; cin >> hex >> x >> dec >> y; cout << "0x" << hex << x << " = " << dec << x << endl; int s = x + y; cout << "Their sum (hexadecimal): " << hex << s << endl; cout << "Their sum (decimal): " << dec << s << endl; return 0; } // lifo.cpp: This program reads 30 integers and prints them // in the reverse order (Last In, First Out). // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 59. #include #include using namespace std; int main() { const int n = 30; int i, a[n]; cout << "Enter " << n << " integers:\n"; for (i=0; i> a[i]; cout << "\nThe same integers, in reverse order:\n"; for (i=0; i using namespace std; int main() { int i = 20, j = 10, k, l, m; k = l = i += j += m = 1; cout << "m=" << m << " j=" << j << " i=" << i << " l=" << l << " k=" << k << endl; return 0; } // signedch.cpp: This program finds out whether the leftmost // bit of type char is a sign bit. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 69. #include using namespace std; int main() { signed char s_ch = '\xFF'; unsigned char u_ch = '\xFF'; char ch = '\xFF'; // Binary: s_ch = u_ch = ch = 11111111 int s, u, i; s = s_ch; // From signed char to int u = u_ch; // From unsigned char to int i = ch; // From char to int (system dependent) cout << "For this C++ implementation, type char has " << ( i == s ? "a sign bit.\n" : i == u ? "no sign bit.\n" : "not been implemented correctly.\n" ); return 0; } // beware.cpp: Can a negative value be equal to a // positive one? // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 70. #include using namespace std; int main() { unsigned u = ~0x1; // u = 0xF...FE int i = u; // i = -2 (same bit pattern as u) if (i == u) cout << "i == u\n"; if (i < 0) cout << "i < 0\n"; if (u > 0) cout << "u > 0\n"; return 0; } Chapter 4 ========= // fdemo1.cpp: Demonstration program with a function. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 79. #include using namespace std; float fun(float x, float y, int i, int j) { float a = x - y; int b = i - j; return b != 0 ? a/b : a > 0 ? +1e20F : a < 0 ? -1e20F : 0.0F; } int main() { int ii, jj; float xx, yy; cout << "Enter two real numbers followed by two integers:\n"; cin >> xx >> yy >> ii >> jj; cout << "Value returned by function: " << fun(xx, yy, ii, jj) << endl; return 0; } // fdemo2.cpp: The function fun, called in main, is declared // before and defined after main. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 81. #include using namespace std; float fun(float x, float y, int i, int j); // declaration int main() { int ii, jj; float xx, yy; cout << "Enter two real numbers followed by two integers:\n"; cin >> xx >> yy >> ii >> jj; cout << "Value returned by function: " << fun(xx, yy, ii, jj) << endl; return 0; } float fun(float x, float y, int i, int j) // definition { float a = x - y; int b = i - j; return b != 0 ? a/b : a > 0 ? +1e20 : a < 0 ? -1e20 : 0.0; } // recurs.cpp: Recursion. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 83. #include using namespace std; int f(int n) { int x = n - 1, y; if (n <= 1) y = 1; else y = n * f(x); return y; } int main() { cout << f(3) << endl; return 0; } // prmax3.cpp: A function that prints the maximum of three // integers. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 84. #include using namespace std; void prmax3(int x, int y, int z) { if (y > x) x = y; if (z > x) x = z; cout << "The maximum of these three is: " << x << endl; } int main() { int i, j, k; cout << "Enter three integers: "; cin >> i >> j >> k; prmax3(i, j, k); return 0; } // nopar.cpp: Using a function without parameters. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 85. #include using namespace std; double readreal() { double x; char ch; for (;;) { cin >> x; if (!cin.fail()) // See Section 3.2 break; cin.clear(); // See Section 3.2 do ch = cin.get(); while (ch != '\n'); // Rest of incorrect line has now been skipped. cout << "Incorrect. Enter a number:\n"; } return x; } int main() { double xx; float x; cout << "Enter a real number: "; xx = readreal(); cout << "Another one, please: "; x = readreal(); cout << "The following numbers have been read: " << xx << " " << x << endl; return 0; } // globvar.cpp: A global variable. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 87. #include using namespace std; int i; void print_i() { cout << i << endl; } int main() { i = 123; print_i(); return 0; } // namespace.cpp: The namespace concept. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 89. #include using namespace std; namespace A { int i = 10; } namespace B { int i = 20; } void fA() { using namespace A; cout << "In fA: " << A::i << " " << B::i << " " << i << endl; // In namespace A, i is A::i. } void fB() { using namespace B; cout << "In fB: " << A::i << " " << B::i << " " << i << endl; // In namespace B, i is B::i. } int main() { fA(); fB(); cout << "In main: " << A::i << " " << B::i << endl; return 0; } // confuse.cpp: Confusing because of two variables i. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 90. #include namespace A {int i = 10;}; int main() { int i = 20; using namespace A; std::cout << i << std::endl; // Output: 20 return 0; } // addtoloc.cpp: A::i is added to the local scope of main. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 91. #include namespace A { int i = 10; }; int i = 20; int main() { using A::i; std::cout << i << std::endl; // Output: 10 return 0; } // refvar.cpp: Demonstration of a reference variable. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 92. #include using namespace std; int main() { int i, &x = i; i = 2; x *= 100; cout << "The value of i is now " << i << ".\n"; cout << "Using x, we also find i = " << x << ".\n"; return 0; } // argconv.cpp: Argument conversion from int to float. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 94. #include using namespace std; float f(float x) { return x * x + 1; } int main() { cout << f(5) << endl; return 0; } // statvar.cpp: A local static variable. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 96. #include using namespace std; void f() { static int i = 1; cout << i++ << endl; } int main() { f(); f(); return 0; } // func.h: Header used in mainfile.cpp and funcfile.cpp. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 100. void setk(int kk); int f(int x); int getcounter(); // mainfile.cpp: Demonstration of separate compilation. // The file funcfile.cpp should be linked. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 100. #include #include "func.h" using namespace std; int main() { extern int n; n = 10; setk(5); cout << "f(2) = " << f(2) << endl; cout << "f(3) = " << f(3) << endl; cout << "Function f was called " << getcounter() << " times.\n"; return 0; } // funfile.cpp: Definitions of functions setk, f, and // getcounter. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 101. #include "func.h" int n; namespace { int k; int counter = 0; } void setk(int kk){k = kk;} int f(int x) { counter++; return k * x + n; } int getcounter(){return counter;} //reffun.cpp: Reference as return value. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 106. #include using namespace std; int &maxim(int &x, int &y) { return (x > y ? x : y); } int main() { int a = 23, b = 15; cout << "a = " << a << " b = " << b << endl; // First call to maxim: cout << "The larger of these is " << maxim(a, b) << endl; // Second call to maxim: maxim(a, b) = 0; // A function call as left-hand side! cout << "The larger of a and b is set to 0. Thus we now have \n"; cout << "a = " << a << " b = " << b << endl; return 0; } // recfun.cpp: Demonstration of a recursive function. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 114. #include using namespace std; void f(int n) { if (n > 0) { f(n-2); cout << n << " "; f(n-1); } } int main() { int k; cout << "Enter k: "; cin >> k; cout << "Output:\n"; f(k); cout << endl; return 0; } Chapter 5 ========= // minimum.cpp: Finding the smallest element of an // integer array. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 119. #include using namespace std; int minimum(const int *a, int n) { int small = *a; for (int i=1; i> table[i]; cout << "\nThe minimum of these values is " << minimum(table, 10) << endl; return 0; } // constcast.cpp: An application of const_cast. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 124. #include using namespace std; // First function maxim: int &maxim(int &x, int &y) { return (x > y ? x : y); } // Second function maxim: inline const int &maxim(const int &x, const int &y) { return maxim(const_cast(x), const_cast(y)); } int main() { int a = 5, b = 6, t; maxim(a, b) = 0; // Assign 0 to the larger of a and b, that is, to b. const int c = 7, d = 8; t = maxim(c, d); // Assign the larger of c and d, that is 8, to t. cout << b << " " << t << endl; // 0 8 return 0; } // strings.cpp: Sorting an array of strings // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 131. #include #include #include using namespace std; int main() { const int n = 5; string a[n]; cout << " Enter five lines of text:\n"; int i; for (i=0; i #include using namespace std; int main() { cout << string(20, '*') // Output: ******************** << endl; return 0; } // align.cpp: Align strings. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 144. // There is version adapted for gcc below. #include #include #include using namespace std; int main() { string names[3] = {"John", "George", "Jim"}; int ages[3] = {9, 100, 24}; for (int i=0; i<3; ++i) cout << setw(10) << left << names[i] << setw(3) << right << ages[i] << endl; return 0; } // ptrarray.cpp: Pointer to array. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 147. #include using namespace std; int main() { int a[5], (*p)[5]; p = &a; (*p)[3] = 123; cout << (*p)[3] << endl; return 0; } // parfun.cpp: Pointer to array as function parameter. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 147. #include using namespace std; void f(int (*q)[5]) { (*q)[3] = 123; } int main() { int a[5]; int (*p)[5]; p = &a; f(p); cout << (*p)[3] << endl; // Output: 123 return 0; } // parray.cpp: Pointer to array that is element of // another array. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 148. #include using namespace std; int main() { int i, j, a[2][3] = {{8, 3, 6}, {5, 7, 0}}, (*p)[3]; p = a; for (i=0; i<2; ++i) { for (j=0; j<3; ++j) cout << p[i][j] << " "; cout << endl; } cout << sizeof(a)/sizeof(int) << " elements in array a.\n"; cout << sizeof(*p)/sizeof(int) << " elements in each row.\n"; return 0; } // progparm.cpp: Demonstration of using program parameters. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 150. #include using namespace std; int main(int argc, char *argv[]) { cout << "argc = " << argc << endl; for (int i=1; i> x; // x = 0.0012 cout << x << endl; // From numerical value y to string t: double y = 10.3456789; ostringstream ostr; ostr << fixed << setw(8) << setprecision(3) << y; string t = ostr.str(); // t = " 10.346" cout << t << endl; return 0; } // pfun.cpp: A function with a function as its argument. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 154. #include using namespace std; double funsum(int n, double (*f)(int k)) { double s = 0; int i; for (i=1; i<=n; ++i) s += (*f)(i); return s; } double reciprocal(int k) { return 1.0/k; } double square(int k) { return static_cast(k) * k; } int main() { cout << "Sum of five reciprocals: " << funsum(5, &reciprocal) << endl; cout << "Sum of three squares: " << funsum(3, &square) << endl; return 0; } // newint.cpp: A very simple use of new and delete. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 156. #include using namespace std; int main() { int *p = new int(123); cout << ++*p << endl; // Output: 124 delete p; return 0; } // newarray.cpp: A dynamically allocated array. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 157. #include using namespace std; int main() { int i, n; cout << "Enter the sequence length n: "; cin >> n; float *a = new float[n]; cout << "Enter n numbers: \n"; for (i=0; i> a[i]; cout << "Here are the same numbers in reverse order:\n"; for (i=n-1; i>=0; --i) cout << a[i] << endl; delete[] a; return 0; } // newplace.cpp: The operator new with placement syntax. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 158. #include using namespace std; void *operator new(unsigned int nbytes, char *p) { static char *pFree = p; // Because of 'static', pFree is initialized only once. cout << "nbytes = " << nbytes << endl; // Output inserted to show what happens. void *p1 = reinterpret_cast(pFree); pFree += nbytes; return p1; } int main() { int *pInt; double *pDouble; char a[1000]; pInt = new (a) int; *pInt = 123; pDouble = new (a) double; *pDouble = 4.56; // Show that array a contains the values 123 and 4.56: int *pI = reinterpret_cast(a); double *pD = reinterpret_cast(a + sizeof(int)); if (*pI == 123 && *pD == 4.56) cout << "Array a used to store 123 and 4.56\n"; return 0; } Chapter 6 ========= // person.h: Header for the class Person. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 163. // There is version adapted for gcc below. #include #include #include using namespace std; class Person { public: Person(const string &s = "", int yr = 0, bool m = true) { name = s; yearOfBirth = yr; male = m; } void setName(const string &s){name = s;} void setYear(int yr){yearOfBirth = yr;} void setMF(bool m){male = m;} const string &getName()const { return name; } int getAgeAtEnd2000()const { return 2000 - yearOfBirth; } void print()const { cout << setw(10) << left << name << setw(4) << right << getAgeAtEnd2000() << (male ? " (M)" : " (F)") << endl; } private: string name; int yearOfBirth; bool male; }; // persdemo.cpp: Demonstration of class Person. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 164. #include #include #include "person.h" using namespace std; int main() { Person a("Mary", 1980, false), b; b.setName("John"); b.setYear(1975); b.setMF(true); string s = a.getName(); cout << s << endl; // Mary b.print(); // John 25 M return 0; } // initcons.cpp: A constructor using the // initialization syntax. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 167. #include using namespace std; class TestInit { public: TestInit(int i, float &x): ii(i), xx(x){} void print()const{cout << ii << " " << xx << endl;} private: const int ii; float &xx; }; int main() { float y = 8.5F; TestInit t(2, y); t.print(); // 2 8.5 return 0; } // datetest.cpp: An application of class DateDM. // The file dateDM.cpp must be linked. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 168. #include #include "dateDM.h" using namespace std; int main() { int d, m; cout << "Enter day and month numbers of date 1: "; cin >> d >> m; DateDM date1(d, m); cout << "Enter day and month numbers of date 2: "; cin >> d >> m; DateDM date2(d, m); cout << "Difference in a non-leap year: " << date1.difference(date2) << " days\n"; return 0; } // dateDM.h: Header file for date, // restricted to day and month. // Both are dates of a non-leap year. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 169. class DateDM { public: DateDM(int d = 1, int m = 1); int difference(const DateDM &date)const; private: int day, month; }; // dateDM.cpp: Implementation of class DateDM. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 170. #include #include "dateDM.h" using namespace std; namespace { int calendar[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; } DateDM::DateDM(int d, int m) { if (m < 1 || m > 12) { cout << "Invalid month number. Value 1 used instead.\n"; m = 1; } if (d < 1 || d > calendar[m-1]) { cout << "Invalid day number. Value 1 used instead.\n"; d = 1; } day = d; month = m; } int DateDM::difference(const DateDM &date2)const { int precedingDays[12]; precedingDays[0] = 0; // 0 for January, etc. for (int i=1; i<12; ++i) precedingDays[i] = precedingDays[i-1] + calendar[i-1]; int dayNr1 = precedingDays[month-1] + day, dayNr2 = precedingDays[date2.month-1] + date2.day; return dayNr2 - dayNr1; } // datetst.cpp: An application of class DateDM. // The file dateDM.cpp must be linked. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 173. #include #include "dateDM.h" using namespace std; DateDM readDate(int i) { int d, m; cout << "Enter day and month numbers of date " << i << ": "; cin >> d >> m; return DateDM(d, m); } int main() { DateDM date1 = readDate(1), date2 = readDate(2); cout << "Difference in a non-leap year: " << date1.difference(date2) << " days\n"; return 0; } // operator.cpp: Overloaded + and << operators. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 176. #include using namespace std; class vec { public: vec(float xx = 0, float yy = 0): x(xx), y(yy) {} void printvec(ostream &os)const { os << "(" << x << ", " << y << ")"; } vec operator+(const vec &b)const { return vec(x + b.x, y + b.y); } private: float x, y; }; ostream &operator<<(ostream &os, const vec &v) { v.printvec(os); return os; } int main() { vec u(3, 1), v(1, 2), s; s = u + v; // This is our own operator + cout << "The sum of (3, 1) and (1, 2) is " << s // This is our own operator << << endl; return 0; } // mod24.cpp: Modulo 24 addition. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 181. #include using namespace std; class mod24 { public: mod24(int x = 0) { t = x % 24; if (t < 0) t += 24; } int getvalue()const{return t;} private: int t; // t = 0, 1, 2, ..., 23 }; mod24 operator+(const mod24 &a, const mod24 &b) { return mod24(a.getvalue() + b.getvalue()); } ostream &operator<<(ostream &os, const mod24 &x) { os << x.getvalue(); return os; } istream &operator>>(istream &is, mod24 &x) { int y; is >> y; x = mod24(y); return is; } int main() { mod24 x(23), y(5); cout << "23 + 5 modulo 24 = " << x + y << endl; cout << "Same result: " << x + 5 << endl; cout << "Same result: " << 23 + y << endl; cout << "Different result: " << 23 + 5 << endl; cout << "Enter two integers: "; cin >> x >> y; cout << "Taken modulo 24, they are equal to " << x << " and " << y << endl; cout << "x + y modulo 24 = " << x + y << endl; return 0; } // rows0.cpp: A class with a pointer, preliminary version. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 188. #include #include using namespace std; class row { public: row(int n = 3) { len = n; ptr = new int[n]; for (int i=0; i #include using namespace std; class row { public: row(int n = 3); // Default constructor row(const row &r); // Copy constructor ~row(); // Destructor row &operator=(const row &r); // Copy assignment operator void printrow(const string &str)const; private: int *ptr, len; }; row::row(int n) // default = 3 not repeated here { len = n; ptr = new int[n]; for (int i=0; i using namespace std; class Shape { public: Shape(double x = 0, double y = 0): xC(x), yC(y){} void printcenter()const { cout << xC << " " << yC << endl; } protected: double xC, yC; }; const double pi = 3.1415926535897932; class Circle: public Shape { public: Circle(double xC, double yC, double r) :Shape(xC, yC) { radius = r; } double area()const {return pi * radius * radius;} private: double radius; }; class Square: public Shape { public: Square(double xC, double yC, double xP, double yP) :Shape(xC, yC) { this->xP = xP; this->yP = yP; } double area()const { double a = xP - xC, b = yP - yC; return 2 * (a * a + b * b); // See Figure 6.5 } private: double xP, yP; }; int main() { double xCircle = 2, yCircle = 2.5, radius = 2; Circle circle(xCircle, yCircle, radius); cout << "Center of circle: "; circle.printcenter(); cout << "Radius: " << radius << endl; cout << "Area of circle: " << circle.area() << endl << endl; double xCsquare = 3, yCsquare = 3.5, xP = 4.37, yP = 3.85; Square square(xCsquare, yCsquare, xP, yP); cout << "Center of square: "; square.printcenter(); cout << "xP = " << xP << " yP = " << yP << endl; cout << "Area of square: " << square.area() << endl; return 0; } // ovride.cpp: The principle of overriding. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 204. #include using namespace std; class B { public: int i; int compute()const{return i * i;} }; class D: public B { public: int i; int compute()const{return i + B::i;} }; int main() { D d; d.i = 5; d.B::i = 6; cout << "d.compute() = " << d.compute() << endl; cout << "d.B::compute() = " << d.B::compute() << endl; return 0; } // nohiding.cpp: The principle of overriding. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 204. // There is version adapted for gcc below. #include using namespace std; class B { public: int f()const{return 1;} }; class D: public B { public: using B::f; int f(int k)const{return k;} }; int main() { D d; cout << "d.f() = " << d.f() << endl; return 0; } // convdb.cpp: Conversion from derived to base class. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 206. #include using namespace std; class B { public: int i; B(int ii = 0): i(ii){} }; class D: public B { public: float x; D(float xx): B(1), x(xx){} }; int main() { B b(2), *pb = &b; D d(3.4F), *pd = &d; b = d; // From derived to base: OK cout << "b: " << b.i << endl; cout << "d: " << pd->i << " " << pd->x << endl; pb = pd; // Corresponding pointer types: OK // d = b; // Would be an error; nor is a cast possible // pd = pb; // Would be an error pd = reinterpret_cast(pb); // With cast: OK (if pb points to a D object) cout << "After pb = pd; pd = reinterpret_cast(pb); " "we have\n"; cout << "d (reached via pd): " << pd->i << " " << pd->x << endl; return 0; } // virtual.cpp: A virtual function in action. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 210. #include using namespace std; class animal { public: virtual void print()const // Virtual print function { cout << "Unknown animal type.\n"; } virtual ~animal(){} // Virtual destructor, discussed below protected: int nlegs; }; class fish: public animal { public: fish(int n) {nlegs = n;} void print()const { cout << "A fish has " << nlegs << " legs.\n"; } }; class bird: public animal { public: bird(int n){nlegs = n;} void print()const { cout << "A bird has " << nlegs << " legs.\n"; } }; class mammal: public animal { public: mammal(int n){nlegs = n;} void print()const { cout << "A mammal has " << nlegs << " legs.\n"; } }; int main() { animal *p[4]; int i; p[0] = new fish(0); p[1] = new bird(2); p[2] = new mammal(4); p[3] = new animal; for (i=0; i<4; ++i) p[i]->print(); for (i=0; i<4; ++i) delete p[i]; return 0; } // late.cpp: This program shows that a class with a virtual // function takes more memory than a similar class // in which no function is virtual. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 212. #include using namespace std; class late {public: int i; virtual void f(){i=1;}}; class early {public: int i; void f(){i=1;}}; int main() { cout << "late: " << sizeof(late) << " bytes.\n"; cout << "early: " << sizeof(early) << " bytes.\n"; return 0; } // virtdest.cpp: A virtual destructor. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 213. #include using namespace std; class B { public: virtual ~B(){} }; class D: public B { public: D(){a = new int[100000];} ~D(){delete[] a; cout << "Memory released!\n";} private: int *a; }; void f() { B *p = new D; // Memory is allocated for 100000 integers delete p; // Released again, thanks to virtual destructor } int main() { f(); return 0; } // purevirt.cpp: A pure virtual function. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 216. #include using namespace std; class animal { public: virtual void print()const = 0; virtual ~animal(){} protected: int nlegs; }; class fish: public animal { public: fish(int n) {nlegs = n;} void print()const { cout << "A fish has " << nlegs << " legs.\n"; } }; class bird: public animal { public: bird(int n){nlegs = n;} void print()const { cout << "A bird has " << nlegs << " legs.\n"; } }; class mammal: public animal { public: mammal(int n){nlegs = n;} void print()const { cout << "A mammal has " << nlegs << " legs.\n"; } }; int main() { animal *p[3]; p[0] = new fish(0); p[1] = new bird(2); p[2] = new mammal(4); int i; // With this way of declaring i, the program // is accepted by both VC++ and gcc. for (i=0; i<3; ++i) p[i]->print(); for (i=0; i<3; ++i) delete p[i]; return 0; } // dyncast.cpp: Run-time type information and dynamic_cast. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 218. #include using namespace std; class B { public: virtual int f() = 0; }; class D: public B { public: int f(){return 1;} }; class E: public B { public: int f(){return 2;} }; int main() { B *p; D d; p = &d; if (dynamic_cast(p)) cout << p->f() << endl; // Output: 1 if (dynamic_cast(p)) cout << p->f() << endl; // Not executed return 0; } // statmem.cpp: Using a static class member to // count how many times the constructor // Person() is called. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 219. #include #include using namespace std; class Person { public: Person(const string &s): name(s) { count++; } void print()const { cout << name << endl; } static void printcount() { cout << "There are " << count << " persons." << endl; } private: string name; static int count; }; int Person::count=0; int main() { Person a("Mary"), b("Peter"), c("Charles"), *p; p = new Person("Kate"); a.print(); b.print(); c.print(); p->print(); Person::printcount(); delete p; return 0; } // ptrmem.cpp: Pointers to class members. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 223. #include using namespace std; class Example { public: Example(int ii, int jj): i(ii), j(jj){} int ivalue(){return i;} int jvalue(){return j;} int i, j; }; int main() { Example u(1, 2), v(3, 4), w(5, 6), *pobject = &w; cout << "Pointer to function members: "; int (Example::*pf)(); pf = &Example::ivalue; cout << (u.*pf)() << " "; // 1 pf = &Example::jvalue; cout << (v.*pf)() << " "; // 4 cout << (pobject->*pf)() << endl;// 6 cout << "Pointer to data members: "; int Example::*pd; pd = &Example::i; cout << u.*pd << " "; // 1 pd = &Example::j; cout << v.*pd << " "; // 4 cout << pobject->*pd << endl;// 6 return 0; } // charflo.cpp: An array of unions. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 225. #include using namespace std; union charfloat {char ch; float x;}; int main() { const int n = 100000; charfloat a[n]; for (int i=0; i using namespace std; class iprint { public: void operator()(int i)const{cout << i << endl;} }; int main() { iprint x; x(123); // Output: 123 iprint()(456); // Output: 456 return 0; } // funobj.cpp: Function object used to pass functions to // another function. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 229. #include using namespace std; class fun { public: virtual double operator()(int k)const = 0; }; class reciprocal: public fun { public: double operator()(int k)const { return 1.0/k; } }; class square: public fun { public: double operator()(int k)const { return static_cast(k) * k; } }; double funsum(int n, const fun &f) { double s = 0; int i; for (i=1; i<=n; ++i) s += f(i); return s; } int main() { cout << "Sum of five reciprocals: " << funsum(5, reciprocal()) << endl; cout << "Sum of three squares: " << funsum(3, square()) << endl; return 0; } Chapter 7 ========= // ftempl.cpp: A function template for swapping the values // of two objects of a given, arbitrary type. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 233. #include using namespace std; template void swapObjects(T &x, T &y){T w = x; x = y; y = w;} int main() { int i = 1, j = 2; swapObjects(i, j); // Now i = 2 and j = 1. float u = 3.4F, v = 5.6F; swapObjects(u, v); // Now u = 5.6 and v = 3.4. cout << i << " " << j << " " << u << " " << v << endl; return 0; } // swap.h: A header file defining the function template // swapObjects. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 235. template void swapObjects(T &x, T &y){T w = x; x = y; y = w;} // swapdemo.cpp: Demonstration of a function template // defined in the header file swap.h. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 235. #include #include "swap.h" using namespace std; int main() { int i = 1, j = 2; swapObjects(i, j); float u = 3.4F, v = 5.6F; swapObjects(u, v); cout << i << " " << j << " " << u << " " << v << endl; // Output: 2 1 5.6 3.4 return 0; } // ftempl2.cpp: Function templates with two parameters. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 235. #include using namespace std; template U multsum(T x, T y, U u, int n) { return x + y + n * u; } int main() { cout << multsum(4, 3, 0.5, 5) << endl; // Output: 9.5 return 0; } // powers.cpp: Two power functions resulting from a template. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 236. #include using namespace std; template resulttype power(basetype a, int n) { resulttype x = 1; for (int i=1; i<=n; ++i) x *= a; return x; } int main() { cout << power(10, 9) << endl; cout << power(10, 30) << endl; return 0; } // ptrpar.cpp: Template parameter used for pointer. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 237. #include using namespace std; template T arraysum(const T *p, int n) { T s = 0; for (int i=0; i using namespace std; template class vec { public: vec(T xx = 0, T yy = 0): x(xx), y(yy) {} void printvec(ostream &os)const { os << "(" << x << ", " << y << ")"; } vec operator+(const vec &b)const { return vec(x + b.x, y + b.y); } private: T x, y; }; template ostream &operator<<(ostream &os, const vec &v) { v.printvec(os); return os; } int main() { vec uInt(1, 2), vInt(3, 4), sInt; vec uFloat(1.1F, 2.2F), vFloat(3.3F, 4.4F), sFloat; sInt = uInt + vInt; sFloat = uFloat + vFloat; cout << sInt << endl; cout << sFloat << endl; return 0; } // sequence.cpp: A class template with three arguments. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 240. #include using namespace std; template class sequence { public: sequence(T start, T incr); S sum(); private: T r[n]; }; template sequence::sequence(T start, T incr) { for (int i=0; i S sequence::sum() { S s = 0; for (int i=0; i a_int(1, 2); // 4 elements sequence a_float(0.3F, 0.1F); // 3 elements sequence a_double(1.0, 0.1); // 5 elements cout << a_int.sum() << " " // 16 << a_float.sum() << " " // 1.2 << a_double.sum() << endl; // 6 return 0; } // istring.cpp: The template basic_string applied to // integers. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 242. // This program does not compile with gcc (see version below). #include #include using namespace std; typedef basic_string istring; // int instead of char! int main() { istring s; s += 123; s += 98; s += 45; for (int i=0; i #include using namespace std; int main() { complex a, aa, b, c, D, sqrtD, x1, x2; cout << "Enter the complex numbers a (nonzero), b, and c:\n"; cin >> a >> b >> c; if (a == 0.0) { cout << "a must be nonzero.\n"; return 1; } D = b * b - 4.0 * a * c; sqrtD = sqrt(D); aa = 2.0 * a; x1 = (-b + sqrtD)/aa; x2 = (-b - sqrtD)/aa; cout << "Solution (complex):\n" << x1 << " " << x2 << endl; return 0; } Chapter 8 ========= // except1.cpp: Example of exception handling // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 249. #include using namespace std; void detail(int k) { cout << "Start of detail function.\n"; if (k == 0) throw 123; cout << "End of detail function.\n"; } void compute(int i) { cout << "Start of compute function.\n"; detail(i); cout << "End of compute function.\n"; } int main() { int x; cout << "Enter x (0 will throw an exception): "; cin >> x; try {compute(x);} catch (int i) {cout << "Exception: " << i << endl;} cout << "The End.\n"; return 0; } // except2.cpp: Two handlers in a try-block. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 251. #include using namespace std; int main() { int i; char ch; cout << "Enter an integer, followed by some " "nonnumeric character:\n"; try { cin >> i >> ch; if (i == 0) throw 0; if (ch == '?') throw '?'; } catch (int) {cout << "Zero entered.\n";} catch (char) {cout << "Question mark entered.\n";} cout << "The End.\n"; return 0; } // except3.cpp: Re-throwing an exception. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 253. #include using namespace std; void h() // Lowest level { throw 0; } void g() // Intermediate level { try {h();} catch(int) { cout << "Catch in g\n"; throw; // This statement re-throws the exception. } } int main() // Highest level { try {g();} catch(int){cout << "Catch in main\n";} return 0; } // except4.cpp: The simplest possible exception class. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 254. #include using namespace std; class MyException { }; int main() { try { throw MyException(); } catch (MyException) { cout << "Exception thrown.\n"; // This text is displayed } return 0; } // except5.cpp: Catch with base class matches throw with // derived class. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 254. #include using namespace std; class B { }; class D: public B { }; int main() { try { throw D(); } catch (B) { cout << "Exception thrown.\n"; // This text is displayed } return 0; } // except6.cpp: Our own subscripting operator with // array-bounds checking. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 255. #include using namespace std; class OutOfBounds { public: OutOfBounds(int ii): i(ii){} int indexValue(){return i;} private: int i; }; class Array { // For int array of length 10. public: int &operator[](int i) { if (i < 0 || i >= 10) throw OutOfBounds(i); return a[i]; } private: int a[10]; }; int main() { Array a; try { a[3] = 30; cout << "a[3] = " << a[3] << endl; a[100] = 1000; cout << "a[1000] = " << a[1000] << endl; } catch (OutOfBounds error) { cout << "Subscript value " << error.indexValue() << " out of bounds.\n"; } return 0; } // newtest1.cpp: Default exception for 'new'. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 256. #include #include #include using namespace std; int main() { char *p; try { for (;;) { p = new char[INT_MAX]; if (p == NULL) { cout << "The operator new returns NULL (= 0).\n"; cout << "This is not in accordance with Standard C++.\n"; exit(1); } } } catch (bad_alloc) { cout << "A bad_alloc exception has been thrown, " "which is correct.\n"; } return 0; } Chapter 9 ========= // itera.cpp: Iterator-based version of introstl.cpp. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 260. #include #include #include #include using namespace std; int main() { vector v; cout << "Enter lines of text to be sorted,\n"; cout << "followed by the word stop:\n"; for (;;) { string s; getline(cin, s); if (s == "stop") break; v.push_back(s); } sort(v.begin(), v.end()); cout << "The same lines after sorting:\n"; for (vector::iterator i=v.begin(); i!=v.end(); ++i) cout << *i << endl; return 0; } // itdeque.cpp: Using a deque instead of a vector. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 262. #include #include #include #include using namespace std; int main() { deque v; cout << "Enter lines of text to be sorted,\n"; cout << "followed by the word stop:\n"; for (;;) { string s; getline(cin, s); if (s == "stop") break; v.push_front(s); } sort(v.begin(), v.end()); cout << "The same lines after sorting:\n"; for (deque::iterator i=v.begin(); i!=v.end(); ++i) cout << *i << endl; return 0; } // insdel.cpp: Insertions and deletions in a list. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 264. #include #include #include using namespace std; void showlist(const string &str, const list &L) { list::const_iterator i; cout << str << endl << " "; for (i=L.begin(); i != L.end(); ++i) cout << *i << " "; cout << endl; } int main() { list L; int x; cout << "Enter positive integers, followed by 0:\n"; while (cin >> x, x != 0) L.push_back(x); showlist("Initial list:", L); L.push_front(123); showlist("After inserting 123 at the beginning:", L); list::iterator i = L.begin(); L.insert(++i, 456); showlist( "After inserting 456 at the second position:", L); i = L.end(); L.insert(--i, 999); showlist( "After inserting 999 just before the end:", L); i = L.begin(); x = *i; L.pop_front(); cout << "Deleted at the beginning: " << x << endl; showlist("After this deletion:", L); i = L.end(); x = *--i; L.pop_back(); cout << "Deleted at the end: " << x << endl; showlist("After this deletion:", L); i = L.begin(); x = *++i; cout << "To be deleted: " << x << endl; L.erase(i); showlist("After this deletion (of second element):", L); return 0; } // stack1.cpp: Using a stack to read a number sequence // of arbitrary length and to display this sequence // in the reverse order. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 266. #include #include #include using namespace std; int main() { stack > S; int x; cout << "Enter some integers, followed by a letter:\n"; while (cin >> x) S.push(x); while (!S.empty()) { x = S.top(); cout << "Size: " << S.size() << " Element at the top: " << x << endl; S.pop(); } return 0; } // stackcmp.cpp: Stack assignments and comparisons. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 267. #include #include #include using namespace std; int main() { stack > S, T, U; S.push(10); S.push(20); S.push(30); cout << "Pushed onto S: 10 20 30\n"; T = S; cout << "After T = S; we have "; cout << (S == T ? "S == T" : "S != T") << endl; U.push(10); U.push(21); cout << "Pushed onto U: 10 21\n"; cout << "We now have "; cout << (S < U ? "S < U" : "S >= U") << endl; return 0; } // queue.cpp: Using a queue; a demonstration of the // member functions push, pop, back, and front. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 269. #include #include #include using namespace std; int main() { queue > Q; Q.push(10); Q.push(20); Q.push(30); cout << "After pushing 10, 20 and 30:\n"; cout << "Q.front() = " << Q.front() << endl; cout << "Q.back() = " << Q.back() << endl; Q.pop(); cout << "After Q.pop():\n"; cout << "Q.front() = " << Q.front() << endl; return 0; } // prqueue.cpp: A priority queue; a demonstration of the // member functions push, pop, empty, and top. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 270. #include #include #include #include using namespace std; int main() { priority_queue > P; int x; P.push(123); P.push(51); P.push(1000); P.push(17); while (!P.empty()) { x = P.top(); cout << "Retrieved element: " << x << endl; P.pop(); } return 0; } // lastdig.cpp: A priority queue; P.top() is the element // whose last digit is less than (or equal to) // that of the other elements. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 270. #include #include #include using namespace std; class CompareLastDigits { public: bool operator()(int x, int y) { return x % 10 > y % 10; } }; int main() { priority_queue , CompareLastDigits> P; int x; P.push(123); P.push(51); P.push(1000); P.push(17); while (!P.empty()) { x = P.top(); cout << "Retrieved element: " << x << endl; P.pop(); } return 0; } // find1.cpp: Finding a given value in a list. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 272. #include #include #include using namespace std; int main() { int x; list v; v.push_back(2); v.push_back(5); v.push_back(8); cout << "Enter an integer to be found in {2, 5, 8}:\n"; cin >> x; list::iterator i = find(v.begin(), v.end(), x); if (i == v.end()) cout << "Not found."; else { cout << "Found "; if (i == v.begin()) cout << "as the first element."; else cout << "after " << *--i; } cout << endl; return 0; } // copyio.cpp: Using the copy algorithm for I/O. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 275. #include #include #include #include using namespace std; typedef istream_iterator istream_iter; int main() { vector a; ifstream file("example.txt"); if (file.fail()) { cout << "Cannot open file example.txt.\n"; return 1; } copy(istream_iter(file), istream_iter(), inserter(a, a.begin())); copy(a.begin(), a.end(), ostream_iterator(cout, " ")); cout << endl; return 0; } // sortarr.cpp: Sorting an array. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 276. #include #include using namespace std; int main() { int a[10], x, n = 0, *p; cout << "Enter at most 10 positive integers, " "followed by 0:\n"; while (cin >> x, x != 0 && n < 10) a[n++] = x; sort(a, a+n); cout << "After sorting: \n"; for (p=a; p != a+n; ++p) cout << *p << " "; cout << endl; return 0; } // list1.cpp: The list member functions sort and unique. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 280. #include #include using namespace std; void out(const char *s, const list &L) { cout << s; copy(L.begin(), L.end(), ostream_iterator(cout, " ")); cout << endl; } int main() { list L(5, 123); L.push_back(100); L.push_back(123); L.push_back(123); out("Initial contents: ", L); L.unique(); out("After L.unique(): ", L); L.sort(); out("After L.sort(): ", L); return 0; } // splice.cpp: Splicing. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 281. #include #include using namespace std; int main() { list L; list::iterator i, j1, j2, j; for (int k = 10; k <= 80; k += 10) { L.push_back(k); j = L.end(); if (k == 20) j1 = --j; else if (k == 50) j2 = --j; else if (k == 70) i = --j; } L.splice(i, L, j1, j2); copy(L.begin(), L.end(), ostream_iterator(cout, " ")); cout << endl; return 0; } // removal.cpp: The remove algorithm. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 282. #include #include #include #include using namespace std; int main() { int a[6] = {1, 4, 1, 3, 1, 2}; list L(a, a + 6); list::iterator new_end = remove(L.begin(), L.end(), 1); cout << L.size() << endl; // 6 (still garbage at the end) L.erase(new_end, L.end()); // Remove last three elements cout << L.size() << endl; // 3 (garbage removed) return 0; } // removemf.cpp: The list member function remove. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 283. #include #include using namespace std; void out(const char *s, const list &L) { cout << s; copy(L.begin(), L.end(), ostream_iterator(cout, " ")); cout << endl; } int main() { int a[6] = {1, 4, 1, 3, 1, 2}; list L(a, a + 6); out("Initial sequence L:\n", L); L.remove(1); out("After L.remove(1):\n", L); return 0; } // lstmerge.cpp: The list member function merge. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 284. #include #include using namespace std; void out(const char *s, const list &L) { cout << s; copy(L.begin(), L.end(), ostream_iterator(cout, " ")); cout << endl; } int main() { list L1, L2, L3; list::iterator new_end; L1.push_back(10); L1.push_back(20); L1.push_back(30); L2.push_back(15); L2.push_back(35); out("Initial sequence L1:\n", L1); out("Initial sequence L2:\n", L2); L1.merge(L2); out("After L1.merge(L2):\n", L1); return 0; } // mergealg.cpp: The merge algorithm. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 285. #include #include #include #include using namespace std; int main() { int a[3] = {10, 20, 30}; list L; L.push_back(15); L.push_back(35); vector v; merge(a, a + 3, L.begin(), L.end(), inserter(v, v.begin())); for (int i=0; i #include using namespace std; int main() { set S, T; S.insert(10); S.insert(20); S.insert(30); S.insert(10); T.insert(20); T.insert(30); T.insert(10); if (S == T) cout << "Equal sets, containing:\n"; for (set::iterator i = T.begin(); i != T.end(); ++i) cout << *i << " "; cout << endl; return 0; } // multiset.cpp: Two multisets. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 288. #include #include using namespace std; int main() { multiset S, T; S.insert(10); S.insert(20); S.insert(30); S.insert(10); T.insert(20); T.insert(30); T.insert(10); if (S == T) cout << "Equal multisets:\n"; else cout << "Unequal multisets:\n"; cout << "S: "; copy(S.begin(), S.end(), ostream_iterator(cout, " ")); cout << endl; cout << "T: "; copy(T.begin(), T.end(), ostream_iterator(cout, " ")); cout << endl; return 0; } // map1.cpp: First application of a map. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 289. #include #include #include using namespace std; int main() { map D; D["Johnson, J."] = 12345; D["Smith, P."] = 54321; D["Shaw, A."] = 99999; D["Atherton, K."] = 11111; string GivenName; cout << "Enter a name: "; getline(cin, GivenName); if (D.find(GivenName) != D.end()) cout << "The number is " << D[GivenName]; else cout << "Not found."; cout << endl; return 0; } // multimap.cpp: A multimap containing equal keys. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 290. #include #include #include using namespace std; typedef multimap mmtype; int main() { mmtype D; D.insert(mmtype::value_type("Johnson, J.", 12345)); D.insert(mmtype::value_type("Smith, P.", 54321)); D.insert(mmtype::value_type("Johnson, J.", 10000)); cout << "There are " << D.size() << " elements.\n"; return 0; } // pairs.cpp: Operations on pairs. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 291. #include #include using namespace std; int main() { pair P(123, 4.5), Q; Q = pair(122, 4.5); cout << "P: " << P.first << " " << P.second << endl; cout << "Q: " << Q.first << " " << Q.second << endl; if (P > Q) cout << "P > Q\n"; ++Q.first; cout << "After ++Q.first: "; if (P == Q) cout << "P == Q\n"; return 0; } // rel_ops.cpp: Relational operators. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 292. // There is a version adapted for gcc below. #include #include using namespace std; using namespace std::rel_ops; class Example { public: Example(int i = 0, int j = 0): a(i), b(j){} int a, b; bool operator==(const Example &y)const { return a == y.a && b == y.b; } bool operator<(const Example &y)const { return a < y.a || a == y.a && b < y.b; } }; int main() { Example u(1, 3), v(1, 2); if (u > v) cout << "u > v\n"; if (u >= v) cout << "u >= v\n"; if (u != v) cout << "u != v\n"; if (u <= v) cout << "u <= v\n"; return 0; } // funobj1.cpp: A simple function object. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 294. #include using namespace std; struct sq { int operator()(int x)const {return x * x;} }; int main() { cout << "5 * 5 = " << sq()(5) << endl; // 25 return 0; } // funobj2.cpp: Function classes used as // template arguments. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 295. #include using namespace std; struct square { int operator()(int x)const {return x * x;} }; struct cube { int operator()(int x)const {return x * x * x;} }; template class cont { public: cont(int i): j(i){} void print()const {cout << T()(j) << endl;} private: int j; }; int main() { cont sqobj(10); cont cubeobj(10); sqobj.print(); // Output (= area of square): 100 cubeobj.print(); // Output (= contents of cube): 1000 return 0; } // funobj3.cpp: The operator() function is a // binary predicate. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 296. // This program is not accepted by gcc (see version below). #include using namespace std; template struct LessThan { bool operator()(const T &x, const T &y)const { return x < y; } }; struct CompareLastDigits { bool operator()(int x, int y)const { return x % 10 < y % 10; } }; template class PairSelect { public: PairSelect(const T &x, const T &y): a(x), b(y){} void PrintSmaller()const { cout << (Compare()(a, b) ? a : b) << endl; } private: T a, b; }; int main() { PairSelect > P(123.4, 98.7); P.PrintSmaller(); // Output: 98.7 PairSelect Q(123, 98); Q.PrintSmaller(); // Output: 123 (because 3 < 8) return 0; } // binder.cpp: The bind2nd adaptor used to count how // many array elements are less than 100. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 299. #include #include #include using namespace std; int main() { int a[10] = {800, 3, 4, 600, 5, 6, 800, 71, 100, 2}, n; n = count_if(a, a + 10, bind2nd(less(), 100)); cout << n << endl; // Output: 6 return 0; } // not2demo.cpp: The not2 adaptor demonstrated. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 300. #include #include #include using namespace std; int main() { int a[5] = {50, 30, 10, 40, 20}; sort(a, a+5, not2(less())); for (int i=0; i<5; ++i) cout << a[i] << " "; // Output: 50 40 30 20 10 cout << endl; return 0; } // not1demo.cpp: The not1 adaptor demonstrated. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 300. #include #include #include using namespace std; int main() { int a[10] = {800, 3, 4, 600, 5, 6, 800, 71, 100, 2}, n; // Count how many elements are not less than 100: n = count_if(a, a + 10, not1(bind2nd(less(), 100))); cout << n << endl; // Output: 4 return 0; } // not2own.cpp: The not2 adaptor applied to a function // object of our own. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 302. #include #include #include using namespace std; struct iLessThan: binary_function { bool operator()(int x, int y)const {return x < y;} }; int main() { int a[5] = {50, 30, 10, 40, 20}; sort(a, a+5, not2(iLessThan())); for (int i=0; i<5; ++i) cout << a[i] << " "; // Output: 50 40 30 20 10 cout << endl; return 0; } // not1own.cpp: The not1 adaptor applied to a // function object of our own. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 302. #include #include #include using namespace std; struct LessThan100: unary_function { bool operator()(int x)const {return x < 100;} }; int main() { int a[10] = {800, 3, 4, 600, 5, 6, 800, 71, 100, 2}, n; // Count how many elements are not less than 100: n = count_if(a, a+10, not1(LessThan100())); cout << n << endl; // Output: 4 return 0; } // negate.cpp: The transform algorithm and negate. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 303. #include #include #include using namespace std; int main() { int a[5] = {10, 20, -18, 40, 50}, b[5]; transform(a, a + 5, b, negate()); for (int i=0; i<5; ++i) cout << b[i] << " "; // Output: -10 -20 18 -40 -50 cout << endl; return 0; } // plus.cpp: The transform algorithm and plus. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 304. #include #include #include using namespace std; int main() { int a[5] = {10, 20, -18, 40, 50}, b[5] = { 2, 2, 5, 3, 1}, s[5]; transform(a, a + 5, b, s, plus()); for (int i=0; i<5; ++i) cout << s[i] << " "; // Output: 12 22 -13 43 51 cout << endl; return 0; } // compute.cpp: The transform algorithm and a // function object of our own. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 305. #include #include #include using namespace std; struct compute: binary_function { int operator()(int x, int y)const{return x + 2 * y;} }; int main() { int a[5] = {10, 20, -18, 40, 50}, b[5] = { 2, 2, 5, 3, 1}, result[5]; transform(a, a + 5, b, result, compute()); for (int i=0; i<5; ++i) cout << result[i] << " "; // Output: 14 24 -8 46 52 cout << endl; return 0; } // compute1.cpp: Replacing a[i] with 1.0/(a[i]*a[i]+1). // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 305. #include #include #include using namespace std; struct compute1: unary_function { double operator()(int x)const{return 1.0/(x*x + 1);} }; int main() { int a[5] = {2, 0, 1, 3, 7}; double b[5]; transform(a, a + 5, b, compute1()); for (int i=0; i<5; ++i) cout << b[i] << " "; // Output: 0.2 1 0.5 0.1 0.02 cout << endl; return 0; } // copy3.cpp: Copying a vector using 'inserter'. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 306. #include #include #include using namespace std; int main() { int a[4] = {10, 20, 30, 40}; vector v(a, a+4); list L(2, 123); copy(v.begin(), v.end(), inserter(L, L.end())); list::iterator i; for (i=L.begin(); i != L.end(); ++i) cout << *i << " "; // Output: 123 123 10 20 30 40 cout << endl; return 0; } // c_iter.cpp: const_iterator and // const_reverse_iterator. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 307. #include #include using namespace std; void showlist(const list &x) { // Forward: list::const_iterator i; for (i=x.begin(); i != x.end(); ++i) cout << *i << " "; cout << endl; // Output: 10 20 30 // Backward: list::const_reverse_iterator j; for (j=x.rbegin(); j != x.rend(); ++j) cout << *j << " "; cout << endl; // Output: 30 20 10 } int main() { list L; L.push_back(10); L.push_back(20); L.push_back(30); showlist(L); return 0; } // outiter.cpp: Output iterator; assignment statements // reading data from a file. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 308. #include #include using namespace std; int main() { ostream_iterator i(cout, "abc\n"); *i++ = 123; *i++ = 456; cout << endl; return 0; } // initer.cpp: Input iterator; assignment statements // performing input from a file. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 308. #include #include #include using namespace std; int main() { ifstream file("num.txt"); if (file) { istream_iterator i(file), eof; int x; while (i != eof) { x = *i++; cout << x << " "; } } else cout << "Cannot open file num.txt."; cout << endl; return 0; } // nonmodif.cpp: Nonmodifying algorithms. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 310. #include #include #include #include using namespace std; void display_greater_than10(int x) { if (x > 10) cout << x << " "; } int main() { int a[8] = {10, 12, 7, 3, 17, 7, 7, 3}; vector v(a, a+8); typedef vector::iterator itType; itType i; for_each(v.begin(), v.end(), display_greater_than10); cout << endl; // 12 17 i = find(v.begin(), v.end(), 7); cout << i - v.begin() << endl; // 2 (v[2] = 7) i = find_if(v.begin(), v.end(), bind2nd(greater(), 13)); cout << i - v.begin() << endl; // 4 (v[4] > 13) int b[3] = {17, 7, 3}; i = find_first_of(v.begin(), v.end(), b, b + 3); cout << i - v.begin() << endl; // 2 (v[2] = 7 occurs in b) i = adjacent_find(v.begin(), v.end()); cout << i - v.begin() << endl; // 5 (v[5] = v[6]) i = adjacent_find(v.begin(), v.end(), greater()); cout << i - v.begin() << endl; // 1 (v[1] > v[2]) int n = count(v.begin(), v.end(), 7); cout << n << endl; // 3 (3 occurrences of 7) n = count_if(v.begin(), v.end(), bind2nd(greater(), 10)); cout << n << endl; // 2 (2 elements > 10) bool eq = equal(v.begin(), v.end(), a); if (eq) cout << "v and a are equal\n"; a[2]++; // Now a[2] = 8 and v[2] = 7 pair itPair = mismatch(v.begin(), v.end(), a); if (itPair.first != v.end()) cout << *itPair.first << " != " << *itPair.second << endl; // 7 != 8 a[2]--; // Now a[2] = b[2] = 7 again. i = search(v.begin(), v.end(), b + 1, b + 3); cout << i - v.begin() << endl; // 2 (v[2]=b[1], v[3]=b[2]) i = find_end(v.begin(), v.end(), b + 1, b + 3); cout << i - v.begin() << endl; // 6 (v[6]=b[1], v[7]=b[2]) i = search_n(v.begin(), v.end(), 2, 7); cout << i - v.begin() << endl; // 5 (v[5] = v[6] = 7) i = search_n(v.begin(), v.end(), 2, 10, less()); cout << i - v.begin() << endl; // 2 (v[2] < 10, v[3] < 10) return 0; } // modif.cpp: Modifying algorithms. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 314. #include #include #include #include #include using namespace std; void show(int *first, int* last, const string s) { for (int* p = first; p != last; p++) cout << *p << " "; cout << "(" + s + ")\n"; } class twopowers { // Used with generate and generate_n public: twopowers(): i(1){} int operator()(){int k = i; i *= 2; return k;} private: int i; }; class myrandom { // Used with random_shuffle public: myrandom(){srand(1234567U);} int operator()(int n){return rand() % n;} }; bool differingAtMostOne(int x, int y) // Used with unique_copy { return y - x <= 1; } int main() { int a[8] = {1, 1, 2, 2, 3, 3, 4, 4}, b[8], res[8]; transform(a, a + 8, b, negate()); show(b, b + 8, "transform-1"); // -1 -1 -2 -2 -3 -3 -4 -4 transform(a, a + 8, b, res, multiplies()); show(res, res + 8, "transform-2"); // -1 -1 -4 -4 -9 -9 -16 -16 copy(a, a + 8, res); show(res, res + 8, "copy"); // 1 1 2 2 3 3 4 4 // To shift all elements a position to the right, in the // same container, use copy_backward, not copy: copy_backward(res, res + 7, res + 8); show(res, res + 8, "copy_backward"); // 1 1 1 2 2 3 3 4 int x = 5, y = 20; swap(x, y); cout << x << " " << y << endl; // 20 5 iter_swap(res, res + 7); // or: swap(res[0], res[7]) show(res, res + 8, "iter_swap"); // 4 1 1 2 2 3 3 1 swap_ranges(a, a + 8, res); show(res, res + 8, "swap_ranges"); // 1 1 2 2 3 3 4 4 swap_ranges(res, res + 8, a); // Restore old situation show(res, res + 8, "swap_ranges (restore)"); // 4 1 1 2 2 3 3 1 replace_copy(a, a + 8, res, 3, 5); // Copy from a to res, but change each 3 into 5 show(res, res + 8, "replace_copy"); // 1 1 2 2 5 5 4 4 replace_copy_if(a, a + 8, res, bind2nd(less(), 3), 0); // Copy from a to res, but change elements less than 3 // into zero. show(res, res + 8, "replace_copy_if"); // 0 0 0 0 3 3 4 4 // Algorithms 'replace' and 'replace_if' omitted. fill(res, res + 8, 1); show(res, res + 8, "fill"); // 1 1 1 1 1 1 1 1 fill_n(res, 8, 2); show(res, res + 8, "fill_n"); // 2 2 2 2 2 2 2 2 generate(res, res + 8, twopowers()); show(res, res + 8, "generate"); // 1 2 4 8 16 32 64 128 generate_n(res, 8, twopowers()); show(res, res + 8, "generate_n"); // 1 2 4 8 16 32 64 128 int *new_end = remove_copy(a, a + 8, res, 3); show(res, new_end, "remove_copy"); // 1 1 2 2 4 4 new_end = remove_copy_if(a, a + 8, res, bind2nd(less(), 3)); show(res, new_end, "remove_copy_if"); // 3 3 4 4 // Algorithms 'remove' and 'remove_if' omitted. new_end = unique_copy(a, a + 8, res); show(res, new_end, "unique_copy-1"); // 1 2 3 4 new_end = unique_copy(a, a + 8, res, differingAtMostOne); show(res, new_end, "unique_copy-2"); // 1 3 // Two versions of 'unique' omitted. reverse_copy(a, a + 8, res); show(res, res + 8, "reverse_copy"); // 4 4 3 3 2 2 1 1 // Algorithm 'reverse' omitted. rotate_copy(a, a + 2, a + 8, res); show(res, res + 8, "rotate_copy"); // 2 2 3 3 4 4 1 1 random_shuffle(res, res + 8); show(res, res + 8, "random_shuffle-1"); // 4 3 2 3 1 1 4 2 (in my test run) random_shuffle(a, a + 8, myrandom()); show(a, a + 8, "random_shuffle-2"); // 4 2 3 3 1 4 1 2 (in my test run) new_end = partition(a, a + 8, bind2nd(less(), 3)); show(a, a + 8, "partition-1"); // 2 2 1 1 3 4 3 4 cout << new_end - a << " in first partition\n"; // 4 // The algorithm stable_partition works similarly, but // preserves the relative order within each partition. // This can be relevant with more complex elements // each consisting of a key and a value, and with // duplicated keys. return 0; } // sortdemo.cpp: Sorting related STL algorithms. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 318. // There is a version adapted for gcc below. #include #include #include #include #include using namespace std; using namespace std::rel_ops; // See Section 9.9 class rectype { public: int nr; string name; rectype(int i = 0, string str = ""): nr(i), name(str){} bool operator==(const rectype &y)const { return nr == y.nr; } bool operator<(const rectype &y)const { return nr < y.nr; } }; void show(rectype *first, rectype* last) { for (rectype* p = first; p != last; p++) cout << p->nr << " " << p->name << " "; cout << endl; } bool greaterthan(const rectype &x, const rectype &y) { return x > y; // or: y < x } int main() { rectype a[5] = {rectype(5, "John"), rectype(5, "Peter"), rectype(3, "Mary"), rectype(7, "Ann"), rectype(2, "Tim")}; rectype b[5]; copy(a, a + 5, b); sort(b, b + 5); show(b, b + 5); // Output: 2 Tim 3 Mary 5 John 5 Peter 7 Ann // (but Peter might have preceded John) // If preserving the order John Peter is essential, // use stable_sort instead of sort. copy(a, a + 5, b); // stable_sort(b, b + 5, greater()); stable_sort(b, b + 5, greaterthan); // descending show(b, b + 5); // Output: 7 Ann 5 John 5 Peter 3 Mary 2 Tim copy(a, a + 5, b); partial_sort(b, b + 2, b + 5); show(b, b + 5); // Output: 2 Tim 3 Mary 5 Peter 7 Ann 5 John rectype *p = partial_sort_copy(a, a + 5, b, b + 2); // The two smallest elements of a appear in b, // and p points to b[2], hence: show(b, p); // Output: 2 Tim 3 Mary copy(a, a + 5, b); nth_element(b, b + 1, b + 5); // Place b[1] where it belongs, as this output shows: show(b + 1, b + 2); // Output: 3 Mary copy(a, a + 5, b); sort(b, b + 5); b[3] = b[2] = b[1]; // so [b+1, b+4) is a range of equal elements rectype *first = lower_bound(b, b + 5, b[2]); cout << "Lower bound: " << first - b << endl; // Output: Lower bound: 1 rectype *last = upper_bound(b, b + 5, b[2]); cout << "Upper bound: " << last - b << endl; // Output: Upper bound: 4 pair itPair = equal_range(b, b + 5, b[2]); cout << "itPair: " << itPair.first - b << " " << itPair.second - b << endl; // Output: itPair: 1 4 cout << (binary_search(b, b + 5, rectype(3, "xxx")) ? "Found\n" : "Not found"); // only the key 3 is used. // Output: Found rectype c[3] = {rectype(3, "Charles"), rectype(4, "George"), rectype(6, "Bill")}; // Another sorted sequence rectype d[8]; last = merge(b, b + 5, c, c + 3, d); show(d, last); // Output (on only line, not two): // 2 Tim 3 Mary 3 Mary 3 Mary 3 Charles 4 George // 6 Bill 7 Ann copy(b, b + 5, d); copy(c, c + 3, d + 5); // Concatenation of b and c in d inplace_merge(d, d + 5, d + 8); show(d, d + 8); // Same output as with 'merge'. return 0; } // setopstr.cpp: Set operations on sorted structures. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 321. #include #include #include using namespace std; void show(const string &s, const int *begin, const int *end) { cout << s << " "; copy(begin, end, ostream_iterator(cout, " ")); cout << endl; } int main() { int a[4] = {1, 5, 7, 8}, b[3] = {2, 5, 8}, sum[7], *pSumEnd, prod[4], *pProdEnd, dif[3], *pDifEnd, symdif[7], *pSymDifEnd; pSumEnd = set_union(a, a+4, b, b+3, sum); pProdEnd = set_intersection(a, a+4, b, b+3, prod); pDifEnd = set_difference(a, a+4, b, b+3, dif); pSymDifEnd = set_symmetric_difference(a, a+4, b, b+3, symdif); show("a: ", a, a+4); show("b: ", b, b+3); show("sum: ", sum, pSumEnd); show("prod: ", prod, pProdEnd); show("dif: ", dif, pDifEnd); show("symdif:", symdif, pSymDifEnd); if (includes(a, a+4, b, b+3)) cout << "a includes b.\n"; else cout << "a does not include b.\n"; if (includes(sum, pSumEnd, b, b+3)) cout << "sum includes b.\n"; else cout << "sum does not include b.\n"; return 0; } // heapdemo.cpp: Demonstration of heap operations. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 324. #include #include #include using namespace std; void show(const string &s, const int *begin, const int *end) { cout << s << endl << " "; copy(begin, end, ostream_iterator(cout, " ")); cout << endl; } int main() { cout << " "; for (int i=0; i<10; ++i) cout << " " << i; cout << endl; int a[10] = {20, 50, 40, 60, 80, 10, 30, 70, 25, 45}; show("Initial contents of a:", a, a+10); random_shuffle(a, a+10); show("After random_shuffle(a, a+10):", a, a+10); make_heap(a, a+10); show("After make_heap(a, a+10):", a, a+10); int x = *a; pop_heap(a, a+10); show("After x = *a and pop_heap(a, a+10):", a, a+9); a[9] = x; push_heap(a, a+10); show("After a[9] = x and push_heap(a, a+10):", a, a+10); sort_heap(a, a+10); show("After sort_heap(a, a+10):", a, a+10); return 0; } // minmax.cpp: The max algorithm (used with a special // comparison) and the min_element algorithm // applied to a list. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 326. #include #include #include using namespace std; bool CompareLastDigit(int x, int y) { return x % 10 < y % 10; } int main() { int x = 123, y = 74, MaxLastDigit; // Out of x and y, choose the value with // the larger last decimal digit: MaxLastDigit = max(x, y, CompareLastDigit); cout << MaxLastDigit << endl; // Output: 74 int a[5] = {10, 30, 5, 40, 20}; list L; L.insert(L.begin(), a, a+5); list::iterator i; i = min_element(L.begin(), L.end()); cout << *i << endl; // Output: 5 return 0; } // lexcomp.cpp: Lexicographical comparison. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 327. #include #include #include using namespace std; int main() { int a[4] = {1, 3, 8, 2}, b[3] = {1, 3, 9}; cout << "a: "; copy(a, a+4, ostream_iterator(cout, " ")); cout << "\nb: "; copy(b, b+3, ostream_iterator(cout, " ")); cout << endl; if (lexicographical_compare(a, a+4, b, b+3)) cout << "Lexicographically, a precedes b.\n"; if (!lexicographical_compare(a, a+4, b, b+3, greater())) cout << "Using the greater-than relation, we find:\n" "b lexicographically precedes a.\n"; return 0; } // permgen.cpp: Permutation generator, generating all // permutations of the sequence 1 2 3. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 328. // There is a version adapted for gcc below. #include #include using namespace std; int main() { int a[3] = {1, 2, 3}, k; cout << "Six successive calls to next_permutation.\n" "Situation before call and value returned by " "call:\n"; for (k=0; k<6; ++k) { copy(a, a+3, ostream_iterator(cout, " ")); bool b = next_permutation(a, a+3); cout << boolalpha << b << endl; // As we will see in Section 10.2, b will appear // as true or false (not as 1 or 0) because of // the manipulator boolalpha. }; cout << "Three successive calls to prev_permutation.\n" "Situation before call and value returned by " "call:\n"; for (k=0; k<3; ++k) { copy(a, a+3, ostream_iterator(cout, " ")); bool b = prev_permutation(a, a+3); cout << boolalpha << b << endl; }; return 0; } // numeric.cpp: Numerical algorithms. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 330. // There is a version adapted for gcc below. #include #include #include #include using namespace std; double power(int x, int n) { double y = 1; for (int k=0; k()); cout << "Product of all elements: " << prod << endl; // 4 * 2 * 3 = 24 int b[n] = {3, 4, 2}, inprod = 0; inprod = inner_product(a, a + n, b, inprod); cout << inprod << endl; // 0 + 4 * 3 + 2 * 4 + 3 * 2 = 26 int product=1; product = inner_product(a, a + n, b, product, multiplies(), power); cout << product << endl; // 1 * power(4, 3) * power(2, 4) * power(3, 2) = // 1 * 64 * 16 * 9 = 9216 int c[n], *iEnd; // a = {4, 2, 3} iEnd = partial_sum(a, a + n, c); copy(c, iEnd, ostream_iterator(cout, " ")); cout << endl; // Output: 4 6 9 int d[n]; iEnd = adjacent_difference(c, c + n, d); copy(d, iEnd, ostream_iterator(cout, " ")); cout << endl; // Output: 4 2 3 return 0; } Chapter 10 ========== // manip.cpp: A demonstration of some manipulators. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 343. // There is a version adapted for gcc below. #include #include using namespace std; int main() { cout << showbase << uppercase << "Left Right Hexa-\n" << "justified justified decimal\n"; for (int i=5; i<=10; i++) { cout << dec << left << setw(5) << i << setw(8) << i * i * i << right << setw(2) << i << setw(8) << i * i * i << hex << setw(8) << i << setw(8) << i * i * i << endl; } return 0; } // booleans.cpp: The manipulators boolalpha and noboolalpha. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 344. // This program does not compile with gcc. #include using namespace std; int main() { cout << true << " " << false << endl // 1 0 << boolalpha << true << endl; // true cout << false << endl; // false cout << noboolalpha << true << endl; // 1 return 0; } // mymanip.cpp: A manipulator defined by ourselves. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 344 and 401. // ios_base has been replaced with ios. The program now compiles // with both VC++ and gcc. #include using namespace std; ostream &hexadecimal(ostream &s) { s.setf(ios::hex, ios::basefield); return s; } int main() { cout << hexadecimal << 17 << endl; // Output: 11 return 0; } // peekdemo.cpp: Looking ahead. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 347. #include #include #include using namespace std; int main() { cout << "Enter some letters, " "immediately followed by an integer: "; string s; for (;;) { int ch = cin.peek(); if (isdigit(ch)) break; ch = cin.get(); s += ch; } int x; cin >> x; cout << "Letters: " << s << endl; cout << "Integer: " << x << endl; return 0; } // rword.cpp: Reading a word. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 351. #include #include using namespace std; int main() { string s; cout << "Enter some text: "; cin >> s; cout << "The following has been read: " << s << endl; return 0; } // copyaabb.cpp: // This program copies characters from file aa to file bb. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 354. #include #include using namespace std; int main() { char ch; int n=0; ifstream ff("aa"); if (!ff) { cout << "Cannot open aa for input\n"; return 1; } ofstream gg("bb"); if (!gg) { cout << "Cannot open bb for output\n"; return 1; } while (ff.get(ch)) { gg.put(ch); n++; } cout << n << " characters copied.\n"; return 0; } // saveload.cpp: Writing and reading class objects // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 359. #include #include #include using namespace std; class article { public: article(const string &ss = "", float xx = 0) : s(ss), x(xx){} void writeObject(ofstream &ff)const { ff << s << endl; ff << x << endl; } bool readObject(ifstream &ff) { getline(ff, s); ff >> x; char ch; ff.get(ch); return ff.good() && ch == '\n'; } void show()const{cout << s << " " << x << endl;} private: string s; float x; }; int main() { ofstream ff("test.txt"); article a("pencil", 1.23F), b("pen", 4.56F); a.writeObject(ff); b.writeObject(ff); ff.close(); ifstream gg("test.txt"); article a1, b1; if (!a1.readObject(gg) || !b1.readObject(gg)) cout << "Could not read two articles.\n"; else { a1.show(); // pencil 1.23 b1.show(); // pen 4.56 } return 0; } // update.cpp: Updating a file by using random access. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 362. // ios_base has been replaced with ios; the program now compiles // with both VC++ and gcc. #include #include #include #include using namespace std; void display(fstream &f) { long x; f.seekg(0); for (;;) { f.read((char *)(&x), sizeof(x)); if (f.eof()) break; cout << x << endl; } f.clear(); } void check(fstream &f, const string &s) { if (! f.good()) { cout << "I/O error: " << s << endl; exit(1); // See Section 11.9 } } int main() { long n, x, incr, i; cout << "Demonstration of updating a binary file.\n"; cout << "How many long ints are to be written? "; cin >> n; fstream f("info.bin", ios::in | ios::out | ios::binary | ios::trunc); check(f, "cannot open file info.bin"); for (i=0; i> i; } while (i < 0 || i >= n); f.seekg(i * sizeof(x), ios::beg); f.read((char *)(&x), sizeof(x)); check(f, "read fails"); cout << x << endl; cout << "Enter increment: "; cin >> incr; x += incr; f.seekp(i * sizeof(x), ios::beg); f.write((char *)(&x), sizeof(x)); check(f, "write fails"); display(f); return 0; } // failtest.cpp: Making a user-defined input // operator >> suitable for the // usual test on success or failure. // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 365. // ios_base has been replaced with ios. The program now compiles // with both VC++ and gcc. #include using std::cout; using std::cin; using std::endl; using std::istream; using std::ostream; using std::ios; class price { public: friend istream &operator>>(istream &is, price &pr); // requires dollar sign followed by a real number double getPrice()const{return x;} private: double x; }; istream &operator>>(istream &is, price &pr) { char ch; is >> ch >> pr.x; bool wrong = (is.fail() || ch != '$'); is.clear(); is.get(ch); wrong |= (ch != '\n'); while (ch != '\n') is.get(ch); if (wrong) is.setstate(ios::failbit); return is; } int main() { cout << "Enter a price (dollar sign, followed by number)\n"; price pr; if (cin >> pr) cout << "Price entered: " << pr.getPrice() << endl; else { cout << "Input incorrect\n"; cin.clear(); } cout << "Enter an integer: "; int i; cin >> i; cout << "Integer entered: " << i << endl; return 0; } // inmemfc.cpp: In-memory format conversion. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 367. // There is a version adapted for gcc below. #include #include #include #include using namespace std; int main() { float x = 2.5; // From binary to text (output to a string): ostringstream oo; oo << "Test:\n" // 6 characters << setfill('*') << setw(8) << setprecision(3) << x * x // 8 characters << endl; // 1 character ('\n') string s = oo.str(); cout << s << "Length: " << s.length() << endl; // 6 + 8 + 1 = 15 characters // From text to binary (input from a string): string t = "0.01234567 89"; double y; int i; istringstream ii(t); ii >> y >> i; cout << "y + i = " << fixed << setprecision(10) << y + i << endl; return 0; } Chapter 11 ========== // assert.cpp: Assertion ineffective because of NDEBUG. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 374. #define NDEBUG 1 #include #include using namespace std; int main() { int x = 2000; assert(x < 1000); cout << "Ready.\n"; return 0; } // errno.cpp: Demonstration of errno. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 375. #include #include #include #include using namespace std; int main() { double x = -1; double y = sqrt(x); // Error since x is negative if (errno == EDOM) { cout << "EDOM\n"; // Output: EDOM cout << strerror(errno) << endl; } return 0; } // vararg.cpp: Variable-length argument lists. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 381. #include #include using namespace std; int main() { double sum(int n, ...); // Literal program text! cout << sum(1, 9.87) << endl; cout << sum(5, 10.0, 20.0, 30.0, 40.0, 50.0) << endl; return 0; } double sum(int n, ...) // Literal program text! // n is the number of arguments that follow. { va_list argp; double s = 0; va_start(argp, n); while (n--) s += va_arg(argp, double); va_end(argp); return s; } // asterisk.cpp: Asterisks in conversion specifications for // printf. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 384. #include int main() { int width = 5, precision = 2, k = 1234; double x = 9.87654321; printf("x =%*.*f k =%*d\n", width, precision, x, width, k); return 0; } // scanfadv.cpp: Some advanced conversion specifications // for scanf. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 386. #include int main() { int k; char str[80], ch; printf("Enter a line of text, ending with a " "punctuation character:\n"); scanf("%[^.,;?!]%c%n", str, &ch, &k); printf("str=%s ch=%c k=%d\n", str, ch, k); return 0; } // numio.cpp: This program reads integers from the file // num.txt and computes their sum. It terminates // as soon as an invalid character is encountered // or the end of the file is reached. The sum is // displayed and also written to the file // outsum.txt. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 389. #include #include int main() { int sum = 0, x; FILE *fp = fopen("num.txt", "r"); if (fp == NULL) { printf("File num.txt not available.\n"); exit(1); } while (fscanf(fp, "%d", &x) == 1) sum += x; if (!feof(fp)) { printf("Invalid character read.\n"); } fclose(fp); printf("The sum (also written to outsum.txt) is: %d\n", sum); FILE *fpsum = fopen("outsum.txt", "w"); fprintf(fpsum, "%d\n", sum); fclose(fpsum); return 0; } // sprintf.cpp: In-memory format conversion using // sprintf and sscanf. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 391. #include int main() { float x = 2.5; // From binary to text (output to a C-style string): char s[100]; sprintf(s, "The square of 2.5 is %f\n", x * x); // Show the result: printf(s); // From text to binary (input from a C-style string): char *t = "0.01234567 89"; double y; int i; sscanf(t, "%lf %d", &y, &i); printf("y = %f i = %d\n", y, i); return 0; } // atexit.cpp: A demonstration of atexit. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 392. #include #include using namespace std; void ready(void) { cout << "Ready.\n"; } void almost_ready(void) { cout << "Almost ready.\n"; } int main() { atexit(ready); atexit(almost_ready); cout << "Not ready.\n"; return 0; } // timedemo.cpp: Demonstration of time and date functions. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 398. #include #include using namespace std; int main() { time_t t = time(NULL); tm s = *localtime(&t); cout << "Time in structure s (of type tm):\n"; cout << " sec=" << s.tm_sec << " min=" << s.tm_min << " hour=" << s.tm_hour << " mday=" << s.tm_mday << " mon=" << s.tm_mon << " year=" << s.tm_year << endl; cout << " wday=" << s.tm_wday << " yday=" << s.tm_yday << " isdst=" << s.tm_isdst << endl; cout << "Time obtained by asctime : " << asctime(&s); cout << "The same result obtained by ctime: " << ctime(&t); cout << "The following lines contain data " "obtained by using strftime:\n"; char str[80]; strftime(str, 80, " Time: %M minutes after %I o'clock %p\n" " Day: %A, %B %d, 20%y", &s); cout << str << endl; return 0; } Appendix A ========== // mymanip1.cpp: A manipulator defined by using a special // class. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 402. // ios_base has been replaced with ios. The program now compiles // with both VC++ and gcc. #include using namespace std; class ManipType {} hexadecimal; ostream& operator<<(ostream& s, ManipType m) { s.setf(ios::hex, ios::basefield); return s; } int main() { cout << hexadecimal << 17 << endl; // Output: 11 return 0; } // parmanip.cpp: Defining a manipulator with a parameter. // Both class 'horline' and operator<< are // specific for this manipulator. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 403. #include using namespace std; class horline { public: int n; horline(int nn):n(nn){} // Use nn to initialize n. }; ostream& operator<<(ostream& s, horline& h) { for (int i=0; i #include using namespace std; int main() { char ch = 'A'; double ff = 5.0/3; float f = ff; bool b = (f > 1); int i, j; j = 2 * (i = 5.0/3); // i = 1, j = 2 cout << "ch = " << ch << " ASCII value: " << int(ch) << endl; cout << setiosflags(ios::fixed) << setprecision(10); cout << "f = " << f << " ff = " << ff << endl; cout << "i = " << i << " j = " << j << endl; if (b) cout << "The variable b is equal to true.\n"; cout << "Number of bytes for type 'bool': " << sizeof(bool) << endl; cout << "Number of bytes for type 'char': " << sizeof(char) << endl; cout << "Number of bytes for type 'int': " << sizeof(int) << endl; cout << "Number of bytes for type 'float': " << sizeof(float) << endl; cout << "Number of bytes for type 'double': " << sizeof(double) << endl; return 0; } // table.cpp: This program produces a table. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 41. // Special version: gcc does not accept the manipulator 'fixed'. #include #include using namespace std; int main() { cout << " x f(x)\n\n"; cout << setiosflags(ios::fixed); for (int i=20; i<=40; i+=2) { double x = i/10.0; cout << setw(3) << setprecision(1) << x << " " << setw(15) << setprecision(10) << x * x + x + 1/x << endl; } return 0; } // align.cpp: Align strings. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 144. // Special version: gcc does not accept some manipulators such as 'fixed'. #include #include #include using namespace std; int main() { string names[3] = {"John", "George", "Jim"}; int ages[3] = {9, 100, 24}; for (int i=0; i<3; ++i) // Modified for gcc: cout << setiosflags(ios::left) << setw(10) << names[i] << setw(3) << setiosflags(ios::right) << ages[i] << endl; return 0; } // convdemo.cpp: In-memory format conversion // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 152. // Special version: // gcc has problems with the header sstream and the manipulator 'fixed'. #include #include #include using namespace std; int main() { // From string s to numerical value x: char s[80] = "1.2e-3"; istrstream istr(s, 80); double x; istr >> x; // x = 0.0012 cout << x << endl; // From numerical value y to string t: double y = 10.3456789; char t[80] = ""; // Initialized with null characters. ostrstream ostr(t, 80); ostr << setiosflags(ios::fixed) << setw(8) << setprecision(3) << y; cout << t << endl; // t = " 10.346" return 0; } // person.h: Header for the class Person. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 163. // Special version: // gcc does not accept the manipulator 'fixed'. #include #include #include using namespace std; class Person { public: Person(const string &s = "", int yr = 0, bool m = true) { name = s; yearOfBirth = yr; male = m; } void setName(const string &s){name = s;} void setYear(int yr){yearOfBirth = yr;} void setMF(bool m){male = m;} const string &getName()const { return name; } int getAgeAtEnd2000()const { return 2000 - yearOfBirth; } void print()const { // Modified for gcc: cout << setw(10) << setiosflags(ios::left) << name << setw(4) << setiosflags(ios::right) << getAgeAtEnd2000() << (male ? " (M)" : " (F)") << endl; } private: string name; int yearOfBirth; bool male; }; // nohiding.cpp: The principle of overriding. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 204. // Special version for gcc. #include using namespace std; class B { public: int f()const{return 1;} }; class D: public B { public: // The following line is omitted for gcc: // using B::f; int f(int k)const{return k;} }; int main() { D d; // cout << "d.f() = " << d.f() << endl; // The previous line has been replaced with this one: cout << "d.B::f() = " << d.B::f() << endl; return 0; } // istring.cpp: The template basic_string applied to // integers. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 242. // gcc gives unclear error messages about a header bastring.h. #include #include using namespace std; //typedef basic_string istring; // int instead of char! int main() { cout << "This program does not work with gcc.\n"; /* istring s; s += 123; s += 98; s += 45; for (int i=0; i #include using namespace std; // using namespace std::rel_ops; class Example { public: Example(int i = 0, int j = 0): a(i), b(j){} int a, b; bool operator==(const Example &y)const { return a == y.a && b == y.b; } bool operator<(const Example &y)const { return a < y.a || a == y.a && b < y.b; } }; int main() { Example u(1, 3), v(1, 2); if (u > v) cout << "u > v\n"; if (u >= v) cout << "u >= v\n"; if (u != v) cout << "u != v\n"; if (u <= v) cout << "u <= v\n"; return 0; } // funobj3.cpp: The operator() function is a // binary predicate. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 296. // This use of a function object (see printSmaller) is not accepted by gcc. #include using namespace std; template struct LessThan { bool operator()(const T &x, const T &y)const { return x < y; } }; struct CompareLastDigits { bool operator()(int x, int y)const { return x % 10 < y % 10; } }; template class PairSelect { public: PairSelect(const T &x, const T &y): a(x), b(y){} void PrintSmaller()const { // Not accepted by gcc: // cout << (Compare()(a, b) ? a : b) << endl; } private: T a, b; }; int main() { PairSelect > P(123.4, 98.7); P.PrintSmaller(); // Output: 98.7 PairSelect Q(123, 98); Q.PrintSmaller(); // Output: 123 (because 3 < 8) return 0; } // sortdemo.cpp: Sorting related STL algorithms. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 318. // Version adapted for gcc. #include #include #include #include #include using namespace std; //The following line is deleted for the gcc compiler: //using namespace std::rel_ops; // See Section 9.9 class rectype { public: int nr; string name; rectype(int i = 0, string str = ""): nr(i), name(str){} bool operator==(const rectype &y)const { return nr == y.nr; } bool operator<(const rectype &y)const { return nr < y.nr; } }; void show(rectype *first, rectype* last) { for (rectype* p = first; p != last; p++) cout << p->nr << " " << p->name << " "; cout << endl; } bool greaterthan(const rectype &x, const rectype &y) { return x > y; // or: y < x } int main() { rectype a[5] = {rectype(5, "John"), rectype(5, "Peter"), rectype(3, "Mary"), rectype(7, "Ann"), rectype(2, "Tim")}; rectype b[5]; copy(a, a + 5, b); sort(b, b + 5); show(b, b + 5); // Output: 2 Tim 3 Mary 5 John 5 Peter 7 Ann // (but Peter might have preceded John) // If preserving the order John Peter is essential, // use stable_sort instead of sort. copy(a, a + 5, b); // gcc does not accept the following two lines: // stable_sort(b, b + 5, greater()); // stable_sort(b, b + 5, greaterthan); // descending // show(b, b + 5); // Output: 7 Ann 5 John 5 Peter 3 Mary 2 Tim copy(a, a + 5, b); partial_sort(b, b + 2, b + 5); show(b, b + 5); // Output: 2 Tim 3 Mary 5 Peter 7 Ann 5 John rectype *p = partial_sort_copy(a, a + 5, b, b + 2); // The two smallest elements of a appear in b, // and p points to b[2], hence: show(b, p); // Output: 2 Tim 3 Mary copy(a, a + 5, b); nth_element(b, b + 1, b + 5); // Place b[1] where it belongs, as this output shows: show(b + 1, b + 2); // Output: 3 Mary copy(a, a + 5, b); sort(b, b + 5); b[3] = b[2] = b[1]; // so [b+1, b+4) is a range of equal elements rectype *first = lower_bound(b, b + 5, b[2]); cout << "Lower bound: " << first - b << endl; // Output: Lower bound: 1 rectype *last = upper_bound(b, b + 5, b[2]); cout << "Upper bound: " << last - b << endl; // Output: Upper bound: 4 pair itPair = equal_range(b, b + 5, b[2]); cout << "itPair: " << itPair.first - b << " " << itPair.second - b << endl; // Output: itPair: 1 4 cout << (binary_search(b, b + 5, rectype(3, "xxx")) ? "Found\n" : "Not found"); // only the key 3 is used. // Output: Found rectype c[3] = {rectype(3, "Charles"), rectype(4, "George"), rectype(6, "Bill")}; // Another sorted sequence rectype d[8]; last = merge(b, b + 5, c, c + 3, d); show(d, last); // Output (on only line, not two): // 2 Tim 3 Mary 3 Mary 3 Mary 3 Charles 4 George // 6 Bill 7 Ann copy(b, b + 5, d); copy(c, c + 3, d + 5); // Concatenation of b and c in d // gcc does not accept the following line: // inplace_merge(d, d + 5, d + 8); // show(d, d + 8); // Same output as with 'merge'. return 0; } // permgen.cpp: Permutation generator, generating all // permutations of the sequence 1 2 3. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 328. // Version adapted for gcc (with regard to the manipulator boolalpha). #include #include using namespace std; int main() { int a[3] = {1, 2, 3}, k; cout << "Six successive calls to next_permutation.\n" "Situation before call and value returned by " "call:\n"; for (k=0; k<6; ++k) { copy(a, a+3, ostream_iterator(cout, " ")); bool b = next_permutation(a, a+3); // gcc does not accept the manipulator boolalpha on the following line: // cout << boolalpha << b << endl; // We can obtain the same effect as follows: cout << (b ? "true" : "false") << endl; // As we will see in Section 10.2, b will appear // as true or false (not as 1 or 0) because of // the manipulator boolalpha. }; cout << "Three successive calls to prev_permutation.\n" "Situation before call and value returned by " "call:\n"; for (k=0; k<3; ++k) { copy(a, a+3, ostream_iterator(cout, " ")); bool b = prev_permutation(a, a+3); // Once again, we avoid the boolalpha manipulator as follows for gcc: cout << (b ? "true" : "false") << endl; }; return 0; } // numeric.cpp: Numerical algorithms. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 330. // Version adapted for gcc. #include #include #include #include using namespace std; double power(int x, int n) { double y = 1; for (int k=0; k()); cout << "Product of all elements: " << prod << endl; // 4 * 2 * 3 = 24 int b[n] = {3, 4, 2}, inprod = 0; inprod = inner_product(a, a + n, b, inprod); cout << inprod << endl; // 0 + 4 * 3 + 2 * 4 + 3 * 2 = 26 int product=1; // gcc does not accept the following statement: // product = inner_product(a, a + n, b, product, // multiplies(), power); cout << product << endl; // 1 * power(4, 3) * power(2, 4) * power(3, 2) = // 1 * 64 * 16 * 9 = 9216 int c[n], *iEnd; // a = {4, 2, 3} iEnd = partial_sum(a, a + n, c); copy(c, iEnd, ostream_iterator(cout, " ")); cout << endl; // Output: 4 6 9 int d[n]; iEnd = adjacent_difference(c, c + n, d); copy(d, iEnd, ostream_iterator(cout, " ")); cout << endl; // Output: 4 2 3 return 0; } // manip.cpp: A demonstration of some manipulators. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 343. // Special version for gcc, which avoids the manipulators left, right, // showbase, uppercase. #include #include using namespace std; int main() { cout << setiosflags(ios::showbase | ios::uppercase) << "Left Right Hexa-\n" << "justified justified decimal\n"; for (int i=5; i<=10; i++) { cout << dec << setiosflags(ios::left) << setw(5) << i << setw(8) << i * i * i << resetiosflags(ios::left) << setw(2) << i << setw(8) << i * i * i << hex << setw(8) << i << setw(8) << i * i * i << endl; } return 0; } // booleans.cpp: The manipulators boolalpha and noboolalpha. // Copied from: // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 344. // gcc does not accept these two manipulators. #include using namespace std; int main() { cout << "This program in its original form does not work\n" "with gcc because this compiler does not accept the\n" "manipulators boolalpha and noboolalpha.\n"; return 0; } //{ cout << true << " " << false << endl // 1 0 // << boolalpha << true << endl; // true // cout << false << endl; // false // cout << noboolalpha << true << endl; // 1 // return 0; //} // inmemfc.cpp: In-memory format conversion. // Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley, // p. 367. // For gcc, has been replaced with , // ostringstream with ostrstream and istringstream with istrstream. // Also, conventional C-strings have been used instead of the C++ 'string' type. #include #include #include #include using namespace std; int main() { float x = 2.5; // From binary to text (output to a string): char s[80] = ""; // initialized with 80 null characters ostrstream oo(s, 80); oo << "Test:\n" // 6 characters << setfill('*') << setw(8) << setprecision(3) << x * x // 8 characters << endl; // 1 character ('\n') cout << s << "Length: " << strlen(s) << endl; // 6 + 8 + 1 = 15 characters // From text to binary (input from a string): char t[80] = "0.01234567 89"; double y; int i; istrstream ii(t, 80); ii >> y >> i; cout << "y + i = " << setiosflags(ios::fixed) << setprecision(10) << y + i << endl; return 0; }