Справочное руководство по C++ - Бьярн Страустрап
Шрифт:
Интервал:
Закладка:
#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 gon";
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 againn";
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 endn";
}
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],input) == 0)
error("cannot open input file",argv[1]);
istream from(&f1);
filebuf f2;
if (f2.open(argv[2],output) == 0)
error("cannot open input file",argv[2]);
ostream to(&f2);
char ch;
while (from.get(ch)) to.put(ch);
if (!from.eof() || to.bad())
error("something strange happened",");
}
Примечания
1
"The C Programming Language" B. Kernighan, D. Ritchie. Prentice Hall, 1978, 1988. Есть русский перевод: "Язык программирования С. Задачи по языку С" Б. Керниган, Д. Ритчи, А. Фьюер. "Финансы и статистика". 1984