Справочное руководство по C++

Страустрап Бьярн

* ПРИМЕРЫ *

 

 

b1_1_1.cxx

#include ‹stream.hxx›

main()

{

 cout ‹‹ "Hello, world\n";

}

 

b1_1_3.cxx

#include ‹stream.hxx›

main ()

{

 int inch = 0;

 cout ‹‹ "inches=";

 cin ›› inch;

 cout ‹‹ inch;

 cout ‹‹ "in = ";

 cout ‹‹ inch*2.54;

 cout ‹‹ " cm\n";

}

 

b1_4_5v.cxx

#include ‹stream.hxx›

main()

{

 const float fac = 2.54;

 float x, in, cm;

 char ch = 0;

 for (int i= 0; i‹ 8; i++) {

  cerr ‹‹ "enter length: ";

  cin ›› x ›› ch;

  if (ch == 'i') {// inch

   in = x;

   cm = x*fac;

  }

  else if (ch == 'c') {// cm

   in = x/fac;

   cm = x;

  }

  else

   in = cm = 0;

   cerr ‹‹ in ‹‹ "in = " ‹‹ cm ‹‹ " cm\n";

 }

}

 

b1_5.cxx

#include ‹stream.hxx›

extern float pow(float, int);

main()

{

 for (int i=0; i‹10; i++) cout ‹‹ pow(2,i) ‹‹ "\n";

}

extern void error(char *);

float pow(float x, int n)

{

 if (n ‹ 0) {

  error ("sorry, negative exponent to pow()");

  return 0;

 }

 switch (n) {

 case 0: return 1;

 case 1: return x;

 default: return x*pow(x,n-1);

 }

}

void error(char *s)

{

 cout ‹‹ s;

}

 

b1__13.cxx

#include ‹stream.hxx›

// 1.11

class vector {

 int *v;

 int sz;

public:

 vector(int); // constructor

 ~vector(); // destructor

 int size() { return sz; }

 void set_size(int);

 int& operator[](int);

 int& elem(int i) { return v[i]; }

};

// 1.13

class vec: public vector {

 int low, high;

public:

 vec(int, int);

 int& elem(int);

 int& operator[](int);

};

main()

{

 vector a(10);

 for (int i=0; i‹a.size(); i++) {

  a[i] = i;

  cout ‹‹ a[i] ‹‹ " ";

 }

 cout ‹‹ "\n";

 vec b(10,19);

 for (i=0; i‹b.size(); i++) b[i+10] = a[i];

 for (i=0; i‹b.size(); i++) cout ‹‹ b[i+10] ‹‹ " ";

 cout ‹‹ "\n";

}

extern void exit(int);

// 1.13

void error(char* p)

{

 cerr ‹‹ p ‹‹ "\n";

 exit (1);

}

// 1.11

vector::vector(int s)

{

 if (s‹=0) error("bad vector size");

 sz = s;

 v = new int[s];

}

int& vector::operator[](int i)

{

 if (i‹0 || sz‹=i) error("vector index out of range");

 return v[i];

}

vector::~vector()

{

 delete v;

}

// 1.13

int& vec::elem(int i)

{

 return vector::elem(i-low);

}

vec::vec(int lb, int hb): (hb-lb+1)

{

 if (hb-lb‹0) hb = lb;

 low = lb;

 high = hb;

}

void vector::set_size(int) {/* dummy */}

int& vec::operator[](int i)

{

 if (i‹low || high‹i) error("vec index out of range");

 return elem(i);

}

 

b1__14.cxx

#include‹stream.hxx›

extern void exit(int);

extern void error(char*);

// 1.11

class vector {

 int *v;

 int sz;

public:

 vector(int); // constructor

 ~vector(); // destructor

 int size() { return sz; }

 void set_size(int);

 int& operator[](int);

 int& elem(int i) { return v[i]; }

};

vector::vector(int s)

{

 if (s‹=0) error("bad vector size");

 sz = s;

 v = new int[s];

}

int& vector::operator[](int i)

{

 if (i‹0 || sz‹=i) error("vector index out of range");

 return v[i];

}

vector::~vector()

{

 delete v;

}

// 1.14

class Vec: public vector {

public:

 Vec(int s): (s) {}

 Vec(Vec&);

 ~Vec() {}

 void operator=(Vec&);

 void operator*=(Vec&);

 void operator*=(int);

};

Vec::Vec(Vec& a): (a.size())

{

 int sz = a.size();

 for (int i = 0; i‹sz; i++) elem(i) =a.elem(i);

}

void Vec::operator=(Vec& a)

{

 int s = size();

 if (s != a.size()) error("bad vector size for =");

 for (int i =0; i‹s; i++) elem(i)=a.elem(i);

}

Vec operator+(Vec& a, Vec& b)

{

 int s = a.size();

 if (s!= b.size()) error("bad vector size for +");

 Vec sum(s);

 for (int i=0; i‹s; i++)

 sum.elem(i) = a.elem(i) + b.elem(i);

 return sum;

}

void error(char* p)

{

 cerr ‹‹ p ‹‹ "\n";

 exit (1);

}

void vector::set_size(int) {}

main()

{

 Vec a(10);

 Vec b(10);

 for (int i=0; i‹a.size(); i++) a[i] = i;

 b = a;

 Vec c = a+b;

 for (i=0; i‹c.size(); i++) cout ‹‹ c[i] ‹‹ "\n";

}

 

b1__16.cxx

#include ‹vector.hxx›

declare(vector,int);

implement(vector,int);

main()

{

 vector(int) vv(10);

 vv[2]American National Standard X3.159-1989. Американский национальный стандарт.
= 3;

 vv[10] = 4; // range error

}

 

b2_1_3.cxx

#include ‹stream.hxx›

int a = 1;

void f()

{

 int b = 1;

 static int c = 1;

 cout ‹‹ " a = " ‹‹ a++

  ‹‹ " b = " ‹‹ b++

  ‹‹ " c = " ‹‹ c++ ‹‹ "\n";

}

main ()

{

 while (a ‹ 4) f();

}

 

b2_3.cxx

#include ‹stream.hxx›

main()

{

 int* p = new int;

 cout ‹‹ "sizeof(int) = " ‹‹ sizeof(int) "\n";

}

 

b2_3_6a.cxx

#include ‹stream.hxx›

extern int strlen(char*);

char alpha[] = "abcdefghijklmnopqrstuvwxyz";

main ()

{

 int sz = strlen(alpha);

for (int i=0; i‹sz; i++) {

 char ch = alpha[i];

 cout ‹‹ "'" ‹‹ chr(ch) ‹‹ "'"

  ‹‹ " = " ‹‹ ch

  ‹‹ " = 0" ‹‹ oct(ch)

  ‹‹ " = 0x" ‹‹ hex(ch) ‹‹ "\n";

 }

}

 

b2_3_6b.cxx

#include ‹stream.hxx›

char v[2]American National Standard X3.159-1989. Американский национальный стандарт.
[5] = {

 'a', 'b', 'c', 'd', 'e',

 '0', '1', '2', '3', '4'

};

main() {

 for (int i = 0; i‹2; i++) {

  for (int j = 0; j ‹5; j++)

   cout ‹‹ "v[" ‹‹ i ‹‹ "][" ‹‹ j

    ‹‹ "]=" ‹‹ chr(v[i][j]) ‹‹ " ";

  cout ‹‹ "\n";

 }

}

 

b2_3_7.cxx

#include ‹stream.hxx›

main()

{

 char cv[10];

 int iv[10];

 char* pc = cv;

 int* pi = iv;

 cout ‹‹ "char* " ‹‹ long(pc+1)-long(pc) ‹‹ "\n";

 cout ‹‹ "int* " ‹‹ long(pi+1)-long(pi) ‹‹ "\n";

}

 

b2_3__10.cxx

#include ‹stream.hxx›

struct pair {

 char* name;

 int val;

};

extern int strlen(char*);

extern int strcpy(char*, char*);

extern int strcmp(char*, char*);

const large = 1024;

static pair vec[large];

pair* find(char* p)

{

 for (int i=0; vec[i].name; i++)

  if (strcmp(p,vec[i].name)==0) return &vec[i];

 if (i == large) return &vec[large-1];

 return &vec[i];

}

int& value(char* p)

{

 pair* res = find(p);

 if (res-›name == 0) {

  res-›name = new char[strlen(p)+1];

  strcpy(res-›name,p);

  res-›val = 0;

 }

 return res-›val;

}

const MAX = 256;

main ()

{

 char buf [MAX];

 while (cin››buf) value(buf)++;

 for (int i=0; vec[i].name; i++)

  cout ‹‹ vec[i].name ‹‹ ":" ‹‹ vec[i].val ‹‹ "\n";

}

 

b3_1all.cxx

#include ‹xstream.hxx›

#include ‹ctype.h›

enum token_value {

 NAME, NUMBER, END,

 PLUS = '+', MINUS = '-', MUL='*', DIV='/',

 PRINT=';', ASSIGN='=', LP='(', RP=')'

};

token_value curr_tok;

struct name {

 char* string;

 name* next;

 double value;

};

const TBLSZ = 23;

name* table[TBLSZ];

int no_of_errors;

double error(char* s) {

 cerr ‹‹ "error: " ‹‹ s ‹‹ "\n";

 no_of_errors++;

 return 1;

}

extern int strlen(const char*);

extern int strcmp(const char*, const char*);

extern char* strcpy(char*, const char*);

name* look(char* p, int ins = 0)

{

 int ii= 0;

 char *pp = p;

 while (*pp) ii = ii‹‹1 ^ *pp++;

 if (ii ‹ 0) ii = -ii;

 ii %= TBLSZ;

 for (name* n=table [ii]; n; n=n-›next)

  if (strcmp(p,n-›string) == 0) return n;

 if (ins == 0) error("name not found");

 name* nn = new name;

 nn-›string = new char[strlen(p) + 1];

 strcpy(nn-›string,p);

 nn-›value = 1;

 nn-›next = table[ii];

 table[ii] = nn;

 return nn;

}

inline name* insert(char* s) { return look (s,1); }

token_value get_token();

double term();

double expr()

{

 double left = term();

 for (;;)

  switch (curr_tok) {

  case PLUS:

   get_token();

   left += term();

   break;

  case MINUS:

   get_token();

   left -= term();

   break;

  default:

   return left;

  }

}

double prim();

double term()

{

 double left = prim();

 for (;;)

  switch (curr_tok) {

  case MUL:

   get_token();

   left *= prim();

   break;

  case DIV:

   get_token();

   double d = prim();

   if (d == 0) return error("divide by 0");

   left /= d;

   break;

  default:

   return left;

  }

}

int number_value;

char name_string[80];

double prim()

{

 switch (curr_tok) {

 case NUMBER:

  get_token();

  return number_value;

 case NAME:

  if (get_token() == ASSIGN) {

   name* n = insert(name_string);

   get_token();

   n-›value = expr();

   return n-›value;

  }

  return look(name_string)-›value;

 case MINUS:

  get_token();

  return -prim();

 case LP:

  get_token();

  double e = expr();

  if (curr_tok != RP) return error(") expected");

  get_token();

  return e;

 case END:

  return 1;

 default:

  return error ("primary expected");

 }

}

token_value get_token()

{

 char ch = 0;

 do {

  if (!cin.get(ch)) return curr_tok = END;

 } while (ch !='\n' && isspace(ch));

 switch (ch) {

 case ';':

 case '\n':

  cin ›› WS;

  return curr_tok=PRINT;

 case '*':

 case '/':

 case '+':

 case '-':

 case '(':

 case ')':

 case '=':

  return curr_tok=ch;

 case '0': case '1': case '2': case '3': case '4':

 case '5': case '6': case '7': case '8': case '9':

 case '.':

  cin.putback(ch);

  cin ›› number_value;

  return curr_tok=NUMBER;

 default:

  if (isalpha(ch)) {

   char* p = name_string;

   *p++ = ch;

   while (cin.get(ch) && isalnum(ch)) *p++ = ch;

   cin.putback(ch);

   *p = 0;

   return curr_tok=NAME;

  }

  error ("bad token");

  return curr_tok=PRINT;

 }

}

int main(int argc, char* argv[])

{

 switch (argc) {

 case 1:

  break;

 case 2:

  cin = *new istream(strlen(argv[1]"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
),argv[1]"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
);

  break;

 default:

  error("too many arguments");

  return 1;

 }

 // insert predefined names:

 insert("pi")-›value = 3.1415926535897932385;

 insert("e")-›value = 2.7182818284590452354;

 while (1) {

  get_token();

  if (curr_tok == END) break;

  if (curr_tok == PRINT) continue;

  cout ‹‹ expr() ‹‹ "\n";

 }

 return no_of_errors;

}

 

b3_2_6a.cxx

extern void strcpy(char *,char *);

extern void exit(int);

extern int strlen(char *);

char *save_string(char* p)

{

 char* s = new char[strlen(p)+1];

 strcpy(s,p);

 return s;

}

int main (int argc, char* argv[])

{

 if (argc ‹ 2) exit(1);

 int size = strlen(argv[1]"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
)+1;

 char* p = save_string (argv[1]"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
);

 delete[size] p;

}

 

b3_2_6b.cxx

#include ‹stream.hxx›

extern void exit(int);

void out_of_store()

{

 cout ‹‹ "operator new failed: out of store\n";

 exit(1);

}

typedef void (*PF)();

extern PF set_new_handler(PF);

main()

{

 set_new_handler(&out_of_store);

 char *p = new char[100000000];

 cout ‹‹ "done, p = " ‹‹ long(p) ‹‹ "\n";

}

 

b4_6_8.cxx

// This version of the program does not assume sizeof(int) == sizeof(char*)!

#include ‹stream.hxx›

#include ‹stdarg.hxx›

extern void exit(int);

void error (int …);

main(int argc, char* argv[])

{

 switch (argc) {

 case 1:

  error(0,argv[0],(char*)0);

  break;

 case 2:

  error(0,argv[0],argv[1]"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
,(char*)0);

  break;

 default:

  error(1,"with",dec(argc-1),"arguments",(char*)0);

 }

}

void error(int n …)

{

 va_list ap;

 va_start(ap,n);

 for (;;) {

  char *p = va_arg(ap,char*);

  if (p == 0) break;

  cerr ‹‹ p ‹‹ " ";

 }

 va_end(ap);

 cerr ‹‹ "\n";

 if (n) exit(n);

}

 

b4_6_9.cxx

#include ‹stream.hxx›

struct user {

 char *name;

 char* id;

 int dept;

};

typedef user* Puser;

user heads[] = {

 "Mcilroy M.D", "doug", 11271,

 "Aho A.V.", "ava", 11272,

 "Weinberger P.J.", "pjw", 11273,

 "Schryer N.L.", "nls", 11274,

 "Schryer N.L.", "nls", 11275,

 "Kernighan B.W.", "bwk", 11276

};

typedef int (*CFT)(char*,char*);

void sort(char* base, unsigned n, int sz, CFT cmp)

{

 for (int i=0; i‹n-1; i++)

  for (int j=n-1; i‹j; j--) {

   char* pj = base+j*sz;

   char *pj1 = pj-sz;

   if ((*cmp)(pj,pj1) ‹ 0)

    // swap b[j] and b[j-1]

    for (int k=0; k‹sz; k++) {

     char temp = pj[k];

     pj[k] = pj1[k];

     pj1[k] = temp;

    }

  }

}

void print_id(Puser v, int n)

{

 for (int i=0; i‹n; i++)

  cout ‹‹ v[i].name ‹‹ "\t"

   ‹‹ v[i].id ‹‹ "\t"

   ‹‹ v[i].dept ‹‹ "\n";

}

extern int strcmp(char*, char*);

int cmp1(char* p, char* q)

{

 return strcmp(Puser(p)-›name, Puser(q)-›name);

}

int cmp2(char* p, char* q)

{

 return Puser(p)-›dept - Puser(q)-›dept;

}

main ()

{

 sort((char*)heads,6,sizeof(user),cmp1);

 print_id(heads,6);

 cout ‹‹ "\n";

 sort ((char*)heads,6,sizeof(user),cmp2);

 print_id(heads,6); // in department number order

}

 

b5_3_2.cxx

#include ‹stream.hxx›

class intset {

 int cursize, maxsize;

 int *x;

public:

 intset(int m, int n);

 ~intset();

 int member(int t);

 void insert(int t);

 void iterate(int& i) { i = 0; }

 int ok(int& i) { return i‹cursize; }

 int next(int& i) { return x[i++]; }

};

extern void exit (int);

void error(char *s)

{

 cout ‹‹ "set: " ‹‹ s ‹‹ "\n";

 exit(1);

}

extern int atoi(char *);

extern int rand();

int randint (int u) // in the range 1…u

{

 int r = rand();

 if (r ‹ 0) r = -r;

 return 1 + r%u;

}

intset::intset(int m, int n)

{

 if (m‹1 || n‹m) error("illegal intset size");

 cursize = 0;

 maxsize = m;

 x = new int[maxsize];

}

intset::~intset()

{

 delete x;

}

void intset::insert(int t)

{

 if (++cursize › maxsize) error("too many elements");

 int i = cursize-1;

 x[i] = t;

while (i›0 && x[i-1]›x[i]) {

 int t = x[i];

 x[i] = x[i-1];

 x[i-1] = t;

 i--;

 }

}

int intset::member(int t)

{

 int l = 0;

 int u = cursize-1;

 int m =0;

 while (l ‹= u) {

  m = (l+u)/2;

  if (t ‹ x[m])

   u = m-1;

  else if (t › x[m])

   l = m+1;

  else

   return 1; // found

 }

 return 0; // not found

}

void print_in_order(intset* set)

{

 int var;

 set-›iterate(var);

 while (set-›ok(var)) cout ‹‹ set-›next(var) ‹‹ "\n";

}

main (int argc, char *argv[])

{

 if (argc!= 3) error("two arguments expected");

 int count = 0;

 int m = atoi(argv[1]"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
);

 int n = atoi (argv[2]American National Standard X3.159-1989. Американский национальный стандарт.
);

 intset s(m,n);

 int t = 0;

 while (count ‹m) {

  t = randint(n);

  if (s.member(t)==0) {

   s.insert(t);

   count++;

  }

 }

 print_in_order(&s);

}

 

b5_4_5.cxx

#include ‹stream.hxx›

struct cl

{

 char* val;

 void print(int x) { cout ‹‹ val ‹‹ x ‹‹ "\n"; }

 cl(char *v) { val = v; }

};

typedef void (cl::*PROC)(int);

main()

{

 cl z1("z1 ");

 cl z2("z2 ");

 PROC pf1 = &cl::print;

 PROC pf2 = &cl::print;

 z1.print(1);

 (z1.*pf1)(2);

 z2.print(3);

 ((&z2)-›*pf2)(4);

}

 

b5_5_3.cxx

main() {

 char *p = new char[100];

 char *q = new char[100];

 delete p;

 delete p;

}

 

b6_3_2.cxx

#include "stream.hxx"

int error (char * p)

{

 cout ‹‹ p ‹‹ "\n";

 return 1;

}

class tiny {

 char v;

 tiny assign(int i)

 {v  = (i&~63) ? (error("range error"),0) : i; return *this; }

public:

 tiny (int i) { assign(i); }

 tiny (tiny& t) { v = t.v; }

 tiny operator=(tiny& t1) { v = t1.v; return *this; }

 tiny operator=(int i) { return assign(i); }

 int operator int() { return v; }

};

void main()

{

 tiny c1 = 2;

 tiny c2 = 62;

 tiny c3 = (c2 - c1);

 tiny c4 = c3;

 int i = (c1 + c2);

 c1 = (c2 + (2 * c1));

 c2 = c1 - i;

 c3 = c2;

}

 

b6_6.cxx

#include ‹stream.hxx›

extern int strcpy(char*, char*);

extern int strlen(char *);

struct string {

 char *p;

 int size;

 inline string(int sz) { p = new char[size=sz]; }

 string(char *);

 inline ~string() { delete p; }

 void operator=(string&);

 string(string&);

};

string::string(char* s)

{

 p = new char [size = strlen(s) + 1];

 strcpy (p,s);

}

void string::operator=(string& a)

{

 if (this == &a) return;

 delete p;

 p=new char[size=a.size];

 strcpy(p,a.p);

}

string::string(string& a)

{

 p=new char[size=a.size];

 strcpy(p,a.p);

}

string g(string arg)

{

 return arg;

}

main()

{

 string s = "asdf";

 s = g(s);

 cout ‹‹ s.p ‹‹ "\n";

}

 

b6_7.cxx

#include ‹stream.hxx›

#include ‹string.h›

struct pair {

 char * name;

 int val;

};

class assoc {

 pair * vec;

 int max;

 int free;

public:

 assoc(int);

 int& operator[](char*);

 void print_all();

};

assoc::assoc(int s)

{

 max = (s‹16) ? s : 16;

 free = 0;

 vec = new pair[max];

}

int& assoc::operator[](char * p)

/*

 maintain a set of "pair"s

 search for p,

 return a reference to the integer part of its "pair"

 make a new "pair" if "p" has not been seen

*/

{

 register pair* pp;

 for (pp=&vec[free-1]; vec‹=pp; pp--)

  if (strcmp(p, pp-›name)-0) return pp-›val;

 if (free==max) {// overflow: grow the vector

  pair* nvec = new pair[max*2];

  for (int i=0; i‹max; i++) nvec[i] = vec[i];

  delete vec;

  vec = nvec;

  max = 2*max;

 }

 pp = &vec[free++];

 pp-›name = new char[strlen(p)+1];

 strcpy(pp-›name,p);

 pp-›val = 0;

 return pp-›val;

}

void assoc::print_all()

{

 for (int i=0; i‹free; i++)

  cout ‹‹ vec[i].name ‹‹ ": " ‹‹ vec[i].val ‹‹ "\n";

}

main()

{

 const MAX = 256;

 char buf[MAX];

 assoc vec(512);

 while (cin››buf) vec[buf]++;

 vec.print_all();

}

 

b6_8.cxx

#include ‹stream.hxx›

#include ‹string.h›

struct pair {

 char* name;

 int val;

};

class assoc {

 friend class assoc_iterator;

 pair* vec;

 int max;

 int free;

public:

 assoc(int);

 int& operator[](char*);

};

class assoc_iterator {

 assoc* cs;

 int i;

public:

 assoc_iterator(assoc& s) { cs =&s; i = 0; }

 pair* operator()()

 { return (i‹cs-›free) ? &cs-›vec[i++] : 0; }

};

assoc::assoc(int s)

{

 max = (s‹16) ? s : 16;

 free = 0;

 vec = new pair[max];

}

int& assoc::operator[](char* p)

{

 register pair* pp;

 for (pp = &vec[free-1]; vec‹=pp; pp--)

  if (strcmp(p,pp-›name)==0) return pp-›val;

 if (free == max) {

  pair* nvec = new pair[max*2];

  for (int i=0; i‹max; i++) nvec[i] = vec[i];

  delete vec;

  vec = nvec;

  max = 2*max;

 }

 pp =&vec[free++];

 pp-›name = new char[strlen(p)+1];

 strcpy(pp-›name,p);

 pp-›val = 0;

 return pp-›val;

}

main()

{

 const MAX = 256;

 char buf[MAX];

 assoc vec(512);

 while (cin››buf) vec[buf]++;

 assoc_iterator next(vec);

 pair* p;

 while (p = next())

  cout ‹‹ p-›name ‹‹ ": " ‹‹ p-›val ‹‹ "\n";

}

 

b6_9.cxx

#include ‹stream.hxx›

#include ‹string.h›

extern void exit(int);

class string {

 struct srep {

  char* s;

  int n;

 };

 srep *p;

public:

 string(char *);

 string();

 string(string&);

 string& operator=(char *);

 string& operator=(string&);

 ~string();

 char& operator[](int i);

 friend ostream& operator‹‹(ostream&, string&);

 friend istream& operator››(istream&, string&);

 friend int operator==(string&x, char *s)

  { return strcmp(x.p-›s, s) == 0; }

 friend int operator==(string&x, string&y)

  { return strcmp(x.p-›s, y.p-›s) == 0; }

 friend int operator!=(string&x, char *s)

  {return strcmp(x.p-›s, s) != 0;}

 friend int operator!=(string&x, string&y)

  {return strcmp (x.p-›s, y.p-›s) != 0;}

};

string::string()

{

 p = new srep;

 p-›s = 0;

 p-›n = 1;

}

string::string(char* s)

{

 p = new srep;

 p-›s = new char[strlen(s) +1];

 strcpy(p-›s, s);

 p-›n = 1;

}

string::string(string& x)

{

 x.p-›n++;

 p = x.p;

}

string::~string()

{

 if (--p-›n - 0) {

  delete p-›s;

  delete p;

 }

}

string& string::operator=(char* s)

{

 if (p-›n › 1) {

  p-›n--;

  p = new srep;

 }

 else if (p-›n == 1)

  delete p-›s;

 p-›s = new char[strlen(s)+1];

 strcpy(p-›s, s);

 p-›n = 1;

 return *this;

}

string& string::operator=(string& x)

{

 x.p-›n++;

 if (--p-›n == 0) {

  delete p-›s;

  delete p;

 }

 p = x.p;

 return *this;

}

ostream& operator‹‹(ostream& s, string& x)

{

 return s ‹‹ x.p-›s ‹‹ " [" ‹‹ x.p-›n ‹‹ "]\n";

}

istream& operator››(istream& s, string& x)

{

 char buf[256];

 s››buf;

 x = buf;

 cout ‹‹ "echo: " ‹‹ x ‹‹ "\n";

 return s;

}

void error(char* p)

{

 cout ‹‹ p ‹‹ "\n";

 exit(1);

}

char& string::operator[](int i)

{

 if (i‹0 || strlen(p-›s)‹i) error("index out of range");

 return p-›s[i];

}

main()

{

 string x[100];

 int n;

 cout ‹‹ "here we go\n";

 for (n = 0; cin››x[n]; n++) {

  string y;

  if (n==100) error("too many strings");

  cout ‹‹ (y = x[n]);

  if (y=="done") break;

 }

 cout ‹‹ "here we go back again\n";

 for (int i=n-1; 0‹=i; i--) cout ‹‹ x[i];

}

 

b7_2_8.cxx

#include ‹stream.hxx›

struct employee {

 friend class manager;

 employee* next;

 char* name;

 short department;

 virtual void print();

};

struct manager: employee {

 employee* group;

 short level;

 void print();

};

void employee::print()

{

 cout ‹‹ name ‹‹ "\t" ‹‹ department ‹‹ "\n";

}

void manager::print()

{

 employee::print();

 cout ‹‹ "\tlevel " ‹‹ level ‹‹ "\n";

}

void f(employee* ll)

{

 for (; ll; ll=ll-›next) ll-›print();

}

main ()

{

 employee e;

 e.name = "J. Brown";

 e.department = 1234;

 e.next = 0;

 manager m;

 m.name = "J. Smith";

 m.department = 1234;

 m.level = 2;

 m.next = &e;

 f(&m);

}

 

b7_7.cxx

#include ‹stream.hxx›

struct base { base(); };

struct derived: base { derived(); };

base:: base()

{

 cout ‹‹ "\tbase 1: this=" ‹‹ long(this) ‹‹ "\n";

 if (this == 0) this = (base*)27;

 cout ‹‹ "\tbase 2: this=" ‹‹ long(this) ‹‹ "\n";

}

derived::derived()

{

 cout ‹‹ "\tderived 1: this=" ‹‹ long(this) ‹‹ "\n";

 if (this == 0) this = (derived*)43;

 cout ‹‹ "\tderived 2: this=" ‹‹ long(this) ‹‹ "\n";

}

main()

{

 cout ‹‹ "base b;\n";

 base b;

 cout ‹‹ "new base;\n";

 new base;

 cout ‹‹ "derived d;\n";

 derived d;

 cout ‹‹ "new derived;\n";

 new derived;

 cout ‹‹ "new derived;\n";

 new derived;

 cout ‹‹ "at the end\n";

}

 

b8_3_3.cxx

#include ‹xstream.hxx›

extern void exit(int);

void error(char* s, char* s2)

{

 cerr ‹‹ s ‹‹ " " ‹‹ s2 ‹‹ "\n";

 exit(1);

}

main(int argc, char* argv[])

{

 if (argc != 3) error ("wrong number of arguments",");

 filebuf f1;

 if (f1.open(argv[1]"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
,input) == 0)

  error("cannot open input file",argv[1]"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984
);

 istream from(&f1);

 filebuf f2;

 if (f2.open(argv[2]American National Standard X3.159-1989. Американский национальный стандарт.
,output) == 0)

  error("cannot open input file",argv[2]American National Standard X3.159-1989. Американский национальный стандарт.
);

 ostream to(&f2);

 char ch;

 while (from.get(ch)) to.put(ch);

 if (!from.eof() || to.bad())

  error("something strange happened",");

}