Вы находитесь на странице: 1из 161

1

++
, 1995 .

1 - C++
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
1.10
1.11
1.12 Inline-
1.13
1.14
1.15 (friend)
1.16
1.17
1.18

2 -
2.1
2.2
2.3
2.4
2.5
2.6

3 -
3.1
3.2
3.3
3.4
3.5

4 -
4.1
4.2
4.3
4.4
4.5
4.6




C++

C

2
4.7
4.8

5 -
5.1
5.2
5.3
5.4
5.5
5.6

6 -
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
6.10
6.11
6.12

7 -
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8

8 -
8.1
8.2
8.3
8.4
8.5
8.6
8.7
8.8

" , ." ..
C++ - , ,
.
C++ C.
, C, C++
. ,
,
.
. ,
. ,
.
-.
, .
C++ . - , .
, ,
, , ,
. C++
, C,
. ,
, , inline- ,
, ,
. C++ C
(, , , ..).
, .
C++ , .
,
C. C++ C , C++
,
C.
,
. C++,
.

C++ ,
. , , ,
, , , , , ,
, .
/.
, C++ ,
, , ,
. : ,
, , , , ,
.
, , , ,
, , , C++,
Bell Labs, , , 26-27 1985 . ,

4
" ," - , - " ." .

,
C++ . C++, ,
C++, C++.
: ,
C++.


1 - C++, ,
. C
; , C C++.
C++;
, 2, 3 4.
2, 3 4 C++, :
, C++ . ,
C++, C.
,
.
5, 6 7 C++ , ,
C. 5 , ,
, , ,
, . 6 ,
, ,
, ,
, .
7 ,
,

, .
8 ostream istream,
-. :
, C++.
, , C++.
#2.3.4 ( 2 3.4). ; , #.8.5.5.


C++
#. ,
UNIX AT&T 3B, DEC VAX, IBM 370
Motorolla 68000. , ,
, 3B UNIX System V
2 [15], VAX11/750 8- UNIX [16] CCI Power 6/32 BSD4.2 UNIX
[17]. , , - " C++",
"" ( #.15.3),
C C++.

.
. ,
.

, .
, (*1) ,
(*2) , (*3) - . , ,
, ,
. (*1) , , ,
. ,
, , (*5) .
2-4 C.
. [1]
.
5-7. , , ,
.
C++ .


; ,
,
. C;
C.
C++ .
, ,
. ,
. , , C++, -
- . ,
, ,
.
,
. , ,
"" , ;
, 16- , 32-
.
C++
, C UNIX.
,
, C++. C++
. C++ ,
. , ,

.
C++
.
.
,
.


, C++ C [7]. C ,
C ,
. C, ,
BCPL [9]; , // () C++
BCPL. BCPL, , C++ - VALOF .
Simula67 [2,3];
( ). ,

.
C++ ,
, 68 [14].
C++ - ( 1983).
1980 "C ".
, , ,
Simula67, . "C "
,
, ()
. "C " , ,
. C++
1983; C++
.
C++ .
C. "++" - C. C+
; , .
C , C++ , ++C. D ,
C
. C++
[8].
C++ ,
, C .

. C++ ; ,
. , C++
C++. " C++" " C++".
C++
, ,
.
C++ C, (1) ,
; (2) ;
(3) ; (4) UNIX. C
, , C
. , C "C " (,
) C Simula-
.
C++ , , ,
C, ,
, C. , C
(., , [12]). ,
(1) C, C++ ,
C C++; (2)
, C,
C++ , C++ C
C; (3) , C,
, , C++,
; (4), C++ C
, ,
, .
C++, , ,
C C++, .
C ,
C++ (. [11]). ANSI C [10]
, "C ".
; , void* ANSI C C++.

ANSI , C++,
. , ,
(#.11), , ,
. , C ANSI C ,
C++ (. #.11).


C++ C
C . , C C++, ,
,
, : ,
. new delete,
C++
.
C++ , C.
, , C++
inline, , ,
.
C
.
C++, , .
C C++ ,
. C . C++ ,
, .
, ,

. ,
. ,
, ,
, ..,
.
, C++ ,
, C. (
1000 ) ,
. . 10 000
, ,
, . C++ ,
,
25 000 .
, , , , ,
, .
, ,
, ,
, .
, , ,
, .. C++ ,
, ,
. ,
.
,
, .. ,
, , . ,
,
, .

- ,
. C++
; C++ , , ..,
C , .


:
, , ,
, , .
, " ",

. C. ,
" ",
. ,
C C++.
, /, ,
, .
.
, .
;
, . ,
,
, ..
.
. ,
C++ .

C++
:
, , ,
.
-
.
,
.
, , . -
; , : ,
, .
; (
) .
, .
, :
? / ?
? ,
-, , "",
, "
" .
,
: , , .. ,
, ,
. C++ ,
, .
, .

,
, ,
. , , ()
. , A B. "A
B", "A B" "A B"
, "A B" (
-). , , ,
"A B ...".
,
, ,
. C++
.
(?). , ,
.
( )
(#7.2.8). , ,
( ).
, . ,
,
; , "A B C ...".
C++ , ,
(#7.2.5).

; .
, ,
.
C++ friend (#5.4.1).
(
),
, , , ,
. -
,
.
, ,
, ,
. , ,
, .
" C++" "
?" : ", " ".
." C++ ,
- .

(*1)
(*1) , "- ." (. .)

, C++.
, ,
. ,
. .
, .
; !
[1] ,
. , :
[a] "" , .
[b] "" , .

10

[c] , .
; ()
, .
[2] , ,
, , , :
[a] .
[b] ( ).
[c] -.
[d] , [a], [b] [c].
[e] - .
[f] " "; .
[g] inline-, .

C
- C, C++ C,
, , C++. , ,
" C" (#.15). , C++
- , C. (#define) C++
; , const (#2.4.6)
enum (#2.4.7), inline (#1.12) - .
-
. ,
, , , -
, . malloc() - new
(#3.2.6) . -
(#2.5.2).
# C++ AT&T, Software Sales and Marketing, PO Box 25000, Greensboro, NC 27420, USA (
800-828-UNIX) , UNIX. (. )

11

1
C++
- .
-
C++.
C++, , ,
.
C++: , ,
, , .
C++ , , ,
, .

1.1
C++.
C++,
, . ,
,
.
,
. , ,
.

1.1.1
, , :
#include
main()
{
cout << "Hello, world\n";
}
#include , ,
stream.h. cout << "Hello, world\n" .
<< (" "*1) ( , "Hello, world\n"
cout). - , .
\, , ;
, \n . Hello, world
.
*1 C << . << ;
<< , .
, #1.8. (. )

main() { ... }
, main. main,
.

1.1.2
cout , <<?
C++ ;

12

, ,
. ,
, .
, , ( cout <<).
,
( ,
). cout << stream.h, ,
, .
cout <<.
, ,
stream.h, ,
, .
C++ CC. , cc
C; . ,
"Hello, world" hello.c,
($ - ):
$ CC hello.c
$ a.out
Hello,world
$
a.out - .
, -o:
$ CC hello.c -o hello
$ hello
Hello,world
$

1.1.3
( ) .
, , .
#include
main()
{
int inch = 0;
cout << "inches";
cin >> inch;
cout << inch;
cout << " in = ";
cout << inch*2.54;
cout << " cm\n";
}

// inch -

main() inch.
>> (" ") cin. cin >>, , .
:
$ a.out
inches=12
12 in = 30.48 cm
$
; . <<
,
:
cout << inch << " in = " << inch*2.54 << " cm\n";

13
.
, ,
-. , C++,
"" -
#include. , C++ , ,
-; , ,
<< >>.

1.2
,

. C++ .
/* , */.
(, ).

, , /* */ .
// , ,
. , .
. // ,
/* */, /* //.

1.3
, ,
. ,
int inch;
, inch int, , inch .
- , . .
. , +, -, * /.
, stream.h, int <<,
ostream.
, , .
,
cout << inch << " in = " << inch*2.54 << " cm\n";
. ,
inch inch*2.54
.
C++ . C++
, .

1.3.1 T
, ,
:
char

short

int

long

float

double

, -
. char ,
(, ), int ,
(, ). , , . C++
char, char .
:
1 = sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

14
sizeof(float) <= sizeof(double)
, - . , ,
, .
const. , ,
, , const .
const float pi = 3.14;
const char plus = '+';
, , . , ,
, ; , ,
. .
, .
.
:
+ (, )
- (, )
* ()
/ ()
:
== ()
!= ( )
< ()
> ()
<= ( )
>= ( )
, : 7/2 3. %
: 7%2 1.
C++
, :
double d = 1;
int i = 1;
d = d + i;
i = d + i;

1.3.2
, :
*

*const
&

[]
*2
()
,
*2 . (, ), ,
"" . (. .)

:
char* p
//
char *const q //
char v[10] // 10

, v :

15

v[0] ... v[9]. #1.5, #1.9.


:
char c;
// ...
p = &c; // p c
& .

1.4
C++ ,
.
, ,
.. , ,
.

1.4.1
C++ , , ( )
. ,
~ ()
& ()
^ ( )
| ( )
<< ( )
>> ( )

, .
; & ,
& - . :
+ a+b , float,
, int. #1.8 ,
, , ,
.
C++ =, , .
, ; ,
x=sqrt(a=3*x). . a=b=c c b, a.
,
. , x[i+3]*=4 x[i+3]=x[i+3]*4,
, x[i+3] .

. .
C++ . *
*3 , .. *p , p.
. , char* p, *p ,
p. ++
--. , p v, p++ p
.
*3 . dereference - , . (. .)

1.4.2

16

- . ,
. :
a = b*3+c;
cout << "go go go";
lseek(fd,0,2);

1.4.3
:
;
. ,
, .

1.4.4
- , :
{ a=b+2; b++; }
. , ,
.
.

1.4.5 if

; , ,
i c :
#include
main()
{
const float fac = 2.54;
float x, in, cm;
char ch = 0;
cout << " : ";
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;
cout << in << " in = " << cm << " cm\n";
}
, if .

1.4.6 switch
switch .
:

17
switch (ch) {
case 'i':
in = x;
cm = x*fac;
break;
case 'c':
in = x/fac;
cm = x;
break;
default:
in = cm = 0;
break;
}
break switch. case
, , default.
default.

1.4.7 while
, p q
. 0.
while (p != 0) {
*q = *p;
q = q+1;
p = p+1;
}
*q = 0;

//

// 0

while . ,
, . ,
.
. ++
, :
while (*p)
*q = 0;

*q++ = *p++;

*p++ : " , p, p."


, p .
, :
while (*q++ = *p++) ;

, p, p , ,
q, q . , .
, . ,
. C++ ( C)
*4.
*4 expression-oriented (expression - ). (. .)

1.4.8 for
:
for (int i=0; i<10; i++) q[i]=p[i];

18
int i = 0;
while (i<10) {
q[i] = p[i];
i++;
}
, , , .
++ . for
, . :
for (i=0; i<10; i++) q[i]=p[i];
, i .

1.4.9
- , .
. ,
, ()
. :
for (int i = 1; i

1.5
- ,
, . ,
2:
extern float pow(float, int); //pow()
main()
{
for (int i=0; i<10; i++) cout << pow(2,i) << "\n";
}
- , , pow - , float int
float. ,
.
,
.
. , pow(12.3,"abcd") , "abcd"
, int. pow(2,i) 2 float, .
pow :
float pow(float x, int n)
{
if (n < 0) error(", pow()");
switch (n) {
case 0: return 1;
case 1: return x;
default:
return x*pow(x,n-1);
}
}
, ( )
( ). return.
, ,
, . ,
. , ,
:
overload pow;
int pow(int, int);

19
double pow(double, double);
//...
x=pow(2,10);
y=pow(2.0,10.0);

overload pow;
, pow .
, void:
void swap(int* p, int* q)
{
int t = *p;
*p = *q;
*q = t;
}

//

1.6
C++ ,
, , .
,
. :
extern double sqrt(double);
extern instream cin;
-
, ( ) , , ,
, . , sqrt
math.h,
4, :
#include
//...
x = sqrt(4);
, ,
. , inline-
(#1.12) (#1.3.1). ,
.
.
include , , ,
( /usr/include/CC); , -
, . :
#include "math1.h"
#include "/usr/bs/math2.h"
math1.h , math2.h /usr/bs.
,
, . header.h :
// header.h
extern char* prog_name;
extern void f();
main.c :
// main.c
#include "header.h"
char* prog_name = ", ";
main()

20
{
}

f();

f.c :
// f.c
#include
#include "header.h"
void f()
{
cout << prog_name << "\n";
}
:
$ CC main.c f.c -o silly
$ silly
,
$

1.7
, ostream.
, , streambuf. streambuf
, ostream. ,
, ostream ;
,
.
, ( C++ class, .. ),
, ,
. : (private)
, , ,
(public) , :
class ostream {
streambuf* buf;
int state;
public:
void put(char*);
void put(long);
void put(double);
}
public : put().
public ostream; buf state
put(), .
class , , ostream,
( , int):
ostream my_out;
, my_out (, #1.10),
:
my_out.put("Hello, world\n");
. my_out
put().
:

21
void ostream::put(char* p)
{
while (*p) buf.sputc(*p++);
}
sputc() - , streambuf. ostream , put()
ostream' put().
.
, ostream::put(): buf buf ,
.
this. X this
X* ( X) ,
. ostream::put() :
void ostream::put(char* p)
{
while (*p) this->buf.sputc(*p++);
}
-> , .

1.8
ostream <<,
. , .
@, @ - C++,
operator@,
. :
class ostream {
//...
ostream operator<<(char*);
};
ostream ostream::operator<<(char* p)
{
while (*p) buf.sputc(*p++);
return *this;
}
<< ostream, s< ");
, , :
&s1 == &my_out
, , ,
( ):
ostream& operator<<(ostream& s, complex z) {
return s << "(" << z.real << "," << z.imag << ")";
}
, , s,
, . , ,
, - ,
, .
,
. ,
.
class istream {
//...

22
int state;
public:
istream& operator>>(char&ap;);
istream& operator>>(char*);
istream& operator>>(int&);
istream& operator>>(long&);
//...
};
, long int ,
. , , int long
(#.6.6),
.

1.10
ostream .
, .
, , :
class ostream {
//...
ostream(streambuf*);
ostream(int size, char* s);
};
. streambuf ,
.
. , , :
ostream my_out(&some_stream_buffer);
char xx[256];
ostream xx_stream(256,xx);
my_out - ,
ostream::ostream(streambuf*), &some_stream_buffer,
streambuf.
, ,
. ,
, . , ,
, .

1.11
C++ ,
. (
)
. , , ,
, ..
: " ."
, . ,
C++, ,
, , ,
, .
class vector {
int* v;
int sz;
public:
vector(int);
~vector();

//
//

23

};

int size() { return sz; }


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

size , 0 ... size()1. set_size , elem


, operator[] .
, ,
,
new:
vector::vector(int s)
{
if (s<=0) error(" ");
sz = s;
v = new int[s];
}
vector , , :
vector v1(100);
vector v2(nelem*2-4);

int& vector::operator[](int i)
{
if(i<0 || sz<=i) error(" ");
return v[i];
}
|| () - . ,
, . ,
[] :
v1[x] = v2[y];
~vector - , , ,
, . C ~C.

vector::~vector()
{
delete v;
}
, delete, , ,
vector ,
.

1.12 Inline-
,
.
( ,
), C++ ,
.
.
inline-. ,
.
. , , size elem inline-,

24
vector s(100);
//...
i = s.size();
x = elem(i-1);
,
//...
i = 100;
x = s.v[i-1];
C++ , ,
. ,
, .
, , inline- , inline,
, , ,
size() elem().
inline-
. , inline- , ,
, . inline-
, .

1.13
,
.
class vec: public vector {
int low, high;
public:
vec(int,int);
int& elem(int);
int& operator[](int);
};
vec
:public vector
, , vec vector. , vec () vector
, . , vector
vec, vec , vector.
vec vector , ,
, ,
elem(int) operator[](int). elem() vec elem() vector:
int& vec::elem(int i)
{
return vector::elem(i-low);
}
:: ,
vec::elem() . :: .
vec::elem() inline, , , ,
, ,
v vector.
.
:
vec::vec(int lb, int hb) : (hb-lb+1)
{
if (hb-lb<0) hb = lb;
low = lb;
high = hb;
}

25
: (hb-lb+1) vector::vector().
vec::vec(). , ,
vector:
#include
void error(char* p)
{
cerr << p << "n\"; // cerr -
exit(1);
}
void vector::set_size(int) { /* */ }
int& vec::operator[](int i)
{
if (i

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(),
vector::vector() . .
, :
void Vec::operator=(Vec& a)
{
int s = size();
if (s!=a.size()) error(" =");
for (int i = 0; i
void error(char* p) {
cerr << p << "\n";
exit(1);
}
void vector::set_size(int) { /*...*/ }
int& vec::operator[](int i) { /*...*/ }
main()
{
Vec a(10);
Vec b(10);
for (int i=0; i

1.15 (friends)
operator+() .
, , .
. ,
" " vector::elem(),
i .
, ,
.
, friend. ,

26
class Vec; // Vec -
class vector {
friend Vec operator+(Vec, Vec);
//...
};

Vec operator+(Vec a, Vec b)
{
int s = a.size();
if (s != b.size()) error(" +");
Vec& sum = *new Vec(s);
int* sp = sum.v;
int* ap = a.v;
int* bp = b.v;
while (s--) *sp++ = *ap++ + *bp++;
return sum;
}
friend ,
. , vector matrix, (.
#.8.8).

1.16
" ," - , - " ,
matrix, ." , C++
. , . ,
.
(#4.7), . ,
vector - ,
. :
#include
declare(vector,int);
main()
{
vector(int) vv(10);
vv[2] = 3;
vv[10] = 4; // :
}
vector.h , declare(vector,int)
vector, , , implement(vector,int)
. implement(vector,int)
, , declare(vector,int)
, .
declare(vector,char);
//...
implement(vector,char);
" ".
#7.3.5.

1.17
-
:

27
class common {
//...
};
class vector {
common** v;
//...
public:
cvector(int);
common*& elem(int);
common*& operator[](int);
//...
};
, , , ""
. , ,
, , .. ,
, cvector
common . :
class apple : public common { /*...*/ }
class orange : public common { /*...*/ }
class apple_vector : public cvector {
public:
cvector fruitbowl(100);
//...
apple aa;
orange oo;
//...
fruitbowl[0] = &aa;
fruitbowl[1] = &oo;
}
, , , . ,
, common, apple orange?
, .
- , ,
.
. , , apple:
class apple_vector : public cvector {
public:
apple*& elem(int i)
{ return (apple*&) cvector::elem(i); }
//...
};
(), common*& (
common), cvector::elem, apple*&.
. ( ,
; . #7.3.5),
, .
, , vector(type),
( implement()) . ,
, , - .

1.18
, .
shape, - :
class shape {
point center;
color col;

28
//...
public:
void move(point to) { center=to; draw(); }
point where() { return center; }
virual void draw();
virtual void rotate(int);
//...
};
, (, move where, ,
"" ""), . virual, ,
. :
class circle: public shape {
int radius;
public:
void draw();
void rotatte(int i) {}
//...
};
, shape_vec - , :
for (int i = 0; i

29

2

.
- ..
(char, int, float ..)
(, , ..).
, , , .
, , , .
C++,
. .

C++. , ,
4, 5 6 .

2.1
() C++ ,
. , , ,
. , :
char ch;
int count = 1;
char* name = "Bjarne";
struct complex { float re, im; };
complex cvar;
extern complex sqrt(complex);
extern int error_number;
typedef complex point;
float real(complex* p) { return p->re; };
const double pi = 3.1415926535897932385;
struct user;
, .
; ,
. ch, count cvar ,
- . real . constant pi
3.1415926535897932385. complex . point complex,
point complex.
extern complex sqrt(complex);
extern int error_number;
struct user;
. , , ,
- . () sqrt ,
error_number int , -
user , . C++
, ,
, , :
int count;
int count;
// :
exnern int error_number;
exnern int error_number; // :
- ( extern . #4.2):
exnern int error_number;

30
exnern int error_number;
"" , :
struct complex { float re, im; };
typedef complex point;
float real(complex* p) { return p->re };
const double pi = 3.1415926535897932385;
, "" ;
:
int count = 1;
char* name = "Bjarne";
//...
count = 2;
name = "Marian";

char ch;
. , , .

2.1.1
; ,
. , (
), ,
; (
) ,
. ()
. ,
.
. :
int x;
f() {
int x;
x = 1;
{
int x;
x = 2;
}
x = 3;
}
int* p = &x;

// x
// x x
// x
// x
// x
// x
// x

. ,
, , , ,
, . .
i x .
:: .
:
int x;
f()
{
int x = 1;
::x = 2;
}

// x
// x

.
. ,
. :

31
int x;
f()
{
int x = x;
}

//

, , , x "used before set"


(" , "), . , , ::,
. :
int x;
f()
//
{
int y = x; // x
int x = 22;
y = x;
// x
}
y x, 11,
x, 22.
,
f(int x)
{
int x;
}

//

, x .

2.1.2 (Lvalue)
, ,
(, *p[a+10]=7). ,
" ".
C++: " ; lvalue ,
"(#.5). "lvalue" ",
".
; , (. #2.4).

2.1.3
, , ,
, ,
() "" .
, static, . *1:
*1 #include . ,
, . (. )
int a = 1;
void f()
{
int b = 1;
// f()
static int c = 1;
//
cout << " a = " << a++
<< " b = " << b++
<< " c = " << c++ << "\n";
}
main()
{
while (a < 4) f();
}

32
a = 1 b = 1 c = 1
a = 2 b = 1 c = 2
a = 3 b = 1 c = 3
(static) .
new delete ,
; . #3.2.4.

2.2
() .
. _ . C++
, (
, ), , , .
,
; (, $)
.
C++ (. #.2.3). :
hello
DEFINED
var0

this_is_a_most_unusially_long_name
foO
bAr
u_name
HorseSense
var1
CLASS
_class
___

, :
012
pay.due

a fool
foo~bar

$sys
.name

class
if

3var

, Count count - ,
, , . ,
, ,
.
, ,
var10 - , var, 10; elseif - , else,
if.

2.3
() C++ .
, ( ,
), . :
int error number;
float real(complex* p);
error_number int, ,
.. real complex .
. , int complex, .
. -
sizeof ( , ) new (
). :
main()
{
int* p = new int;
cout << "sizeof(int) = " << sizeof(int) "\n";
}
, :
float f;

33
char* p;
//...
long ll = long(p);
int i = int(f);

// p long
// f int

2.3.1
C++ ,
:
char
short int
int
long int
,
float
double
,
unsigned
unsigned
unsigned
unsigned

char
short int
int
long int

, , ..
int , ; , long long int,
unsigned unsigned int. , , int. :
const a = 1;
static x;
int.
char ; 8 . C++ char,
sizeof(char)==1. char .
unsigned char, , , ,
- char .
, ,
, ,
.
,
. , , .
. ,
:
1==sizeof(char)<=sizeof(short)<= sizeof(int)<=sizeof(long)
sizeof(float)<=sizeof(double)
, char 0...127 (
), short int 16 , int
, , long 24 . -
, .
#.2.6.
(unsigned) ,
. unsigned int ,
, . ,
, unsigned, -
. :
unsigned surprise = -1;
( ).

34

2.3.2
. ,
, , .
#.6.6.
, .
,
, . , ,

8- :
int i1 = 256+255;
char ch = i1
int i2 = ch;

// ch == 255
// i2 == ?

ch=i1 ( !), ch "-"


(.. 8 ); i2 511! i2?
DEC VAX, char , -1; AT&T 3B-20, char , 255. C++
(.. ) ,
, .

2.3.3
( , )
:
*
&
[]
()

. :
int* a;
float v[10];
char* p[20];
// 20
void f(int);
struct str { short length; char* p; };
#.8.3-4.
, . :
int v[10];
i = v[3];
int* p;
i = *p;

//
//
//
//

, * & ,
[] () , ,
, . , [] , *,
int* v[10];
int (*p)[10];

//
//

, .
, , ,
. .
, . , :
int x, y;

// int x; int y;

35
, (
). :
int* p, y;
int x, *p;
int v[10], *p;

// int* p; int y; int* y;


// int x; int* p;
// int v[10]; int* p;

, , .

2.3.4 void
void () .
, void .
, , ,
.
void f()
void* pv;

// f
//

void* .
, void* , void*
. , ,
, .
, .
, , . :
void* allocate(int size);
//
void deallocate(void*);
//
f() {
int* pi = (int*)allocate(10*sizeof(int));
char* pc = (char*)allocate(10);
//...
deallocate(pi);
deallocate(pc);
}

2.3.5
T T* T. , T*
T. ,
, :
int* pi;
char** cpp;
// char
int (*vp)[10];
// 10 int'
int (*fp)(char, char*); //
// (char, char*)
// int
- , , .
. - * ().
:
char c1 = 'a';
char* p = &c1;
char c2 = *p;

// p c1
// c2 = 'a'

, p,- c1, , c1, 'a', c2


*p 'a'.
. , , ,
( 0):

36
int strlen(char* p)
{
int i = 0;
while (*p++) i++;
return i;
}
, ,
:
int strlen(char* p)
{
char* q = p;
while (*q++) ;
return q-p-1;
}
; #4.6.7.

2.3.6
T T[size] " size T".
() 0 size-1. :
float v[3];
int a[2][5];
char* vpc;

// float: v[0], v[1], v[2]


// int
// 32

:
extern int strlen(char*);
char alpha[] = "abcdefghijklmnoprstuvwxyz";
main()
{
int sz = strlen(alpha);
for (int i=0; i.
strlen() alpha;
alpha ( #2.4.4). ASCII, :
'a' = 97 = 0141 = 0x61
'b' = 98 = 0142 = 0x62
'c' = 99 = 0143 = 0x63
...
, alpha ;
, . , .
. :
char v[9];
v = "";

//

, .
, .
. . :
int
int
char
char

v1[]
v2[]
v3[]
v4[]

=
=
=
=

{
{
{
{

1, 2, 3, 4 };
'a', 'b', 'c', 'd' };
1, 2, 3, 4 };
'a', 'b', 'c', 'd' };

, v4 - ( ) ; ,
. .
, ,

37
, , (,)
(. #3.2.2). , , :
int bad[5,2];

//

:
int v[5][2];
int bad = v[4,1];
int good = v[4][1];

//
//

char v[2][5];
, char[5].
, - .
char v[2][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";
}
}

";


v[0][0]=a v[0][1]=b v[0][2]=c v[0][3]=d v[0][4]=e
v[1][0]=0 v[1][1]=1 v[1][2]=2 v[1][3]=3 v[1][4]=4

2.3.7
C++ .
, :
char alpha[] = "abcdefghijklmnopqrstuvwxyz";
char* p = alpha;
char ch;
while (ch = *p++)
cout << chr(ch) << " = " << ch
<< " = 0" << oct(ch) << "\n";
p
char* p = &alpha[0];
,
; ,
extern int strlen(char*);
char v[] = "Annemarie";
char* p = v;
strlen(p);
strlen(v);
strlen . ,
; , v (
#4.6.3).
+, -, ++ -- ,
. p T* , , p

38
T; p+1 , p-1 . , p+1 sizeof(T) p. ,

main()
{
char cv[10];
int iv[10];
char* pc = cv;
int* pi = iv;
cout << "char* " << long(pc+1)-long(pc) << "\n";
cout << "int* " << long(ic+1)-long(ic) << "\n";
}

char* 1
int* 4
, .
long (#3.2.5).
long, "" int, ,
int ( , sizeof(int)

2.3.8
; struct
() . :
struct address {
char* name;
long number;
char* street;
char* town;
char* state[2];
int
zip;
}

//
//
//
//
//
//

//
"Jim Dandy"
61
"South Street"
"New Providence"
'N' 'J'
7974

, address ( ), , ,
- ( , address
, ). ;
C++, ,
.
address , ,
. (). :
address jd;
jd.name = "Jim Dandy";
jd.number = 61;
, ,
. :
address jd = {
"Jim Dandy",
61, "South Street",
"New Providence", {'N','J'}, 7974
};
(#5.2.4). , jd.state
"NJ". '\0', "NJ" , ,
jd.state.
->. :
void print_addr(address* p)
{

39
cout << p->name << "\n"
<< p->number << " " << p->street << "\n"
<< p->town << "\n"
<< chr(p->state[0]) << chr(p->state[1])
<< " " << p->zip << "\n";

,
. :
address current;
address set_current(address next)
{
address prev = current;
current = next;
return prev;
}
, (== !=) .
; . 6.
. ,
,
( : )
, .
"" . , ( ) sizeof (address) 24, 22, .
, , , ,
. :
struct link{
link* previous;
link* successor;
}
, ,
struct no_good {
no_good member;
};
( no_good). (
) , .
:
struct list;
//
struct link {
link* pre;
link* suc;
link* member_of;
};
struct list {
link* head;
}
list link .

2.3.9
.
:
struct s1 { int a; };
struct s2 { int a; };
,
s1 x;

s2 y = x;

40
// :

,
s1 x;
int i = x;

// :

, .
typedef , . :
typedef char* Pchar;
Pchar p1, p2;
char* p3 = p1;
.

2.3.10
.
, ; 6.
. x& x.
:
int i = 1;
int& r = i;
int x = r
r = 2;

// r i int
// x = 1
// i = 2;

( -, ). ,
.
, . ,
int ii = 0;
int& rr = ii;
rr++;
// ii 1
, rr++ ; ++ int, ii.
, ; ,
() . ,
rr, &rr.
,
. , lvalue (,
, . #.5). &T lvalue,
T. :
[1] -, , (#.6.6-8, #.8.5.6);
[2] ;
[3] , .

double& dr = 1;
:
double* drp;
// ,
double temp;
temp = double(1);
drp = &temp;
, , ,
.
int x = 1;
void incr(int& aa) { aa++; }
incr(x)
// x = 2

41
, , aa
incr x. , ,
, .
:
int x = 1;
int next(int p) { return p+1; }
x = next(x);
// x = 2
void inc(int* p) { (*p)++; }
inc(&x);
// x = 3
, ,
. ,
.
. :
struct pair {
char* name;
int val;
};
, .
find(), , pair
, . (
) :
const large = 1024;
static pair vec[large+1};
pair* find(char* p)
/*
"pair":
p, , "pair",
"pair"
*/
{
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];
}
value(), ,
( ):
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;
// 0
}
return res->val;
}
value() ( );
. , , :
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";

42
}
cin buf (. 8),
find(). , ,
, . ,
aa bb bb aa aa bb aa aa
:
aa: 5
bb: 3

(#6.7) .

2.3.11
()
, .
, ,
. ,
. register.
:
register int i;
register point cursor;
register char* p;
register , .
register (
).
, register, .

2.4
C++ : ,
. , (0)
, char[].
. - ,
. C++
: (1)
, const; (2)
; (3)
.

2.4.1
: , ,
.
, :
0

1234

976

12345678901234567890

int, , int, long.


, .
, x (0x), (
16), , , (
8). :

43
0

02

077

0123

- 0, 2, 63, 83. :
0x0

0x2

0x3f

0x53

a, b, c, d, e f, , 10, 11. 12, 13,


14 15, . ;
. ,
, int , 0xffff
-1; ,
65535.

2.4.2
double. ,
, ,
. :
1.23

.23

0.23

1.

1.0

1.2e10

1.23e-15

, . , 65.43 e-21
, ():
65.43

21

.
float, (#2.4.6):
const float pi = 3.14159265;

2.4.3
C++ , ,
, . , ; , 'a' '0'.

, (
, ,
). , ,
ASCII, '0' 48, EBCDIC, 240.

. , \
escape-:
'\b'
'\f'
'\n'
'\r'
'\t'
'\v'
'\\' ( )
'\''
'\"'
'\0' null, , 0

.
-, - ( \,

44

), -, - (\x,
). :
'\6'
'\60'
'\137'

'\x6'
'\x30'
'\x05f'

6
48
95

ASCII ack
ASCII '0'
ASCII '_'

,
(. ).
.

2.4.4
- , :
" "
, ;
'\0' 0. :
sizeof("asdf")==5;
" ", "asdf" char[5].
"" ( char[1]). , s strlen(s)==sizeof(s)-1, strlen()
0.

. escape- \.
, , '\n'. :
cout << " \007\n"
7 - ASKII bel ().
"" :
" ,
"
, ; ,
. :
cout << " \
ok"

ok
, escape ( ), ,
.
, ,
. , "asdf\000hjkl" , strcpy() strlen(),
"asdf".

.
, . :
char v1[] = "a\x0fah\0129";
char v2[] = "a\xfah\129";
char v3[] = "a\xfad\127";

// 'a' '\xfa' 'h' '\12' '9'


// 'a' '\xfa' 'h' '\12' '9'
// 'a' '\xfad' '\127'

, 9- .

2.4.5

45

(0) ,
. 0. .
( ) - .

2.4.6 Const
const ,
, . :
const int model = 145;
const int v[] = { 1, 2, 3, 4 };
, . -
const , :
model = 145;
model++;

//
//

, const , , ,
. , ,
const:
const char* peek(int i)
{
return private[i];
}
, - ,
( -).
, ,
(, , ). - ,
, . ,
( ) , .
,
, .
,
.
: .
"" const , , . :
const char* pc = "asdf";
pc[3] = 'a';
pc = "ghjk";

//
//
// ok

, , , const*.
:
char *const cp = "asdf";
cp[3] = 'a';
cp = "ghjk";

//
// ok
//

, const. :
const char *const cpc = "asdf";
cpc[3] = 'a';
cpc = "ghjk";

// const const
//
//

, , ,
. .
const , . :
char* strcpy(char* p, const char* q); // q
, .

46
, ,
. :
int a = 1;
const c = 2;
const* p1 = &c;
const* p2 = &a;
int* p3 = &c;
*p3 = 7;

//
//
//
//

ok
ok

, , int.

2.4.7
, ,
const. :
enum { ASM, AUTO, BREAK };
, , .
0 , :
const ASM = 0;
const AUTO = 1;
const BREAK = 2;
. :
enum keyword { ASM, AUTO, BREAK };
int, . keyword, int,
, , . :
keyword key;
switch (key) {
case ASM:
// -
break;
case BREAK:
// -
break;
}
, keyword .
. :
enum int16 {
sign=0100000,
most_significant=040000,
least_significant=1
};

//
//
//

, .

2.5
,
, .
, :
[1] ;
[2]
.
, -

47

. .
,
, , .
; ,
(#3.2.6) .

2.5.1
char , ,
/, , char
, C++ . , ,
struct.
, .
; , :
struct sreg {
unsigned enable : 1;
unsigned page : 3;
unsigned : 1;
//
unsigned mode : 2;
unsigned : 4:
//
unsigned access : 1;
unsigned length : 1;
unsigned non_resident : 1;
}
0 DEC PDP11/45 ( ,
). :
. ,
, . sreg
:
sreg* sr0 = (sreg*)0777572;
//...
if (sr->access) {
//
//
sr->access = 0;
}

. , , ,
, . , ,
! , char int
, . -
.

2.5.2
,
, , :
struct entry {
char* name;
char type;
char* string_value;
// type == 's'
int
int_value;
// type == 'i'
};
void print_entry(entry* p)
{
switch p->type {
case 's':
cout << p->string_value;

48

break;
case 'i':
cout << p->int_value;
break;
default:
cerr << " type\n";
break;
}

string_value int_value , ,
. , , union ();
, :
struct entry {
char* name;
char type;
union {
char* string_value;
int
int_value;
};
};

// type == 's'
// type == 'i'

, entry, , ,
entry string_value int_value . ,
, .
, ,
, .
, , -
. ,
(#5.4.6).
" " ( ,
, ,
). , "" VAX' int int*, :
struct fudge {
union {
int i;
int* p;
};
};
fudge a;
a.i = 4096;
int* p = a.p;

//

: int int*
, .
, (#3.2.5).
, . , ,
fudge, 0:
fudge.p = 0;
int i = fudge.i;

// i 0

, . , fudge
:
union fudge {
int i;
int* p;
};
() .
; . #5.4.6.

2.6

49
(*1) "Hello, world" (1.1.1).
(*1) #2.1 : ,
. , ,
.
(*1) : ; 10 ; 10 ;
; ; ;
; . .
(*1.5) , .
sizeof.
(*1.5) , 'a'...'z' '0'...'9' .
. , .
(*1) , 0 . : #2.5.2.
(*1.5) , double.
(*2) , , : char, short, int, long,
float, double, unsigned, char*, int* void*?
? , , int* ?
? , , int ?
(*1) C++ ?
C++ ? -
, ?
(*2) one :
const one = 1;
one 2. num :
const num[] = { 1, 2 };
num[1] 2.
(*1) , ( ).
int*. , int&.
(*1) str :
char str[] = "a short string";
"a short string"?
(*1.5) . . :
, ,
.
(*1) typedef : char; char;
; char; ; 7 ;
7 ; 8 7 .
*1 #include . ,
, . (. )

50

3

,
-

C++ ,
.
.

. ,
*1 .
*1 , indentation.
. (. .)

3.1

,
. . ,

r=2.5
area=pi*r*r
(pi ), :
2.5
19.635
2.5 - , 19.635 - .
: (parser'), ,
(). , ,
,
, ,
, . ,
, (200 ),

C++.

3.1.1
, :
program:
END
// END -
expr_list END
expr_list:
expression PRINT
// PRINT - '\n' ';'
expression PRINT expr_list
expression:
expression + term
expression - term
term
term:
term / primary
term * primary
primary

51
primary:
NUMBER
NAME
NAME = expression
- primary
( expression )

// C++
// C++ '_'

, .
, . , *, /, +, ( ) =. .
;
. , C++, ,
. , .
(, END, NUMBER, + -) get_token(),
expr(), term() prim().
() , ;
.
get_token(). get_token()
curr_tok; curr_tok token_value:
enum token_value {
NAME
NUMBER
END
PLUS='+'
MINUS='-'
MUL='*'
PRINT=';'
ASSIGN='='
LP='('
};
token_value curr_tok;

DIV='/'
RP=')'

, get_token(), curr_tok
, .
() ,
, . ""
. expr() ; ,
:
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;
}
}

//

// ````
// '+'

// '-'

. ,
, . , 23+4 (2-3)+4, . for(;;) -
; "" *2. for;
- while(1). switch , + -,
return default.
*2 : "for" - "forever" (). (. .)
+= -= .
left=left+term() left=left-term(). left+=term() left- =term() ,
. @ x@=y x=x@y
, x .
+ - * / % & | ^ << >>

52
:
+= -= *= /= %= &= |= ^= <<= >>=
, a+ =1 - + =.
(% ; &,| ^ , ;
<< >> ). term() get_token()
expr().
, 4.
,
. expr(), term(), prim(),
expr(). - ;
double expr();

//

prim() .
term() :
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(" 0");
left /= d;
break;
default:
return left;
}
}
, , , , ,
. error(char*)
. d , , .
.
/ .
; ,
, ,
*3. , = , ==
.
* 3 . (. )
prim, primary, , ,
- , ,
:
double prim()
// primary ()
{
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;
}

53
return look(name-string)->value;
case MINUS:
//
get_token();
return -prim();
case LP:
get_token();
double e = expr();
if (curr_tok != RP) return error(" )");
get_token();
return e;
case END:
return 1;
default:
return error(" primary");
}

NUMBER ( , ), .
get_token() number_value.
, ,
. . :
, ( token_value), ( ) .
curr_tok,
NUMBER number_value. ,
.
, NUMBER number_value, name_string
NAME. , -
, , , ,
. . #3.1.3;
, :
srtuct name {
char* string;
char* next;
double value;
}
next , :
name* look(char*);
name* insert(char*);
name, - ; look()
, . ,
, .

3.1.2
- . ,
, ,
.
( ) .
,
.
. get_token().
,
; .
,
;
get_token() .
, '\n'
, . ,

54

'\n' . ,
(, ..):
char ch
do {
// '\n'
if(!cin.get(ch)) return curr_tok = END;
} while (ch!='\n' && isspace(ch));
cin.get(ch) ch. if(!cin.get(ch))
, cin ; END,
. ! (), get()
.
(inline) isspace() , (#8.4.1);
isspace(c) , c , .
, isspace() ,
; isalpha(), isdigit() isalnum(),
get_token().
, , ,
. ,
. '\n' ';' :
switch (ch) {
case ';':
case '\n':
cin >> WS;
//
return curr_tok=PRINT;
, get_token(). WS , ; .
get_token(). ,
case () ,
. PRINT curr_tok.
:
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;
case , , ,
, .
>> double,
: ( ) cin,
number_value. , NAME, ,
:
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;
}
name_string , . isalpha() isalnum() ; isalnum(c)
, c , .
, , :
token_value get_token()
{
char ch;
do {
// '\n'
if(!cin.get(ch)) return curr_tok = END;

55
} 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:
// NAME, NAME=
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(" ");
return curr_tok=PRINT;
}

token_value ( ) *4,
.
* 4 . (. .)

3.1.3

name* look(char* p, int ins =0);
, . =0
, , look() .
, look("sqrt2") look("sqrt2",0), , .
, :
inline name* insert(char* s) { return look(s,1);}
, :
srtuct name {
char* string;
char* next;
double value;
}
next . -
name:
const TBLSZ = 23;
name* table[TBLSZ];

56
, table
.
look() (
- ):
int ii = 0;
//
char* pp = p;
while (*pp) ii = ii<<1 ^ *pp++;
if (ii < 0) ii = -ii;
ii %= TBLSZ;
, "" ii (""
). x^y ,
x y . , ii ,
. :
ii <<= 1;
ii ^= *pp++;
, ^ , +. - .

if (ii < 0) ii = -ii;


ii %= TBLSZ;
, ii 0...TBLSZ-1; % - (
).
:
extern int strlen(const char*);
extern int strcmp(const char*, const char*);
extern int strcpy(const 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* 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;
}
- ii next. name
strcmp(). , name,
name.
name new
(. #3.2.6), , .
, , , .
. strlen()
, , new - , strcpy() -
.

3.1.4

57

, .
,
:
int no_of_errors;
double error(char* s) {
cerr << "error: " << s << "\n";
no_of_errors++;
return 1;
}
, ,
, ,
. . get_token()
, error() , .
, .
, ,
. exit(),
(#8.3.2), .
- abort(),
- ( ); , ,
.

3.1.5
,
, . main() :
int main()
{
// :
insert("pi")->value = 3.1415926535897932385;
insert("e")->value = 2.7182818284590452354;
while (cin) {
get_token();
if (curr_tok == END) break;
if (curr_tok == PRINT) continue;
cout << expr() << "\n";
}
return no_of_errors;
}
, main()
, . ,
.
- . :
cout << expr() << "\n";
cin , -
, END , get_token() .
break switch ( ,
for, while do). PRINT ( , '\n' ';') expr()
. continue ,

while (cin) {
// ...
if (curr_tok == PRINT) continue;
cout << expr() << "\n";
}

58
while (cin) {
// ...
if (curr_tok == PRINT) goto end_of_loop;
cout << expr() << "\n";
end_of_loop
}
#.9.

3.1.6
, , ,
,
.
,
.
, main(). , main()
: , argc,
, argv. - , argv
char*[argc]. (, )
argv[0], argc . ,
dc 150/1.1934
:
argc
argv[0]
argv[1]

"dc"
"150/1.1934"

; ,
. ,
, (#8.5). , cin :
int main(int argc, char* argv[])
{
switch(argc) {
case 1:
//
break;
case 2:
//
cin = *new istream(strlen(argv[1]),argv[1]);
break;
default:
error(" ");
return 1;
}
//
}
, main()
switch. main() ,
, , ,
:
dc "rate=1.1934;150/rate;19.75/rate;217/rate"
, ; UNIX.

3.2
C++ #.7; , ,
. .

59

.
_ - , - , - ,
, - , , , lvalue - , .
( *, () ..) ,
.
,
. , a=b=c a=(b=c), a+b+c (a+b)+c, *p++
*(p++), (*p)++.
( 1)
::


::

->
[]
()
()
sizeof
sizeof

::

++
++
--~
!
+
&
*
new
delete
delete[]
()

->
[ ]
(_)
(_)
sizeof
sizeof ( )

()
()

( )

*
/
%

()

+
-

()
()

_ ::

lvalue++
++lvalue
lvalue---lvalue
~
!
-
+
& lvalue
*
new
delete
delete[ ]
( )
*
/
%
+
-

. ,
, . : a+b*c a+(b*c), * ,
+, a+b-c (a+b)-c, + - ( + ).

( 2)
<<
>>

lvalue <<
lvalue >>

60
<
<=
>
>=

==
!=

&

<
<=
>
>=
==
!=

&

|
&&
||

&&

?:

||

if

=
*=
/=
%=
+=
-=
<<=
>>=
&=
|=
^=
,

? :

()

lvalue =
lvalue =
lvalue /=
lvalue %=
lvalue +=
lvalue -=
lvalue <<=
lvalue >>=
lvalue &=
lvalue |=
lvalue ^=
,

3.2.1
C++ ;
: ,
( ),
, . ,
,
, " " ( ,
). ,
if (i<=0 || max

3.2.2
.
int i = 1;
v[i] = i++;
v[1]=1, v[2]=1.
. ,

61
, .

,

&&

||

, , . , b=(a=2,a=1) b 3.
#3.3.1 && ||. , , ()
, .
f1(v[i],i++);
f2( (v[i],i++) )

//
//

f1 , v[i] i++, - .
- - , . f2
, , i++.
. , a*(b/c) (a*b)/c,
* / . , ,
, , (t=b/c,a*t).

3.2.3 *5
*5 "" "", ,
C, C. (. .)

++
. ++lvalue
lvalue+=1, lvalue=lvalue+1 , lvalue
. , () ,
, (). ,
--. ++ -- , .
++x ( ) x. , y=++x
y=(x+=1). x++, , x. , y=x++
y=(t=x,x+=1,t), t - , x.
.
, :
inline void cpy(char* p, const char* q)
{
while (*p++ = *q++) ;
}
, , ,
, ; p++ , p
. p T* :
long(p+1) == long(p)+sizeof(T);

3.2.4

&

>>

<<

, char, short, int, long unsigned , .


- (
). ,
. & , | , ^
. . ,
( ) :
enum state_value { _good=0, _eof=1, _fail=2, _bad=4};

62
// , , ,
_good . , , ,
. :
cout.state = _good;
, , :
if (cout.state&(_bad|_fail)) // good
, & , |.
, , :
cin.state |= _eof;
|= , ( , state==_bad),
cin.state = _eof;
. :
state_value diff = cin.state^cout.state;
stream_state ( ) ,
. , , ,
, , , .
, (#2.5.1)
. , ,
, , 16 32- int :
unsigned short middle(int a) { return (a>>8)&0xffff; }
:
&&

||

0 1, if, while
for (#3.3.1). , !0 ( ) 1, ~0 ( ) , -1.

3.2.5
.
. :
float r = float(1);
1 1.0.
lvalue, ( ).
: C (double)a
double(a). ,
. ,

char* p = (char*)0777;
:
typedef char* Pchar;
char* p = Pchar(0777);
, .

63
Pname n2 = Pbase(n1->tp)->b_name;
Pname n3 = ((Pbase)n2->tp)->b_name;

//
//

-> , ,
((Pbase)(n2->tp))->b_name
,
. :
any_type* p = (any_type*)&some_object;
p some_object any_type.
, . ,
, , , .
, ,
(, , , ,
struct ; . #2.5.2 ). ,
,
, . :
int i = 1;
char* pc = "asdf";
int* pi = &i;
i = (int)pc;
pc = (char*)i;
// : pc
//
// sizeof(int)

3.2.6
, . #2.1.3).

.
, .
, , .
, ,
, . new,
delete. , new, ,
.
, ,
. ,
.
, .
:
struct enode {
token_value oper;
enode* left;
enode* right;
};
enode* expr()
{
enode* left = term();
for(;;)
switch(curr_tok) {
case PLUS:
case MINUS:
get_token();
enode* n = new enode;
n->oper = curr_tok;
n->left = left;

64

n->right = term();
left = n;
break;
default:
return left;
}

:
void generate(enode* n)
{
switch (n->oper) {
case PLUS:
//
delete n;
}
}
, new, , delete, ,
, new. " ", ,
, new, . delete
, new, . delete
.
new . :
char* save_string(char* p)
{
char* s = new char[strlen(p)+1];
strcpy(s,p);
return s;
}
, , new, delete
. :
int main(int argc, char* argv[])
{
if (argc < 2) exit(1);
char* p = save_string(argv[1]);
delete p;
}
, , new, ,
(, ).
delete. :
int main(int argc, char* argv[])
{
if (argc < 2) exit(1);
int size = strlen(argv[1])+1;
char* p = save_string(argv[1]);
delete[size] p;
}
,
(#5.5.5).
(#.7.2.3):
void operator new(long);
void operator delete(void*);
new .
, new ? ,
.
char* p = new char[100000000];

65
, - . new , ,
_new_handler ( #4.6.9).
set_new_handler(). :
#include
void out_of_store()
{
cerr << " new : \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 << ", p = " << long(p) << "\n";
}
, "",
new :
_new_handler - , . ,
new delete, , , operator new() operator delete(),
, new.
, , , , delete
. , , - .
new 0,
_new_handler.
include
main()
{
char* p = new char[100000000];
cout << ", p = " << long(p) << "\n";
}

, p = 0
! , , _new_handler,
new ( ,
, ; . #5.5.6).

3.3
C++ #.9, , ,
. .

:

{_ opt}
opt
if ( )
if ( ) else
switch ( )
while ( )
do while ()
for ( opt ; opt )

66
case _ :
default :
break ;
continue ;
return opt ;
goto ;
:
_:

_
, , .
.

3.3.1
if, switch:
if ( )
if ( ) else
switch ( )
C++ .
==

!=

<

<=

>

>=

1, , 0. ,
1, 0.
if ( ) , ,
( ). ,
. , a ,
if (a) // ...

if (a != 0) // ...

&&

||

. && || ,
. :
if (p && 1count) // ...
, p , , 1count.
if if. :
if (a <= d)
max = b;
else
max = a;
:
max = (a<=b) ? b : a;
, , , .
switch - if. :
switch (val) {
case 1:
f();
break;

67
case 2;
g();
break;
default:
h();
break;
}
:
if (val == 1)
f();
else if (val == 2)
g();
else
h();
, (switch) ,
( ). switch
.
, switch - , ,
case. :
switch (val) {
//
case 1:
cout << "case 1\n";
case 2;
cout << "case 2\n";
default:
cout << "default: case \n";
}
val==1
case 1
case 2
default: case
. - break,
goto. :
switch (val) {
//
case 0:
cout << "case 0\n";
case1:
case 1:
cout << "case 1\n";
return;
case 2;
cout << "case 2\n";
goto case1;
default:
cout << "default: case \n";
return;
}
val==2
case 2
case 1
, case goto:
goto case 1;

//

3.3.2 Goto

68

C++ goto.
goto ;
:
, ,
, C++ , . ,
goto ,
. goto ,
, , - , .
(break
). :
for (int i = 0; i

3.4

.
.
( ,
). .

, ,
,
[1] ;
[2] ;
[3] .
,
. , .
- , ,
. :
// "v" .
// "v" "f()".
// init()
// .
// "cleanup()"
.
// "wierd()".
// "f()" .
C++ .
, , , (#4.2 )
, (. #5.5.2).
- , . :
a = b+c;
count++;

// a b+c
//

, , ,
, .
:
[1] , ,
, , ..;
[2] , ,
( ) , , -
;
[3] , / ;
[4] .
:

69
// tbl.c:
/*

. Ralston: "A first course ..." . 411.
*/
// swap() AT&T sB20.
/**************************************
Copyright (c) 1984 AT&T, Inc.
All rights reserved
****************************************/
- .
, .
, //,
/* */, .

3.5
(*1) for while:
for (i=0; im
*p.m
*a[i]
(*2) : strlen(), , strcpy(),
, strcmp(), . ,
, ,
.
(*1) , :
a := b+1;
if (a = 3) // ...
if (a&077 == 0) // ...
, , .
(*2) cat(), ,
. new, .
rev(), . ,
rev(p) p .
(*2) ?
void send(register* to, register* from, register count)
// .
{
register n=(count+7)/8;
switch (count%8) {
case 0: do {
*to++ = *from++;
case 7: do {
*to++ = *from++;
case 6: do {
*to++ = *from++;
case 5: do {
*to++ = *from++;
case 4: do {
*to++ = *from++;
case 3: do {
*to++ = *from++;
case 2: do {
*to++ = *from++;
case 1: do {
*to++ = *from++;
while (--n>0);
}
}
- ?
(*2) atoi(), , ,
int. , atoi("123") - 123. atoi() ,
C++. atoi() ,

70
. itoa(),
.
(*2) get_token() (#3.1.2), , ,
.
(*2) #3.1 , sqrt(), log() sin(). :
.
.
(*3) . :
, , .
, . ,
, . ,
, .
(*1.5) , name_string
number_value symbol:
struct symbol {
token_value tok;
union {
double number_value;
char* name_string;
};
};
7.

(*2.5) , C++ . , cin,


// /* */ cout.
( , ). .
// /* */ , .

8.

(*2) - ,
, .

71

4

, . - .


( ). ,
,
( ),
, .
. , ,
, , , . .

4.1
,
- . ,
.

, .
, ,
( ), .
, ,
.
. .
,
, "" ,
expr(), term() prim().
, ( ,
, ),
. , -.
; " "
, ,
200 ,
.
, ,
, , ,
. , *1.
*1 . (. .)

- , .
() . UNIX' ld.
, ,
.
,
().
,
. , , .
C++ , *2.
* 2C , . C,
, , , ,
. (. )

72

4.2
, , ,
, , ,
, . ,
, , . , , :
// file1.c:
int a = 1;
int f() { /* - */ }
// file2.c:
extern int a;
int f();
void g() { a = f(); }
a f(), g() file2.c,- , file1.c. extern ()
, a file2.c () , . a
, extern ,
. .
, . :
// file1.c:
int a = 1;
int b = 1;
extern int c;
// file2.c:
int a;
extern double b;
extern int c;
: a (int a; , int a=0;), b
, c , . ( )
, . , ,
.
C++ ( C ):
// file1.c:
int a;
int f() { return a; }
// file2.c:
int a;
int g() { return f(); }
-, file2.c C++, f() , . -,
( file2.c ) , a .
, static. :
// file1.c:
static int a = 6;
static int f() { /* ... */ }
// file2.c:
static int a = 7;
static int f() { /* ... */ }
a f static, .
a f().
static, (
). static , ,
, .
:

73
// file1.c:
const int a = 6;
inline int f() { /* ... */ }
struct s { int a,b; }
// file1.c:
const int a = 7;
inline int f() { /* ... */ }
struct s { int a,b; }
" " , inline-
, , file1.c file2.c C++
. , ? ,
: , .. , , ,
. ( ).

4.3
.
,
- 1950-,
*3. , ,
, , ,
. ,
,
, , /
.
*3 , ,
, ? (. )

#include -
() .
#include "to_be_included"
, #include, "to_be_included".
C++, .
, C , CC
, , , .
,
. ,

CC -E file.c
file.c , CC .
< >.
:
#include
//
#define "myheader.h"
//
<> ,
( , /usr/include/CC, usr/include). ,
include :
#include < stream.h >

//

, , - ,
, ,
. ,
, ,

74
, .
, ,
, , #include.
:

struct point { int x, y; }

extern int strlen(const char*);
inline- inline char get() { return *p++; }

extern int a;

const float pi = 3.141593

enum bool { false, true };


include
#include

#define Case break;case

/* */


char get() { return *p++; }

int a;
const tbl[] = { /* ... */ }
UNIX , () .h. ,
, .c. , , ".h
" ".c ". #4.7 . , C++ ,
C, C++ , const inline
.
, ,
, . , ,
(
).
. ,
.

4.3.1

,
, , .
.c : lex.c, syn.c, table.c main.c,
dc.h, ,
.c :
// dc.h:
enum token_value {
NAME,
NUMBER,
END,
PLUS='+',
MINUS='-',
MUL='*',
PRINT=';',
ASSIGN='=',
LP='(',
};
extern int no_of_errors;
extern double error(char* s);
extern token_value get_token();
extern token_value curr_tok;
extern double number_value;
extern char name_string[256];
extern double expr();
extern double term();
extern double prim();
struct name {
char* string;
name* next;
double value;
};
extern name* look(char* p, int ins = 0);

DIV='/',
RP=')'

75
inline name* insert(char* s) { return look(s,1); }
, lex.c :
// lex.c:
#include "dc.h"
#include
token_value curr_tok;
double number_value;
char name_string[256];
token_value get_token() { /* ... */ }
, ,
, , - , . ,
lex.c :
extern token_value get_token();
// ...
token_value get_token() { /* ... */ }
, , .
, get_token() token_value,
int, lex.c - .
syn.c :
// syn.c:
#include "dc.h"
double prim() { /* ... */ }
double term() { /* ... */ }
double expr() { /* ... */ }
table.c :
// table.c:
#include "dc.h"
extern char* strcmp(const char*, const char*);
extern char* strcpy(char*, const char*);
extern int strlen(const char*);
const TBLSZ = 23;
name* table[TBLSZ];
name* look(char* p; int ins) { /* ... */ }
, table.c ,
. , .c
extern. " ",
, , . ,
, strlen() main() ().
,
. , , extern dc.h,
. "" , C
, , , , ,
, , . !
main.c, , :
// main.c: ,
#include "dc.h"
int no_of_errors;
double error(char* s) { /* ... */ }
extern int strlen(const char*);
main(int argc, char* argv[]) { /* ... */ }
, .
- - (.
5-8).
. "" .
. ,

76
.
.

4.3.2
,
. ,
, ,
. . - ,
,
. .c .h , .c
( , ) .h , ,
.h ( , ).
, , error()
, . ,
error() main():
// error.h:
extern int no_errors;
extern double error(char* s);
// error.c
#include
#include "error.h"
int no_of_errors;
double error(char* s) { /* ... */ }
.h .c
, .h , .c .
.
:
// table.h:
struct name {
char* string;
name* next;
double value;
};
extern name* look(char* p, int ins = 0);
inline name* insert(char* s) { return look(s,1); }
// table.c:
#include "error.h"
#include
#include "table.h"
const TBLSZ = 23;
name* table[TBLSZ];
name* look(char* p; int ins) { /* ... */ }
, .
.
// lex.h:
enum token_value {
NAME,
NUMBER,
END,
PLUS='+',
MINUS='-',
MUL='*',
DIV='/',
PRINT=';',
ASSIGN='=',
LP='(',
RP=')'
};
extern token_value curr_tok;
extern double number_value;
extern char name_string[256];
extern token_value get_token();
.
get_token()
number_value name_string.

77
// lex.c:
#include
#include
#include "error.h"
#include "lex.h"
token_value curr_tok;
double number_value;
char name_string[256];
token_value get_token() { /* ... */ }
:
// syn.c:
extern double expr();
extern double term();
extern double prim();
// syn.c:
#include "error.h"
#include "lex.h"
#include "syn.h"
double prim() { /* ... */
double term() { /* ... */
double expr() { /* ... */

}
}
}

, , :
// main.c:
#include
#include "error.h"
#include "lex.h"
#include "syn.h"
#include "table.h"
#include
main(int argc, char* argv[]) { /* ... */ }
, .
, , C++. ,
, ,
. , 10 50
, 500 , ,
.
:
. ,
(
..), .

4.3.3
,
. ,
, , .c extern.
, :
// file1.c:
// "extern"
int a = 7;
const c = 8;
void f(long) { /* ... */ }
// file2.c:
// "extern" .c
extern int a;
extern const c;
extern f(int);
int g() { return f(a+c); }

78
extern file2.c file1.c,
. ,
, , .
, ,
, static, ,
. :
// table.c:
#include "error.h"
#include
#include "table.h"
const TBLSZ = 23;
static name* table[TBLSZ];
name* look(char* p; int ins) { /* ... */ }
, table look(). ""
TBLSZ .

4.4
.c .h . .h
, ; .c .
. ,
, . ,
- , .
. , .c , .h
. ,
, .c . ,
, .c ,
. (.o ).
, ,
. ,
.h , ,
(), .h ,
().
, ,
. , table , ,
.
5.
,
() .
. , ,
, - , / ,
; . #5.5.2.

4.5
" " " - " (
, ), C++ ? ,
, ; ,
8- UNIX.
.
.o ,
.c . .h
, .o .
, ( )

79

.
:
extern
extern
extern
extern
extern

double
double
double
double
double

sqrt(double);
sin(double);
cos(double);
exp(double);
log(double);

//

, , sqrt.c, sin.c, cos.c, exp.c log.c.


math.h , , :
$ CC -c sqrt.c sin.c cos.c exp.c log.c
$ ar cr math.a sqrt.o sin.o cos.o exp.o log.o
$ ranlib math.a
. ar,
math.a. , , .
runlib, , , . , ,
ar. , , :
$ CC myprog.c math.a
, math.a
.o ? :
$ CC myprog.c sqrt.o sin.o cos.o exp.o log.o
.o , , .
, myprog.c sqrt() cos(), ,

$ CC myprog.c sqrt.o cos.o
, cos.c sin.c.
, CC .a ( , math.a) ,
, .a , .o .
,
( , ,
), , , ,
.

4.6
- C++ - , .
, .
, .

4.6.1
, (
) , . :
extern
extern
extern
extern

double sqrt(double);
elem* next_elem();
char* strcpy(char* to, const char* from);
void exit(int);

. ,
. , ,
double sr2 = sqrt(2);

80
sqrt() 2.0.
.
. ,
.

4.6.2
, , - ( ).
- , . :
extern void swap(int*, int*);
void swap(int*, int*)
{
int t = *p;
*p =*q;
*q = t;
}

//
//

, inline (#1.12),
, register (#2.3.11).
, - .

4.6.3
, ,

. .
, ,
.
(#4.6.5),
(#4.6.8) (#4.6.6).
void f(int val, int& ref)
{
val++;
ref++;
}
f(), val++ , ref++
. :
int i = 1;
int j = 1;
f(i,j);
j, i. , i, , , j, .
#2.3.10, , ,
, ( . #6.5 #8.4).
, .
const, , ,
:
void f(const large& arg)
{
// "arg"
}
, const , ,
, . :
extern int strlen(const char*);
//
extern char* strcpy(char* to, const char* from);

81
extern int strcmp(const char*, const char*);
.
, . const
, , (#6.6).

4.6.4
, void, ( ) .
return. :
int fac(int n) {return (n>1) ? n*fac(n-1) : 1; }
return:
int fac(int n)
{
if (n > 1)
return n*fac(n-1);
else
return 1;
}
,
. .

. :
double f()
{
// ...
return 1;
}

// double(1)

, , .
,
. :
int* f() {
int local = 1;
// ...
return &local;
}

//

, :
int& f() {
int local = 1;
// ...
return local;
}

//

, . :
int& f() { return 1;}

//

4.6.5
,
. :
int strlen(const char*);
void f()
{

82

};

char v[] = "a vector"


strlen(v);
strlen("Nicholas");

, T[] T*. ,
, . ,
, ( ) .
. ,
. , .
, , ,
, (. #1.11). :
void compute1(int* vec_ptr, int vec_size);
struct vec {
int* ptr;
int size;
};
void compute2(vec v);

//
//

, ,
. :
char* day[] = {
"mon", "tue", "wed", "thu", "fri", "sat", "sun"
};
, , .
, :
void print_m34(int m[3][4])
{
for (int i = 0; i<3; i++) {
for (int j = 0; j<4; j++)
cout << " " << m[i][j];
cout << "\n";
}
}
, , , .
(#2.3.6).
:
void print_mi4(int m[][4], int dim1)
{
for (int i = 0; i

4.6.6
,
. , hex(),
.
.
, ,
, . ,
, .
" ,
". hex(i,0),
:
extern char* hex(long, int =0);
. ,
, . :

83
cout << "**" << hex(31) << hex(32,3) << "**";

cout << "**" << hex(31,0) << hex(32,3) << "**";
:
** 1f 20**
.
,
int f(int, int =0, char* =0);
int g(int =0, int =0, char*);
int f(int =0, int, char* =0);

// ok
//
//

, * = (*= ):
int nasty(char*=0);

//

4.6.7
, - ,
,
.
(overloading).
C++: , +,
, .
, , , .
,
. :
overload print;
void print(int);
void print(char*);
, , , .
, - , , .
, - .
sqrt, print open. ,
+, * << (#6.2) (#5.2.4 #6.3.1),
. f(), , f
.
f. , ,
:
[1] , , ;
[2]
;
[3] , (#6.3),
, .
:
overload print(double), print(int);
void f();
{
print(1);
print(1.0);
}
, f 1 1.0 .
, char short int. , float double.
C++ (#.6.6)

84
. , , . int
long, int double, long, double : , void*,
(#7.2.4).
, :
overload print(double), print(long);
void f(int a);
{
print(a);
}
a double, long.
( print(long(a)) print(double(a))).
,
, (). :
overload pow;
int pow(int, int);
double pow(double, double);
complex pow(double, complex);
complex pow(complex, int);
complex pow(complex, double);
complex pow(complex, complex);

//
//

unsigned const.

4.6.8
,
.
(...), " , - ". :
int printf(char* ...);
, printf , char*, ,
. :
printf("Hello, world\n");
printf(" %s %s\n", first_name, second_name);
printf("%d + %d = %d\n",2,3,5);
,
. printf() ,
, printf() . %s
" char*", %d " int". , ,
, . :
printf(" %s %s\n",2);
- .
, , ,
. char short int, float
double. , .
, wild(...), ,
,
C. ,
. , ,
,
. ,
. C ,
, :
extern int fprintf(FILE*, char* ...);
extern int execl(char* ...);
extern int abort(...);

//
//
//

85
, ,
, . ,
:
void error(int ...);
main(int argc, char* argv[])
{
switch(argc) {
case 1:
error(0,argv[0],0);
break;
case 2:
error(0,argv[0],argv[1],0);
default:
error(1,argv[0],"",dec(argc-1),"",0);
}
}
:
#include
void error(int n ...)
/*
"n" char*,
*/
{
va_list ap;
va_start(ap,n);
// arg
for (;;) {
char* p = va_arg(ap,char*);
if(p == 0) break;
cerr << p << " ";
}
va_end(ap);
// arg
cerr << "\n";
if (n) exit(n);
}
va_list va_start(). va_start va_list'
. va_arg
. ; va_arg() ,
, . ,
va_start(), va_end(). , va_start() ,
; va_end() .

4.6.9
: . ,
, .
:
void error(char* p) { /* ... */ }
void (*efct)(char*);
void f()
{
efct = &error;
(*efct)("error");
}

//
// efct error
// error efct

, , efct, , *efct.
() , *,
*efct("error"). *efct("error"), .
(. #7.3.4).

86
, , .
. :
void (*pf)(char*);
// void(char*)
void f1(char*);
// void(char*)
int f2(char*);
// int(char*)
void f3(int*);
// void(int*)
void f()
{
pf = &f1;
// ok
pf = &f2;
// :
pf = &f3;
// :
(*pf)("asdf");
// ok
(*pf)(1);
// :
int i = (*pf)("qwer"); // : void int'
}

.
, - ,
--. :
typedef int (*SIG_TYP)();
//
typedef void (*SIG_ARG_TYP);
SIG_TYP signal(int,SIG_ARG_TYP);
. , *4
.
, :
*4 - . ,
. (. )
typedef void (*PF)();
PF edit_ops[] = { //
cut, paste, snarf, search
};
PF file_ops[] = { //
open, reshape, close, write
};
, , ,
(button) :
PF* button2 = edit_ops;
PF* button3 = file_ops;
. , -
, , .
. ()
. , 3 2,
:
(button2[3])();
-
. , .
.
, ,
:
typedef int (*CFT)(char*,char*);
int sort(char* base, unsigned n, int sz, CFT cmp)
/*
"n" "base"

, "cmp".

*/
{

87
"sz".
:

for (int i=0; iname, Puser(q)->name);


}
int cmp2(char*p, char* q)
// dept
{
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);
//
}
inline-, , , (#.8.9).

4.7
*5 #.11. C , C++
. : ,
. , ,
. , , ,
C .
*5 . (. .)

:
#define name rest of line
name , rest of line. :
named = name
:
named = rest of line
. :
#define mac(a,b) argument1: a argument2: b
mac . mac() a b.
:
expanded = mac(foo bar, yuk yuk)

expanded = argument1: foo bar argument2: yuk yuk
C++ , C++ . ,
, . .
:
#define Case break;case

88
#define nl <<"\n"
#define forever for(;;)
#define MIN(a,b) (((a)<(b))?(a):(b))
:
#define PI 3.141593
#define BEGIN {
#define END }
:
#define SQUARE(a) a*a
#define INCR_xx (xx)++
#define DISP = 4
, , :
int xx = 0;
void f() {
int xx = 0;
xx = SQUARE(xx+2);
INCR_xx;
if (a-DISP==b) {
// ...
}
}

//
//
//
//
//


xx = xx+2*xx+2
xx
a-= 4==b

,
:: (#2.1.1) ,
(. MIN ).
:
#define m1(a) something(a)
#define m2(a) something(a)

//
/* */

,
int a = m1(1)+2;
int b = m2(1)+2;

int a = something(1)
int b = something(1)

// +2;
/* */+2;

. ,
. , C - . , , , , , (
. #7.3.5).

4.8
(*1) : ,
; ; ,
; , . ,
. :
typedef.
(*1) ? ?
typedef int (rifii&) (int, int);

89
(*1.5) "Hello, world",
"Hello, ". ,
hello .
(*1.5) , ,
, cout.
, cat ().
(*2) C C++. ,
. , , #define
enum const inline. .c extern
C++. malloc() free() new delete. .
(*2) sort() (#4.6.7) .
(*2) struct tnode .#8.5.
tnode. tnode.
tnode . tnode , ()
, new .
tnode.
(*2) "", . .h push(), pop()
(). .c , .
(*2) , . ,
/usr/include /usr/include/CC ( , ).
, .
(*2) .
(*2) , cin cout .
: c -
c^key[i], key () - , .
key , .
key . ( ),
.
(*3) , ,
, . : David Kahn: The Code-Breakers, Macmillan, 1967, New York, pp 207-213.
(*3) error, printf,
%s, %c %d, . printf(). %s
.., #8.2.4. .
(*1) , typedef?
(*2) - , ,
. ? ?
x y?
(*1) ?
#define PI = 3.141593
#define MAX(a,b) a>b?a:b
#define fac(a) (a)*fac((a)-1)
(*3) , ( C ).
cin cout. . :
(#3.1) ,
.

90

"", , int float. -

C++,
.
, , , , .
, ,
( , "") .
C++
.

5.1
, ,
, ,
. , ,
,
.
(). ,
C++ float +, -, * .. ,
. ,
,
. , , ,
trunk_module ( ), -
list_of_paragraphs ( ). , , ,
, , ,
. , ,
.
,
.
-
(, , ) ,
(, ,
). ,

().
:
I.

II.

. , ,
(class). ,
. .
, .
. ""
. .
. , ,
.

III.

. ,
. , ,
. (friend). ,
.

IV.

. ,
. ( ),

91
.
.

5.2
- .
, , , ,
.

5.2.1
struct ,
date :
struct date { int month, day, year; };
// :
, , }
date today;
void set_date(date*, int, int, int);
void next_date(date*);
void print_date(date*);
// ...
. ,
:
struct date {
int month, day, year;
void set(int, int, int);
void get(int*, int*, int*);
void next();
void print();
};
, ,
.
:
date today;
//
date my_burthday;
//
void f()
{
my_burthday.set(30,12,1950);
today.set(18,1,1985);
my_burthday.print();
today.next();
}
,
:
void date::next()
{
if ( ++day > 28 ) {
//
}
}
.
, .

5.2.2

92

date date,
, date.
struct class:
class date {
int month, day, year;
public:
void set(int, int, int);
void get(int*, int*, int*);
void next();
void print();
};
public . , ,
. , , . Struct - class,
, ,
. :
void date::ptinr()
// ,
{
cout << month << "/" << day << "/" year;
}
date. :
void backdate()
{
today.day--;
}

//

, , .
, , (, 36, 1985)
, , ,
, . ,
date . - ,
,
.
.
, , , .

5.2.3
, ,
. :
class x {
int m;
public:
int readm() { return m; }
};
x aa;
x bb;
void f()
{
int a = aa.readm();
int b = bb.readm();
// ...
}
member() m aa.m, - bb.m.
, , .
this. x this
x* this;

93
, , . this
, . x :
class x {
int m;
public:
int readm() { return this->m; }
};
this . this
, . - ,
:
class dlink {
dlink* pre;
//
dlink* suc;
//
public:
void append(dlink*);
// ...
};
void dlink::append(dlink* p)
{
p->suc = suc;
// , p->suc = this->suc
p->pre = this;
// this
suc->pre = p;
// , this->suc->pre = p
suc = p;
// , this->suc = p
}
dlink* list_head;
void f(dlink*a, dlink *b)
{
// ...
list_head->append(a);
list_head->append(b);
}
, 7.
, this, pre suc
(, ). dlink, dlink::append()
. C++ class, .

5.2.4
set_date()
( ) . ,
, , (
, , ) .
: ,
.
, . ,
, . :
class date {
// ...
date(int, int, int);
};
, .
, :
date today = date(23,6,1983);
date xmas(25,12,0);
//
// (xmas - )
date my_burthday;
// ,

94
. ,
. :
class date {
int month, day, year;
public:
// ...
date(int, int, int);
date(char*);
date(int);
date();
};

//
//
// ,
// :

,
(#4.6.7). ,
:
date
date
date
date

today(4);
july4(" 4, 1983");
guy("5 ");
now;

//

, overload.
,
overload
.
date .
"", - , -
, , , .
, , .
- . date
, " : today"
().
class date {
int month, day, year;
public:
// ...
date(int d =0, int m =0, int y =0);
date(char*);
//
};
date::date(int d, int m, int y)
{
day = d ? d : today.day;
month = m ? m : today.month;
year = y ? y : today.year;
// ,
// ...
}
, " ",
. day mounth , , year
. , . 1 . .. (year==-1)
1 . .. (year==1), .
.
, . :
date

d = today;

//

, , .
X ,
X(X&). #6.6.

5.2.5

95

, , ,
.
, , .
X ~X() (" "). ,
(. #3.2.6),
. , , ,
:
class char_stack {
int size;
char* top;
char* s;
public:
char_stack(int sz) { top=s=new char[size=sz]; }
~char_stack()
{ delete s; }
//
void push(char c) { *top++ = c; }
char pop()
{ return *--top;}
}
char_stack , :
void f()
{
char_stack s1(100);
char_stack s2(200);
s1.push('a');
s2.push(s1.pop());
char ch = s2.pop();
cout << chr(ch) << "\n";
}
f(), char_stack s1, 100 , s2,
200 . f() .

5.2.6 Inline

. , , , . , ,
, .
, (
) , ,
.
, inline- . ,
( ) , inline. ,
, , char_stack,
, !
, ,
. , , .
,
.
inline . :
char char_stack {
int size;
char* top;
char* s;
public:
char pop();
// ...
};

96
inline char char_stack::pop()
{
return *--top;
}

5.3
? ,
. , " ",
. ,
,
. , .
: , , ,
, .. "",
, .
, ,
. ( , )
.
(. #4.4:
). , , . ,
, , .
. , ,
.

5.3.1
,
.
, 3.
:
struct name {
char* string;
char* next;
double value;
};
table:
// table.h
class table {
name* tbl;
public:
table() { tbl = 0; }
name* look(char*, int = 0);
name* insert(char* s) { return look(s,1); }
};
, 3 , .
table, table .. :
#include "table.h"
table globals;
table keywords;
table* locals;
main() {
locals = new table;
// ...
}
table::look(), name :

97
#include
name* table::look(char* p, int ins)
{
for (name* n = tbl; n; n=n->next)
if (strcmp(p,n->string) == 0) return n;
if (ins == 0) error(" ");
name* nn = new name;
nn->string = new char[strlen(p)+1];
strcpy(nn->string,p);
nn->value = 1;
nn->next = tbl;
tbl = nn;
return nn;
}
table, ,
, . - ,
, table,
:
class table {
name** tbl;
int size;
public:
table(int sz = 15);
~table();
name* look(char*, int = 0);
name* insert(char* s) { return look(s,1); }
};
, ,
.
, , , .
, .
-:
table::table(int sz)
{
if (sz < 0) error(" ");
tbl = new name*[size=sz];
for (int i = 0; inext) {
delete n->string;
delete n;
}
delete tbl;
}
name table::~table().
, (#3.1.3):
#include
name* table::look(char* p, int ins)
{
int ii = 0;
char* pp = p;
while (*pp) ii = ii<<1 ^ *pp++;
if (ii < 0) ii = -ii;
ii %= size;
for (name* n=tbl[ii]; n; n=n->next)
if (strcmp(p,n->string) == 0) return n;
if (ins == 0) error(" ");
name* nn = new name;
nn->string = new char[strlen(p)+1];
strcpy(nn->string,p);
nn->value = 1;
nn->next = tbl[ii];

98

tbl[ii] = nn;
return nn;

, , -
. .
, .
. , , ,
. ( ), ()
, ,
.
, , C++ ,
? ,
? , ,
, , ,
? - . , ,
, , ( )
.
, "" .
, ""
, , .
, , ,

. inline- ,
. , C C++
( C struct , C++ ). C++
.

5.3.2
( )
, ( ).
,
. ,
; . ,
,
.
intset, " ":
class intset {
int cursize, maxsize;
int *x;
public:
intset(int m, int n);
// , m int' 1..n
~intset();
int member(int t);
// t ?
void insert(int t);
// "t"
void iterate(int& i)
{ i = 0; }
int ok(int& i)
{ return i
void error(char* s)
{
cerr << "set: " << s << "\n";
exit(1);
}
intset main(), .
, . ,
:
main(int argc, char* argv[])
{
if (argc != 3) error(" ");
int count = 0;
int m = atoi(argv[1]);
//

99
int n = atoi(argv[2]);
// 1..n
intset s(m,n);
while (count maxsize) error(" ");
int i = cursize-1;
x[i] = t;
while (i>0 && x[i-1]>x[i]) {
int t = x[i];
// x[i] [i-1]
x[i] = x[i-1];
x[i-1] = t;
i--;
}

:
int intset::member(int t)
{
int l = 0;
int u = cursize-1;
while (l <= u) {
int m = (l+u)/2;
if (t < x[m])
u = m-1;
else if (t > x[m])
l = m+1;
else
return 1;
}
return 0;
}

//

//
//

, , ,
, intset .
, ( ,
, intset -, ).
: iterate() , ok() , , next()
, :
class intset {
// ...
void iterate(int& i)
{ i = 0; }
int ok(int& i)
{ return iiterate(var);
while (set->ok(var)) cout << set->next(var) << "\n";
}
#6.8.

5.4
, . ,
. ,
, ,
. ,
, . ,
, , () .

5.4.1
, , vector matrix ( ).

. , . ,
, 0...3,
, 0...3. ,

100

elem(), , matrix
.
multiply() () :
vector multiply(matrix& m, vector& v);
{
vector r;
for (int i = 0; i<3; i++) {
// r[i] = m[i] * v;
r.elem(i) = 0;
for (int j = 0; j<3; j++)
r.elem(i) += m.elem(i,j) * v.elem(j);
}
return r;
}
"" , . multiply() elem()
4*(1+4*3) .
, multiply() vector,
, multiply() matrix,
. .
, . ,
, (friend).
friend. :
class matrix;
class vector {
float v[4];
// ...
friend vector multiply(matrix&, vector&);
};
class matrix {
vector v[4];
// ...
friend vector multiply(matrix&, vector&);
};
, . , friend
this ( ). friend .
. ,
; , .
, :
vector multiply(matrix& m, vector& v);
{
vector r;
for (int i = 0; i<3; i++) {
// r[i] = m[i] * v;
r.v[i] = 0;
for (int j = 0; j<3; j++)
r.v[i] += m.v[i][j] * v.v[j];
}
return r;
}
friend (
multiply() ).
, ,
, . 6 friend.
.
. :
class x {
// ...
void f();
};
class y {

101

};

// ...
friend void x::f();

, .
:
class x {
friend class y;
// ...
};
friend y x.

5.4.2 *1
*1 . (. .)

.
:: :
class x {
int m;
public:
int readm()
{ return x::m; }
void setm(int m) { x::m = m; }
};
x::setm() m m, -
x::m. :: .
:: () . ,
read, put open ,
, . :
class my_file {
// ...
public:
int open(char*, char*);
};
int my_file::open(char* name, char* spec)
{
// ...
if (::open(name,flag)) { // open() UNIX(2)
// ...
}
// ...
}

5.4.3
. :
class set {
struct setmem {
int mem;
setmem* next;
setmem(int m, setmem* n) { mem=m; next=n; }
};
setmem* first;
public:
set() { first=0; }
insert(int m) { first = new setmem(m,first);}
// ...
};

102
, . ,
- ,
:
class set {
struct setmem {
int mem;
setmem* next;
setmem(int m, setmem* n)
};
// ...
};
setmem::setmem(int m, setmem* n) { mem=m, next=n}
setmem m1(1,0);
, set::setmem::setmem(), , .
- --.
:
class setmem {
friend class set;
// set
int mem;
setmem* next;
setmem(int m, setmem* n) { mem=m; next=n; }
};
class set {
setmem* first;
public:
set() { first=0; }
insert(int m) { first = new setmem(m,first);}
// ...
};

5.4.4
- , ,
, . ,
() .
, . ,

:
class task {
// ...
task* next;
static task* task_chain;
void shedule(int);
void wait(event);
// ...
};
task_chain ( ) static , ,
task. task, ""
, public.
:
task::task_chain
task_chain.
.

5.4.5

103

. ,
, #4.6.9
, . ,
: ,
. ,
. , , ,
. ,
, .
, this
() :
#include
struct cl
{
char* val;
void print(int x) { cout << val << x << "\n"; };
cl(char* v) { val = v; }
};
// ``'' :
typedef void (*PROC)(void*, int);
main()
{
cl z1("z1 ");
cl z2("z2 ");
PROC pf1 = PROC(&z1.print);
PROC pf2 = PROC(&z2.print);
z1.print(1);
(*pf1)(&z1,2);
z2.print(3);
(*pf2)(&z2,4);
}
(. 7) ,
*2.
*2 C++ : cl::* "
cl". :
typedef void (cl::*PROC)(int);
PROC pf1 = &cl::print;
//
PROC pf2 = &cl::print;
. ->. :
(z1.*pf1)(2);
((&z2)->*pf2)(4);
(. )

5.4.6
struct - , ,
struct s { ...

class s { public: ...
, .
struct, (. #.8.5.13).
, ,

104
. , C
:
union tok_val {
char* p;
char v[8];
long i;
double d;
};

//
//
//
//

( 8 char)

, , , ,
, . :
void strange(int i)
{
tok_val x;
if (i)
x.p = "2";
else
x.d = 2;
sqrt(x.d);
}

// i != 0

, , , , . :
tok_val curr_val = 12;

// : int tok_val'

. , , :
union tok_val {
char* p;
char v[8];
long i;
double d;
tok_val(char*);
tok_val(int ii)
tok_val()
};

//
// ( 8 char)
//
//
// p v
{ i = ii; }
{ d = dd; }

,
(. #4.6.7 #6.3.3). :
void f()
{
tok_val a = 10;
tok_val b = 10.0;
}

// a.i = 10
// b.d = 10.0

( , char* char[8], int char, ..),



. :
tok_val::tok_val(char* pp)
{
if (strlen(pp) <= 8)
strncpy(v,pp,8); //
else
p = pp;
//
}
- .
tok_val,
, .
, , :
class tok_val {
char tag;

105
union {
char* p;
char v[8];
long i;
double d;
};
int check(char t, char* s)
{ if (tag!=t) { error(s); return 0;
public:
tok_val(char* pp);
tok_val(long ii)
{ i=ii; tag='I'; }
tok_val(double dd) { d=dd; tag='D'; }
long& ival()
{ check('I',"ival");
double& fval()
{ check('D',"fval");
char*& sval()
{ check('S',"sval");
char* id()
{ check('N',"id");
};

} return 1; }

return
return
return
return

i;
d;
p;
v;

}
}
}
}

, , strncpy(). strncpy()
strcpy(), , , :
tok_val::tok_val(char* pp)
{
if (strlen(pp) <= 8) {
tag = 'N'
strncpy(v,pp,8);
}
else {
tag = 'S'
p = pp;
}
}

//
// 8
//
//

tok_val :
void f()
{
tok_val t1("short");
tok_val t2("long string");
char s[8];
strncpy(s,t1.id(),8);
strncpy(s,t2.id(),8);
}

// , v
// , p
// ok
// check()

5.5
, , .
, , .
:
[1] : ,
, ,
;
[2] : , , ,
;
[3] : new
delete;
[4] : .

(. #6.4), .
, ,
. table #5.3.

5.5.1

106

x y - cl, x=y y
x (. #2.3.8). (
) , ,
. :
class char_stack {
int size;
char* top;
char* s;
public:
char_stack(int sz) {
~char_stack()
{
void push(char c) {
char pop()
{
};
void h()
{
char_stack s1(100);
char_stack s2 = s1;
char_stack s3(99);
s3 = s2;
}

top=s=new char[size=sz]; }
delete s; }
//
*top++ = c; }
return *--top; }

//
//

char_stack::char_stack() : s1 s3. s2 ,
. char_stack::~char_stack()
: s1, s2 s3! ,
, h() s1, s2 s3 ,
s1. ,
s3. : . 6.

5.5.2
:
table tbl1(100);
void f() {
static table tbl2(200);
}
main()
{
f();
}
table::table(), #5.3.1 , : tbl1
tbl2. table::~table() : tbl1 tbl2 main().
,
; . ,
, , , .
, ,
.
:
void g(int a)
{
static table t(a);
}

//

main() . , C,
/
, / main().
C++ .
. .
cin, cout cerr? ? , ,
, ? ,

107
main().
,
. , .
exit(), ,
abort(), . , , exit()
. exit() .
, ,
, : .
, ,
.

5.5.3
:
main() {
table*
table*
delete
delete
}

p = new table(100);
q = new table(200);
p;
p;
// ,

table::table() , table::~table(). , C++


, , new, - , .
q , p ! ,
, p q. , , ,
. p , , .
delete
, ,
.
new delete (. #3.2.6).
new delete (. #5.5.6)

5.5.4

class classdef {
table members;
int no_of_members;
// ...
classdef(int size);
~classdef();
};
, classdef size member,
- , , table::table() size.
:
classdef::classdef(int size)
: members(size)
{
no_of_members = size;
// ...
}
member ( table::table()) ( )
, ( classdef::classdef()).
, .
, , .
:
class classdef {
table members;

108

};

table friends;
int no_of_members;
// ...
classdef(int size);
~classdef();

( ),
:
classdef::classdef(int size)
: friends(size), members(size)
{
no_of_members = size;
// ...
}
, , ,
:
classdef::classdef(int size)
: friends(size=size/2), members(size);
{
no_of_members = size;
// ...
}

//

, .
, table::table 15,
:
classdef::classdef(int size)
: members(size)
{
no_of_members = size;
// ...
}
size friend' 15.
, , (, classdef) ,
, .
, , -
:
class classdef {
table* members;
table* friends;
int no_of_members;
// ...
classdef(int size);
~classdef();
};
classdef::classdef(int size)
{
members = new table(size);
friends = new table;
no_of_members = size;
// ...
}

//

new, delete:
classdef::~classdef()
{
// ...
delete members;
delete friends;

109
}
, , members friends
,
. , , .

5.5.5
, ,
, .
. :
table tblvec[10];
, table::table() .
. table, table
(#5.3.1) :
class table {
// ...
void init(int sz);
public:
table(int sz)
{ init(sz); }
table()
{ init(15); }
}

//
// ,
//

, . ,
new, .
,
. :
void f()
{
table*
table*
delete
delete
}

t1 =
t2 =
t1;
t2;

new table;
new table[10];
//
// : 10

:
void g(int sz)
{
table* t1 = new table;
table* t2 = new table[sz];
delete t1;
delete[] t2;
}
? ,
.

5.5.6
, ,
,
. -
, ,

.

110

name, table.
:
struct name {
char* string;
name* next;
double value;
name(char*, double, name*);
~name();
};
,
( , ), new
delete. , "" name, ,
. nfree
name:
const NALL = 128;
name* nfree;
, new, ,
delete. , ,
. , name
16 , 20 . :
name::name(char* s, double v, name* n)
{
register name* p = nfree;
//
if (p)
nfree = p->next;
else {
//
name* q = (name*)new char[ NALL*sizeof(name) ];
for (p=nfree=&q[NALL-1]; qnext = p-1;
(p+1)->next = 0;
}
this = p;
//
string = s;
value = v;
next = n;
}
this , ,
. name::name()
, name new, . #5.5.8
, ,
.
,
name* q = new name[NALL];
, , new name::name().
:
name::~name()
{
next = nfree;
nfree = this;
this = 0;
}
this 0 ,
.

5.5.7

111

this, this
. ,
.
, this :
mytype::mytype(int i)
{
if (i) this = mytype_alloc();
//
};
, i==0 .
, new, . new, this
, this ,
(, ). , , ( )
new. :
mytype::mytype(int i)
{
if (this == 0) this = mytype_alloc();
//
};
, ,
new, , , , delete, ,
. , -
. , - ,
. ,
.
, , ,
, .
, , , .

5.5.8
,
, .
( - .) vector, stack, intset
table ,
. ,
,
. :
class char_stack {
int size;
char* top;
char* s;
public:
char_stack(int sz) { top=s=new char[size=sz]; }
~char_stack()
{ delete s; }
//
void push(char c) { *top++ = c; }
char pop()
{ return *--top; }
};
, . :
class char_stack {
int size;
char* top;
char s[1];
public:
char_stack(int sz);
void push(char c) { *top++ = c; }

char pop()

112
{ return *--top; }

};
char_stack::char_stack(int sz)
{
if (this) error(" ");
if (sz < 1) error(" < 1");
this = (char_stack*) new char[sizeof(char_stack)+sz-1];
size = sz;
top = s;
}
, , , char_stack,
delete .

5.6
(*1) 3, table.
(*1) tnode (#.8.5) , ..
tnode' , ..
(*1) intset (#5.3.2) .
(*1) intset node, node - .
(*3) . , ,
+, -, * /. :
class expr {
// ...
public:
expr(char*);
int eval();
void print();
}
expr::expr() . expr::eval()
, expr::print() cout. , ,
:
expr x("123/4+123*4-3");
cout << "x = " << x.eval() << "\n";
x.print();
expr : ,
- . :
, , ..
(*1) char_queue ( ) ,
. char_queue (1) (2) .
.
(*2) histogram (), ,
histogram.
. , . : .
(*2) , .
, , draw,
"" . : . intset.
(*2) date (#5.8.2), char_stack (#5.2.5) intset (#5.3.2)
( ). class friend. ,
.
(*3) - .
, , .

113
(*2) 5 ,
=. 10.
(*1) :
#include
main()
{
cout << "Hello, world\n";
}
,
Initialize
Hello, world
Clean up
main().

114

6

! -

, C++ .

. , ,
, () [],
.
. , ,

.

6.1
,
. , int C++ +, -, *, / ..
() .
, ,
. ,
. ,
, , ,
C++. C++
,
. , ,

, , .
:
class complex {
double re, im;
public:
complex(double r, double i) { re=r; im=i; }
friend complex operator+(complex, complex);
friend complex operator*(complex, complex);
};
,
, + * ( ).
+ * operator+ operator*. ,
, b c complex, b+c ( ) operator+(b,c).
. :
void f()
{
complex a = complex(1, 3.1);
complex b = complex(1.2, 2);
complex c = b;
a = b+c;
b = b+c*a;
c = a*b+complex(1,2);
}
, b=b+(c*a), b=(b+c)*a.

6.2

115

, :
+

&

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>= <<= ==

!=

<=

>=

&&

||

++

--

[]

()

new delete

- (#6.7), (#6.8),
(#3.2.6). ,
. , , %
!. , ,
, . , **, pow().
,
. , **, ,
, . ** (
) ( )? a**p a*(*p) (a)**(p)?
operator ( , ), ,
, operator<<. , .
- . :
void f(complex a, complex b)
{
complex c = a + b;
//
complex d = operator+(a,b); //
}
complex .

6.2.1
, ,
, . ,
@ aa@bb aa.operator@(bb),
operator@(aa,bb). , aa@bb . ,
, ,
, , . ,
@ aa@ @aa aa.operator@(),
operator@(aa). , , aa@ @aa .
:
class X {
//
friend X operator-(X);
//
friend X operator-(X,X);
//
friend X operator-();
// :
friend X operator-(X,X,X); // :
// ( : this)
X* operator&(); // & ( )
X operator&(X); // & ( )
X operator&(X,X);
// :
};
++ -- , .

6.2.2
, ,
. , , =

116

, , ,
lvalue (#.6).

. , a int, ++a
a+=1, a=a+1.
, ,
. , operator+=() complex
complex::operator+() complex::operator=().
= &
. " " .
, , X. , ,
X::operator&(), . - X,
*1. , ,
X::operator&() , .
*1 "", ,
. . ( )

6.2.3
,
(, new delete,
). ,
, . ,
, .
, ,
. , , aa 2:
aa+2, ,
aa.operator+(2), 2+aa , int,
+ , 2.operator+(aa).
, , 2+aa aa+2,
. +, ,
, , 2+aa aa+2.
.
.
,
, ,
, (. #4.6.7).

6.3
,
-, .
. :
class complex {
double re, im;
public:
complex(double r, double i) { re=r; im=i; }
friend complex operator+(complex, complex);
friend complex operator+(complex, double);
friend complex operator+(double, complex);
friend complex operator-(complex, complex);
friend complex operator-(complex, double);
friend complex operator-(double, complex);
complex operator-()
// friend complex operator*(complex, complex);
friend complex operator*(complex, double);
friend complex operator*(double, complex);

117
};

// ...

, complex, :
void f()
{
complex a(1,1), b(2,2), c(3,3), d(4,4), e(5,5);
a = -b-c;
b = c*2.0*c;
c = (d+e)*a;
}
complex double, operator+(),
. ,
; , , complex.

6.3.1
()
, double complex. :
class complex {
// ...
complex(double r) { re=r; im=0; }
};
, , :
complex z1 = complex(23);
complex z2 = 23;
z1, z2 complex(23).
- , . ,
, , ,
. , complex :
class complex {
double re, im;
public:
complex(double r, double i = 0) { re=r; im=i; }
friend complex operator+(complex, complex);
friend complex operator*(complex, complex);
};
, complex , .
complex . , a=b*2 :
a=operator*( b, complex( double(2), double(0) ) )
,
.
, ,
, , .

6.3.2
,
, :
[1]
( );
[2] , ;
[3] , .

118

, ,
. X::operator T(), T - ,
X T. , tiny (),
0...63,
:
class tiny {
char v;
int assign(int i)
{ return v = (i&~63) ?
public:
tiny(int i)
tiny(tiny& i)
int operator=(tiny& i)
int operator=(int i)
operator int()
}

(error(" "),0) : i; }
{
{
{
{
{

assign(i); }
v = t.v; }
return v = t.v; }
return assign(i); }
return v; }

, tiny int, , int.


tiny .
tiny , tiny::operator int(), int tiny. ,
, int, tiny, int. :
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;
}

//
//
//
//
//
//

c3 = 60

i = 64
: c1 =
: c2 =

()
0 ( 66)
0
()

tiny , .
, .
- ,
( 100, , -
..). , + *.
,
( ) ,
.
istream ostream , ,
while (cin>>x) cout<>x istream&. ,
cin, while (. #8.4.2).
, , .

6.3.3
( ) X ,
X,
X.

. ;
, .
.
. :
class x { /* ... */ x(int); x(char*); };
class y { /* ... */ y(int); };
class z { /* ... */ z(x); };
overload f;

119
x f(x);
y f(y);
z g(z);
f(1);
// : f(x(1)) f(y(1))
f(x(1));
f(y(1));
g("asdf");
// : g(z(x("asdf")))
g(z("asdf"));
,
. :
class x { /* ... */ x(int); }
overload h(double), h(x);
h(1);
h(double(1)), h(x(1)),
.
, #4.6.7.
, , .
.
, ; ,
, . , ,
, .
.
( ), .
- . ,
, ,
complex.

. , , aa=f(1),
aa . aa x, , x,
, - f(x(1)), aa - y, f(y(1)).
g("asdf"),
g(z(x("asdf"))). , ,
. ,
,
, ..
, , , !

6.4
, 1.2 12e3
double. , ,
, .
, .
inline, .
, , comlpex, zz1*3+zz2*comlpex(1,2)
, . *, +
, comlpex(3) comlpex(1,2),
inline.

6.5
comlpex , , ,
, .
double , . ,
.
, ,
. :
class matrix {

120
double m[4][4];
public:
matrix();
friend matrix operator+(matrix&, matrix&);
friend matrix operator*(matrix&, matrix&);
};
,
, . ,
. :
matrix operator+(matrix&, matrix&);
{
matrix sum;
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
sum.m[i][j] = arg1.m[i][j] + arg2.m[i][j];
return sum;
}
operator+() + , .
:
class matrix {
// ...
friend matrix& operator+(matrix&, matrix&);
friend matrix& operator*(matrix&, matrix&);
};
, .
, .
,
. , .
( , ) .

6.6
string:
struct string {
char* p;
int size;
// , p
string(int sz) { p = new char[size=sz]; }
~string() { delete p; }
};
- , .
. , #5.10, .
:
void f()
{
string s1(10);
string s2(20);
s1 = s2;
}
, s1=s2
. f() s1 s2
. ,
string:
struct string {
char* p;
int size;

// , p

121
string(int sz) { p = new char[size=sz]; }
~string() { delete p; }
void operator=(string&)

};
void string::operator=(string& a)
{
if (this == &a) return;
// s=s;
delete p;
p=new char[size=a.size];
strcpy(p,a.p);
}
string , .
f() :
void f()
{
string s1(10);
s2 = s1;
}
, .
. string::operator=() ,
: p .
, . ,
, . , , , ,
:
struct string {
char* p;
int size;
// , p
string(int sz) { p = new char[size=sz]; }
~string() { delete p; }
void operator=(string&)
string(string&);
};
void string::string(string& a)
{
p=new char[size=a.size];
strcpy(p,a.p);
}
X X X(X&). ,
- . .
X , ,
, :
class X {
// ...
X(something);
X(&X);
operator=(X&);
~X();
};

//
//
//
//

:
:
:
:

, : .
, - .
. ,
. X(X&), :
string g(string arg)
{
return arg;
}
main()
{
string s = "asdf";

122
}

s = g(s);

, g() s "asdf". s arg


: string(string&). g()
string(string&); ,
s. , , string::~string()
.

6.7
operator[].
() operator[] .
.. #2.3.10,

. .
:
struct pair {
char* name;
int val;
};
class assoc {
pair* vec;
int max;
int free;
public:
assoc(int);
int& operator[](char*);
void print_all();
};
assoc pair max. free.
:
assoc::assoc(int s)
{
max = (s<16) ? s : 16;
free = 0;
vec = new pair[max];
}
, #2.3.10.
assoc :
#include
int assoc::operator[](char* p)
/*
"pair":
p,
"pair"
"pair", 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; iname = new char[strlen(p)+1];
strcpy(pp->name,p);
pp->val = 0;
// : 0
return pp->val;
}

123
assoc , . ,
, :
vouid assoc::print_all()
{
for (int i = 0; i>buf) vec[buf]++;
vec.print_all();
}

6.8
, (_),
, , .
operator()
.
,
,
.
assoc . ,
assoc_iterator, ,
assoc. , assoc,
:
class assoc {
friend class assoc_iterator;
pair* vec;
int max;
int free;
public:
assoc(int);
int& operator[](char*);
};

class assoc_iterator{
assoc* cs; // assoc
int i;
//
public:
assoc_iterator(assoc& s) { cs = &s; i = 0; }
pair* operator()()
{ return (ifree)? &cs->vec[i++] : 0; }
};
assoc_iterator assoc, pair
, ().
0:
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";
}
, :
. ,

124
.
,
. , first(), next() last() (,
).

6.9
string.

C++.
#include
#include
class string {
struct srep {
char* s;
//
int
n;
//
};
srep *p;
public:
string(char *);
// string x = "abc"
string();
// string x;
string(string &);
// string x = 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;
}

125
}
, .
() :
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";
}
(#8.4.1).
istream& operator>>(istream& s, string& x)
{
char buf[256];
s >> buf;
x = buf;
cout << "echo: " << x << "\n";
return s;
}
. :
void error(char* p)
{
cerr << p << "\n";
exit(1);
}
char& string::operator[](int i)
{
if (i<0 || strlen(p->s)s[i];
}
. ,
. , done,
, .
.

126
main()
{
string x[100];
int n;
cout << " \n";
for (n = 0; cin>>x[n]; n++) {
string y;
if (n==100) error(" ");
cout << (y = x[n]);
if (y=="done") break;
}
cout << " \n";
for (int i=n-1; 0<=i; i--) cout << x[i];
}

6.10
, , ,
, - .
: , (. ),
.
X:
class X {
// ...
X(int);
int m();
friend int f(X&);
};
f(X&) X::m() ( ),
X. X::m() " ",
f() , .
:
void g()
{
1.m();
f(1);
}

//
// f(x(1));

, , , .
, lvalue (=, *=, ++ ..),
.
, ,
, . , ,
lvalue (+, -, || ..).
, ,
, , , .
. , ,
m m.inv(). , inv() m,
, m, .
, : , - -
. ,
. , ;
. ,
. ,
this. , .

6.11

127

,
, . ,
,
. , , ,
, + .
/
,
int, ,
.
. ,
. ,
C++ ,
.

6.12
(*2) string. + "
" +=. string ?
(*1.5) () .
(*3) string ,
. , ,
, .
(*2) string , , ..
, , ,
sring.
(*3) string ,
. , ,
. ,
.
(*4) string , ,
.
(*2) :
struct X {
int i;
X(int);
operator+(int);
};
struct Y {
int i;
Y(X);
operator+(X);
operator int();
};
X operator* (X,Y);
int f(X);
X x = 1;
Y y = x;
int i = 2;
main()
{
i + 10;
y + 10;
y + 10 * y;
x + y + i;
x * x + i;
f(7);
f(y);

128

y + y;
106 + y;

X Y , . ,
.
(*2) INT, int. : INT::operator int().
(*1) RINT, int ,
- + ( ), - ( ), *, /, %. :
$ (R?)INT::operator int().
(*3) LINT, RINT , 64
.
(*4) , . :
, string.
(*2) ,
. : INT + - ,
int INT. ,

.
(*3) , .
, .
, .
(*2) comlpex (#6.3.1), tiny (#6.3.2) string (#6.9) friend .
. . ,
. 5.3.
(*2) vec4 float. operator[] vec4. +,
-, *, /, =, +=, -=, *=, /= .
(*3) mat4 vec4. mat4 operator[], vec4.
. ,
mat4.
(*2) vector, vec4, ,
vector::vector(int).
(*3) matrix, mat4, ,
matrix::matrix(int,int).

129

7

- .

C++.
,

.
,
.
,
, .

. ,
.

7.1
(,
, ),
.
, ,
. , ( )
, , .., ,
,
- , .
, ()
.
,
, , ,
, /
,
( , ..), .
C++, #7.2,
, .
, , ,
, .
- ,
, . ,
, ,
, ,
.

7.2
,
. ,
, (
).
, , , .

7.2.1

130

, ,
. :
struct employee {
char*
name;
short
age;
short
department;
int
salary;
employee* next;
// ...
};

//
//
//
//
//

next. :
struct manager {
employee emp;
employee* group;
// ...
};

//
//
//

; employee emp
manager. , , , emp
. (manager*) (employee*),
, , . ,
, . manager*
, emp,
. , ,
:
struct manager : employee {
employee* group;
// ...
};
manager employee , , employee manager. manager
group employee (name, age ..).
employee manager ,
. :
void f()
{
manager m1, m2;
employee e1, e2;
employee* elist;
elist = &m1;
// m1, e1, m2 e2 elist
m1.next = &e1;
e1.next = &m2;
m2.next = &e2;
e2.next = 0;
}
, manager* employee*.
, employee* manager* .

7.2.2
employee manager
, , . :
class employee {
char* name;
// ...
public:
employee* next;
void print();

131
// ...

};
class manager : public employee {
// ...
public:
void print();
// ...
};
. manager
employee? employee
manager? employee
manager? ,
?
:
void manager::print()
{
cout << " " << name << "\n";
// ...
}
,
, . , this,
() name this->name. manager::print
,
, name .
, :
. ,
,
. ,
, .
, ,
, , ..
.
, friend,
, ( #5.3). :
class employee {
friend void manager::print();
// ...
};
manager::print(),
class employee {
friend class manager;
// ...
};
employee manager. , name
manager::print().
, , -
. :
void manager::print()
{
employee::print();
// ...
}

//
//

, ::, print() manager.


. :
void manager::print()
{
print();

//

// ...

132
//

, manager::print()
.

7.2.3
employee (public) manager :
class manager : public employee {
// ...
};
, employee manager. :
void clear(manager* p)
{
p->next = 0;
}
, next - employee manager'. -
(private) , public:
class manager : employee {
// ...
};
, employee manager. ,
manager employee,
manager . , manager clear()
. ,
.
, , , ,
. , ,
.
struct, public . ,
struct D : B { ...

class D : public B { public: ...


, , class, public friend,
struct. , ,
, .
, , $
. :
class manager : employee {
// ...
public:
// ...
employee::name;
employee::department;
};

_ :: _ ;
, .
name department manager', salary age - . ,
.
.

133
, ,
, , ()
. , ,
.

7.2.4
derived base, derived
base
. , base derived, .
:
class base { /* ... */ };
class derived : public base { /* ... */ };
derived m;
base* pb = &m;
//
derived* pd = pb; // : base* derived*
pd = (derived*)pb; //
,
. .
base derived, derived* base* .
, base
base, derived:
class base {
int m1;
public:
int m2;
// m2 - base
};
class derived : base {
// m2 derived
};
derived d;
d.m2 = 2;
// : m2
base* pb = &d; // : ( base)
pb->m2 = 2;
// ok
pb = (base*)&d; // ok:
pb->m2 = 2;
// ok
, ,
. , , "". ,
,
, . , ,
m1.
.

7.2.5
. :
class
class
class
class
class
class
class
class

employee { ... };
secretary : employee { ... };
manager : employee { ... };
temporary : employee { ... };
consultant : temporary { ... };
director : manager { ... };
vice_president : manager { ... };
president : vice_president { ... };

.
,
. :

class
class
class
//
class
class

134
temporary { ... };
employee { ... };
secretary : employee { ... };
C++:
temporary_secretary : temporary : secretary { ... };
consultant : temporary : employee { ... };

,
. ,
. :
class temporary { ... };
class employee { ... };
class secretary : employee { ... };
// :
class temporary_secretary : secretary
{ temporary temp; ... };
class consultant : employee
{ temporary temp; ... };
,
. , consultant temporary, consultant'
(temporary employee), .
.

7.2.6
.
, , ,
. :
class base {
// ...
public:
base(char* n, short t);
~base();
};
class derived : public base {
base m;
public:
derived(char* n);
~derived();
};
.
, (. #5.5.4).
:
derived::derived(char* n) : (n,10), m("member",123)
{
// ...
}
: , , .
: , .

7.2.7

, : base*,
?
:
[1] , (#7.3.3);

135

[2] , ;
[3] (#7.2.8).
( ) : , ,
.. 1 ,
. 2 3 ,
( ) . 3 -
2, .
, 2.
:
enum empl_type { M, E };
struct employee {
empl_type type;
employee* next;
char*
name;
short
department;
// ...
};
struct manager : employee {
employee* group;
short
level;
//
};
, , :
void print_employee(employee* e)
{
switch (e->type) {
case E:
cout << e->name << "\t" << e->department << "\n";
// ...
break;
case M:
cout << e->name << "\t" << e->department << "\n";
// ...
manager* p = (manager*)e;
cout << " " << p->level << "\n";
// ...
break;
}
}
, :
void f()
{
for (; ll; ll=ll->next) print_employee(ll);
}
, , ,
, , .
. -
, - case switch .
, $,
, , , .
- , print() ,
, . :
void print_employee(employee* e)
{
cout << e->name << "\t" << e->department << "\n";
// ...
if (e->type == M) {
manager* p = (manager*)e;
cout << " " << p->level << "\n";

136

// ...

if, ,
, , , ,
.

7.2.8
,
,
.
. :
struct employee {
employee* next;
char*
name;
short
department;
// ...
virtual void print();
};
virtual , print()
, print() .
.
, . :
void employee::print()
{
cout << e->name << "\t" << e->department << "\n";
// ...
}
, , ,
, , ,
. , .
:
struct manager : employee {
employee* group;
short
level;
// ...
void print();
};
void manager::print()
{
employee::print();
cout << "\t" << level << "\n";
// ...
}
print_employee() , print(),
:
void f(employee* ll)
{
for (; ll; ll=ll->next) ll->print();
}
. :
main()
{
employee e;

137

e.name = ".";
e.department = 1234;
e.next = 0;
manager m;
m.name = ".";
e.department = 1234;
m.level = 2;
m.next = &e;
f(&m);

. 1234
2
. 1234
, , f() ,
manager ! , employee
. ( )
.
, .
, .
::, manager::print(),
, . manager::print()
. ,
: virtual inline ( ), ,
:: inline-.
,
. ,
.

7.3
, , ,
. ,
, , ,
, .
, ,
, . - ,
#include. ,
, .

7.3.1
slist ,
, ,
. ent:
typedef void* ent;
ent , , .
slink:
class slink {
friend class slist;
friend class slist_iterator;
slink* next;
ent e;
slink(ent a, slink* p) { e=a; next=p;}
};
ent, slist:

138
class slist {
friend class slist_iterator;
slink* last;
// last->next -
public:
int insert(ent a); //
int append(ent a); //
ent get();
//
void clear();
//
slist()
{ last=0; }
slist(ent a) { last=new slink(a,0); last->next=last; }
~slist()
{ clear(); }
};
, ,
ent', . , slink'
slist', .

7.3.2
slist . -
, , , get() -
. #7.3.4. slist.
,
append() insert():
int slist::insert(ent a)
{
if (last)
last->next = new slink(a,last->next);
else {
last = new slink(a,0);
last->next = last;
}
return 0;
}
int slist::append(ent a)
{
if (last)
last = last->next = new slink(a,last->next);
else {
last = new slink(a,0);
last->next = last;
}
return 0;
}
ent slist::get()
{
if (last == 0) slist_handler("get fromempty list");
//
slink* f = last->next;
ent r f->e;
if (f == last)
last = 0;
else
last->next = f->next;
delete f;
return f;
}
, slist_handler ( #7.3.4).
, .
:
(*slist_handler)("get fromempty list");

139
slist::clear(), , :
void slist::clear()
{
slink* l = last;
if (l == 0) return;
do {
slink* ll = l;
l = l->next;
delete ll;
} while (l!=last);
}
slist , .
, slist, slink, slist_iterator ,
. , #6.8:
class slist_iterator {
slink* ce;
slist* cs;
public:
slist_iterator(slist& s) { cs = &s; ce = cs->last; }
ent operator()() {
// 0
// ,
ent ret = ce ? (ce=ce->next)->e : 0;
if (ce == cs->last) ce= 0;
return ret;
}
};

7.3.3
slist . ,
void*? , slist
, .
C++. ; -

struct name {
char* string;
// ...
};
, .
e slist', .
nlist, slist:
#include "slist.h"
#include "name.h"
struct nlist : slist {
void insert(name* a)
void append(name* a)
name* get()
nlist(name* a) : (a)
};

{ slist::insert(a); }
{ slist::append(a); }
{}
{}

slist ,
. nlist - , slist. ent
void*, name*,
(#2.3.4).
, :
struct classdef {

140

};

nlist friends;
nlist constructors;
nlist destructors;
nlist members;
nlist operators;
nlist virtuals;
// ...
void add_name(name*);
classdef();
~classdef();

:
void classdef::add_name(name* n)
{
if (n->is_friend()) {
if (find(&friends,n))
error("friend redeclared");
else if (find(&members,n))
error("friend redeclared as member");
else
friends.append(n);
}
if (n->is_operator()) operators.append(n);
// ...
}
is_iterator() is_friend() name. find() :
int find(nlist* ll, name* n)
{
slist_iterator ff(*(slist*)ll);
ent p;
while ( p=ff() ) if (p==n) return 1;
return 0;
}
, slist_iterator nlist. , nlist', #7.3.5. nlist , , :
void print_list(nlist* ll, char* list_name)
{
slist_iterator count(*(slist*)ll);
name* p;
int n = 0;
while ( count() ) n++;
cout << list_name << "\n" << n << "members\n";
slist_iterator print(*(slist*)ll);
while ( p=(name*)print() ) cout << p->string << "\n";
}

7.3.4
, ,
slist ( C++
):
[1] ;
[2] ;
[3] , slist;
[4] , .
, ,
.
.

141

, , .
,
slist.
, ,
( / istream
ostream; - #8.4.2). , , ,
,
. ,
. .
, , . ,
, , ,
. , .
, ,
, (#4.5),
. 3 4
( ), , .
, slist, ,
, , ,
, , , .
:
typedef void (*PFC)(char*); //
extern PFC slist_handler;
extern PFC set_slist_handler(PFC);
set_slist_hanlder() .
,
cerr, exit():
#include "slist.h"
#include
void default_error(char* s)
{
cerr << s << "\n";
exit(1);
}
, , :
PFC slist_handler = default_error;
PFC set_slist_handler(PFC handler);
{
PFC rr = slist_handler;
slist_handler = handler;
return rr;
}
, set_slist_hanlder() slist_hanlder().
.
, slist , ,
, . :
{
PFC old = set_slist_handler(my_handler);
// , slist
// my_handler
set_slist_handler(old); //
}
, slist_hanlder slist,
.

142

7.3.5
, (classdef*, int, char* ..)
, nlist: slist.
( ),
"". , C
(#4.7 #.11.1), .
.
, (generic) slist, gslist,
. :
#include "slist.h"
#ifndef GENERICH
#include
#endif
#ifndef , ,
. GENERICH .
name2(), ,
:
#define gslist(type) name2(type,gslist)
#define gslist_iterator(type) name2(type,gslist_iterator)
, , gslist() gslist_iterator():
#define gslistdeclare(type)
struct gslist(type) : slist {
int insert(type a)
{ return slist::insert( ent(a) ); }
int append(type a)
{ return slist::append( ent(a) ); }
type get() { return type( slist::get() ); }
gslist(type)() { }
gslist(type)(type a) : (ent(a)) { }
~gslist(type)() { clear(); }
};

\
\
\
\
\
\
\
\
\
\
\
\
struct gslist_iterator(type) : slist_iterator {
\
gslist_iterator(type)(gslist(type)& a)
\
: ( (slist&)s ) {}
\
type operator()()
\
{ return type( slist_iterator::operator()() ); } \
}
\ , .
, nlist,
:
#include "name.h"
typedef name* Pname;
declare(gslist,Pname); // gslist(Pname)
gslist(Pname) nl;
// gslist(Pname)
declare () . ,
gslistdeclare, . declare .
name*,
typedef.
, .
, ,
. gslist #7.6.2.

7.3.6

143

slist - .
. , , ,
. ,
. , :
#include "slist.h"
class iqueue : slist {
// sizeof(int)<=sizeof(void*)
public:
void put(int a) { slist::append((void*)a); }
int det()
{ return int(slist::get()); }
iqueue()
{}
};
:
( ), int, , iqueue.
. - , ,
:
#include "slist.h"
class stack : slist {
public:
slist::insert;
slist::get;
stack() {}
stack(ent a) : (a) {}
};
" ":
#include "stack.h"
class cp : stack {
public:
void push(char* a) { slist::insert(a); }
char* pop() { return (char*)slist::get(); }
nlist() {}
};

7.4
.
.

. ,
, - ,
, -.
,
.
. , slist, , ,
slink, . ,
, ,
. next ,
, slink. ,
olink next, olist,
olink. olist ,
olink. "o" , ,
olist:
struct olink {
olink* next;
};

144
olist slist. , olist
olink :
class olist {
olink* last;
public:
void insert(olink* p);
void append(olink* p);
olink* get();
// ...
};
olink name:
class name : public olink {
// ...
};
,
.
, olist, . , , olink'.
, olist.
:
void f()
{
olist ll;
name nn;
ll.insert(&nn);
name* pn = (name*)ll.get();
}

// &nn
//

: , olist :
class olist : public olist {
// ...
name* get() { return (name*)olist::get(); }
};
name olist. ,
, , . , shape
. , slist
olist, .
.

7.5
. ,
. .
. , ,
, . , .
, ,
,
. -. ,
.
, (
), ( ).

7.6

145

.
:
[1] : ,
; ;
[2] :
;
[3] : ,
, , .
(
).
,
, .
. ,
, .
, ,
.
- ,
.

7.6.1
C ( C++),
. ,
: C ( ,
, ..), ,
..
, , C ,
, C++ .
,
put_point() put_line(), point:
// screen.h
const XMAX=40, YMAX=24;
struct point {
int x,y;
point() {}
point(int a, int b) { x=a; y=b; }
};
overload put_point;
extern void put_point(int a, int b);
inline void put_point(point p) { put_point(p.x,p.y); }
overload put_line;
extern void put_line(int, int, int, int);
inline void put_line(point a, point b)
{ put_line(a.x,a.y,b.x,b.y); }
extern void screen_init();
extern void screen_refresh();
extern void screen_clear();
#include
put screen_init(),
screen_refresh(). ,
"" ("refresh")
. :
#include "screen.h"
#include
enum color { black='*', white=' ' };
char screen[XMAX][YNAX];
void screen_init()
{

146
for (int y=0; y=a || a<=b) y0 += dy, eps -= two_a;
}

:
void screen_clear() { screen_init(); }
void screen_refresh()
{
for (int y=YMAX-1; 0<=y; y--) {
for (int x=0; x

//
//
//

7.6.2
(shape). ,
( ) (,
), ,
, shape:
struct shape {
shape() { shape_list.append(this); }
virtual point north() { return point(0,0); }
virtual point south() { return point(0,0); }
virtual point east() { return point(0,0); }
virtual point neast() { return point(0,0); }
virtual point seast() { return point(0,0); }
virtual void draw() {};
virtual void move(int, int) {};
};

//
//
//
//
//
//
//

-
-

, move(),
draw(). , ,
( ).
, , .
. shape::shape()
shape_list. gslist, ,
, #7.3.5. :
typedef shape* sp;
declare(gslist,sp);
typedef gslist(sp) shape_lst;
typedef gslist_iterator(sp) sp_iterator;
shape_list :
shape_lst shape_list;
, .
, . , :
. :
class line : public shape {
/*
'w' 'e'
north() ``
''
*/
point w,e;
public:
point north()
{ return point((w.x+e.x)/2,e.ydraw();
screen_refresh();
}

147
, , (). , ,
south() north() :
void stack(shape* q, shape* p)
{
point n = p->north();
point s = q->south();
q->move(n.x-s.x,n.y-s.y+1);
}

// p q

, ,
, , ,
.
.

7.6.3
. my_shape (
), ,
. my_shape:
#include "shape.h"
class myshape : public rectangle {
line* l_eye;
//
line* r_eye;
//
line* mouth;
//
public:
myshape(point, point);
void draw();
void move(int, int);
};
- , my_shape:
myshape::myshape(point a, point b) : (a,b)
{
int ll = neast().x-swest().x+1;
int hh = neast().y-swest().y+1;
l_eye = new line(
point(swest().x+2,swest().y+hh*3/4),2);
r_eye = new line(
point(swest().x+ll-4,swest().y+hh*3/4),2);
mouth = new line(
point(swest().x+2,swest().y+hh/4),ll-4);
}
shape_refresh(),
my_shape, .
my_shape. .
, draw():
void myshape::draw()
{
rectangle::draw();
put_point(point(
(swest().x+neast().x)/2,(swest().y+neast().y)/2));
}
my_shape rectangle
l_eye, r_eye mouth ( , ):
void myshape::move()
{
rectangle::move();

148

l_eye->move(a,b);
r_eye->move(a,b);
mouth->move(a,b);

, , :
main()
{
shape* p1 = new rectangle(point(0,0),point(10,10));
shape* p2 = new line(point(0,15),17);
shape* p3 = new myshape(point(15,10),point(27,18));
shape_refresh();
p3->move(-10,-10);
stack(p2,p3);
stack(p1,p2);
shape_refresh();
return 0;
}
, shape_refresh() stack() ,
, (, , ) .
:
***********
*

***********
*****************
*************
*

* **

** *

*
*
*

*
*

*
*

* ********* *
*

*************

149

7.7
slist, ,
slink. slink -
, ,
.
, #5.5.6. slink
new delete slist,
.
this,
, this
,
. this, ,
. :
#include
struct base { base(); };
struct derived : base { derived(); }
base::base()
{
cout << "\tbase 1: this=" << int(this) <<
if (this == 0) this = (base*)27;
cout << "\tbase 2: this=" << int(this) <<
}
derived::derived()
{
cout << "\tderived 1: this=" << int(this)
this = (this == 0) ? (derived*)43 : this;
cout << "\tderived 2: this=" << int(this)
}
main()
{
cout << "base b;\n";
base b;
cout << "new base b;\n";
new base;
cout << "derived d;\n";
derived d;
cout << "new derived d;\n";
new derived;
cout << "at the end\n";
}

"\n";
"\n";

<< "\n";
<< "\n";


base b;

base 1:
base 2:
new base;
base 1:
base 2:
derived d;
derived
base 1:
base 2:
derived
new derived;
derived
base 1:
base 2:
derived
at the end

this=2147478307
this=2147478307
this=0
this=27
1: this=2147478306
this=2147478306
this=2147478306
1: this=2147478306
1: this=0
this=43
this=43
1: this=43

this, ,

150
. -
this, , this *1.
*1 , . , ( .) derived::derived() :
if (this == 0) this = (derived*)43;
, d base::base() .
, , . (. )

7.8
(*1)
class base {
public:
virtual void iam() { cout << "base\n"; }
};
base iam() (" "), .
iam().
base* iam() .
(*2) (#7.6.1) .
(*2) triangle () circle ().
(*2) , , ,
" " .
(*2) , line rectangle .
(*2) , .
(*2) ,
. ,
, .
(*2) .
(*4) , ( ).
X, X::X(X&), X::~X() X::operator=(X&).
(*5) , . : .
- , . task (- ).
task (
task::save() task::restore()), .
, task. , ,
.
(). ,
. task::delay(), "" .
task - ,
. . queue ().
, .
. , ?

151

C++ /. ;
.
/
, ,
, .
. ,
, .

8.1
/
. /
.
C++ , ,
. , /
, , , ,
. ,
/
/ .
C++ ,
, .
, / C++ C++
, .
/ .
/
. /,
UNIX, /
,
.

.


. :
put(cerr,"x = "); // cerr -
put(cerr,x);
put(cerr,"\n");
, put .
. . <<
" " .
:
cerr << "x = " << x << "\n";
cerr - . , x int 123,

x = 123
. , X complex
(1,2.4), cerr

152
x = 1,2.4)
, x <<,
<< .

8.2

,
.

8.2.1
ostream << (" ")
:
class ostream {
// ...
public:
ostream& operator<<(char*);
ostream& operator<<(int i) { return *this<

8.2.2
, ,
. <
(#6.2).
, , ,
, . , =
(), cout=a=b cout=(a=b).
< >, "" ""
, /
. , "<" ",",
:
cout < x , y , z;
.
<< >> , ,
"" "", << ,
. :
cout << "a*b+c=" << a*b+c << "\n";
, , ,
. :
cout << "a^b|c=" << (a^b|c) << "\n";
:
cout << "a<

8.2.3
<< ,
.
,

153

, . () ,
.
char*
char*
char*
char*
char*

oct(long, int =0);


dec(long, int =0);
hex(long, int =0);
chr(int, int =0);
str(char*, int =0);

//
//
//
//
//

, ;
(), . :
cout <<
<<
<<
<<

"dec(" << x
") = oct(" << oct(x,6)
") = hex(" << hex(x,4)
")";

x==15, :
dec(15) = oct(

17) = hex(

f);

:
char* form(char* format ...);
cout<

8.2.4
virtual. shape,
(#1.18):
class shape {
// ...
public:
// ...
virtual void draw(ostream& s); // "this" "s"
};
class circle : public shape {
int radius;
public:
// ...
void draw(ostream&);
};
, ,
, .
, << :
ostream& operator<<(ostream& s, shape* p)
{
p->draw(s);
return s;
}
next - #7.3.3, :
while ( p = next() ) cout << p;

8.3
. cin,
cout cerr.
.

154

8.3.1
ostream :
class ostream {
// ...
ostream(streambuf* s);
//
ostream(int fd);
//
ostream(int size, char* p); //
};
- . streambuf - , ;
#8.6, filebuf, streambuf . filebuf
streambuf.
cout cerr,
/, :
//
char cout_buf[BUFSIZE]
// "filebuf"
// UNIX' 1 ( )
filebuf cout_file(1,cout_buf,BUFSIZE);
// ostream,
ostream cout(&cout_file);
char cerr_buf[1];
// 0, ,
// UNIX' 2 ( )
filebuf cerr_file()2,cerr_buf,0;
ostream cerr(&cerr_file);
ostream #8.3.3 #8.5.

8.3.2
ostream
ostream::flush():
ostream::~ostream()
{
flush();
//
}
. :
cout.flush();

8.3.3
, ,
.
cin, cout cerr, ( )
. , , , ,
, :
#include
void error(char* s, char* s2)
{
cerr << s << " " << s2 << "\n";
exit(1);
}
main(int argc, char* argv[])
{
if (argc != 3) error(" ","");

155
filebuf f1;
if (f1.open(argv[1],input) == 0)
error(" ",argv[1]);
istream from(&f1);
filebuf f2;
if (f2.open(argv[2],output) == 0)
error(" ",argv[2]);
ostream to(&f2);
char ch;
while (from.get(ch)) to.put(ch);
if (!from.eof() !! to.bad())
error(" ","");

ostream ,
: (1) ( filebuf); (2)
( filebuf::open()); ,
, (3) ostream filebuf . .
:
enum open_mode { input, output };
filebuf::open() 0, .
, output, .
, (. #8.4.2).
.
, ,
, .
( ). , ; .
8 - 10.

8.3.4
. :
cout = cerr;
, .
, cin - (
. #3.1.6)

8.4
. istream, >> ("
") . operator>>
, .

8.4.1
istream :
class istream {
// ...
public:
istream& operator>>(char*);
istream& operator>>(char&);
istream& operator>>(short&);
istream& operator>>(int&);
istream& operator>>(long&);
istream& operator>>(float&);
istream& operator>>(double&);
// ...
};

//
//

156
:
istream& istream::operator>>(char& c);
{
//
int a;
// "a"
c = a;
}
C, isspase() ,
(, , , ).
get():
class istream {
// ...
istream& get(char& c);
istream& get(char* p, int n, int ='\n');
};

// char
//

, . istream::get(char)
; istream::get n , p.
(,
), . ,
. get n ,
, '\n' . ,
. :
cin.get(buf,256,'\t');
buf 256 , ('\t'), get.
, cin, '\t'.
,
:
int
int
int
int
int
int

isalpha(char)
isupper(char)
islower(char)
isdigit(char)
isxdigit(char)
isspase(char)

int iscntrl(char)
int
int
int
int
int

ispunct(char)
isalnum(char)
isprint(char)
isgraph(char)
isascii(char c)

// 'a'..'z' 'A'..'Z'
// 'A'..'Z'
// 'a'..'z'
// '0'..'9'
// '0'..'9' 'a'..'f' 'A'..'F'
// ' ' '\t'
//
//
// (ASCII 0..31 127)
// :
// isalpha() | isdigit()
// : ascii ' '..'-'
// isalpha() | isdigit() | ispunct()
{ return 0<=c &&c<=127; }

isascii() ,
. ,
(('a'<=c && c<='z') || ('A'<=c && c<='Z')) //
( EBCDIC
), , :
isalpha(c)

8.4.2
(istream ostream) ,

157

.
:
enum stream_state { _good, _eof, _fail, _bad };
_good _eof, . _good,
, .
, , _good,
. v, , v
( , v ,
istream ostream). _fail _bad
. _fail ,
. _bad .
:
switch (cin.rdstate()) {
case _good:
// cin
break;
case _eof:
//
break;
case _fail:
//
// ,
break;
case _bad:
// , cin
break;
}
z , << >>,
:
while (cin>>z) cout << z << "\n";
, z - ,
( , ) .
,
( , ) _good. ,
istream, cin>>z. ,
, .
(#6.3.2).
,
, , . ,
, . /
, C++ ( )
( )
/.

8.4.3 ,
, ,
, , .
:
istream& operator>>(istream& s, complex& a)
/*
complex; "f" float:
f
( f )
( f , f )
*/
{

158

double re = 0, im = 0;
char c = 0;
s >> c;
if (c == '(') {
s >> re >> c;
if (c == ',') s >> im >> c;
if (c != ')') s.clear(_bad);
}
else {
s.putback(c);
s >> re;
}
if (s) a = complex(re,im);
return s;

// state

, ,
. c , '('
, . ,
a , .
clear() (),
_good. _good istream::clear(),
ostream::clear().
. , , ,
( ), ,
. , , ,
.

8.4.4
, istream, ostream, :
class istream {
// ...
istream(streambuf* s, int sk =1, ostream* t =0);
istream(int size, char* p, int sk =1);
istream(int fd, int sk =1, ostream* t =0);
};
sk , . t ()
ostream, istream. , cin cout; , ,
, cin
cout.flush(); //
istream::tie() ( , tie(0)) ostream
istream. :
int y_or_n(ostream& to, istream& from)
/*
"to", "from"
*/
{
ostream* old = from.tie(&to);
for (;;) {
cout << " Y N: ";
char ch = 0;
if (!cin.get(ch)) return 0;
if (ch != '\n') { //
char ch2 = 0;
while (cin.get(ch2) && ch2 != '\n') ;
}
switch (ch) {
case 'Y':
case 'y':
case '\n':

159
from.tie(old);
// tie
return 1;
case 'N':
case 'n':
from.tie(old);
// tie
return 0;
default:
cout << ", : ";
}

( ),
. . y_or_n()
, .
istream::putback(char). "
" .

8.5
, /, ,
istream ostream. , ,
,
:
void word_per_line(char v[], int sz)
/*
"v" "sz"
*/
{
istream ist(sz,v); // istream v
char b2[MAX];
//
while (ist>>b2) cout << b2 << "\n";
}
.
ostream , :
char* p = new char[message_size];
ostream ost(message_size,p);
do_something(arguments,ost);
display(p);
, do_something, ost, ost ..
. , ost
, _fail. , , display
"" . ,
, ,
. , ost
- .

8.6
/ ,
. ,
ostream, , ,
ostream, . ,
(
ostream).
, ostream , . ,
, . ,
.

160

,
.
:
struct streambuf {
//
char* base;
//
char* pptr;
// char
char* qptr;
// char
char* eptr;
//
char alloc;
// , new
// :
// EOF 0
virtual int overflow(int c =EOF);
//
// EOF ,
// char
virtual int underflow();
int snextc()
// char
{
return (++qptr==pptr) ? underflow() : *qptr&0377;
}
// ...
int allocate()
//
streambuf() { /* ... */}
streambuf(char* p, int l) { /* ... */}
~streambuf() { /* ... */}
};
, , ,
( ) inline- .
overflow()
underflow(). :
struct filebuf : public streambuf {
int fd;
//
char opened;
//
int overflow(int c =EOF);
int underflow();
// ...
// :
// , 0,
// "this"
filebuf* open(char *name, open_mode om);
int close() { /* ... */ }
filebuf() { opened = 0; }
filebuf(int nfd) { /* ... */ }
filebuf(int nfd, char* p, int l) : (p,l) { /* ... */ }
~filebuf() { close(); }
};
int filebuf::underflow()
// fd
{
if (!opened || allocate()==EOF) return EOF;
int count = read(fd, base, eptr-base);
if (count < 1) return EOF;
qptr = base;
pptr = base + count;
return *qptr & 0377;
}

8.7
, /
, , . .
" " inline-,

161

- .
(, ..) .
, /,
.

8.8
(*1.5) ,
.
(*1.5) name_and_address (__). << >>.
name_and_address.
(*2) . y_or_n() #8.4.4. : , , , , ,
.. .
(*1.5) , (1) , (2) , (3)
, (4) , C++ , (5)
, (6) , (7) , (8)
, (9) .
(*4) / C () /
C++ ().
(*4) / C++ ()
/ C ().
(*4) C C++ , .
(*2) , [] .
(*3) 8, , [] , . : ,
[] " ",
, char .
(*2) 9, [] , .
(*3) , 10.
(*3.5) .
printf.
.
istream.
(*4) ( ) , .