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

Ñïàñèáî, ÷òî ñêà÷àëè êíèãó â áåñïëàòíîé ýëåêòðîííîé áèáëèîòåêå RoyalLib.

ru
Âñå êíèãè àâòîðà: http://royallib.ru/author/hill_myurrey.html
Ýòà æå êíèãà â äðóãèõ ôîðìàòàõ: http://royallib.ru/book/hill_myurrey/C.html
Ïðèÿòíîãî ÷òåíèÿ!

C++
Ìþððåé Õèëë

Ñ++ - ýòî óíèâåðñàëüíûé ÿçûê ïðîãðàììèðîâàíèÿ, çàäóìàííûé òàê, ÷òîáû ñäåëàòü ïðîãðàììèðîâ
Êëþ÷åâûì ïîíÿòèåì Ñ++ ÿâëÿåòñÿ êëàññ. Êëàññ - ýòî òèï, îïðåäåëÿåìûé ïîëüçîâàòåëåì. Êëàññû
Ñ++ è åãî ñòàíäàðòíûå áèáëèîòåêè ñïðîåêòèðîâàíû òàê, ÷òîáû îáåñïå÷èâàòü ïåðåíîñèìîñòü. Èì
Ýòà êíèãà ïðåäíàçíà÷åíà ãëàâíûì îáðàçîì äëÿ òîãî, ÷òîáû ïîìî÷ü ñåðüåçíûì ïðîãðàììèñòàì èç

Õèëë Ì., Ñòðàóñòðàï Á.

C++

Ïðåäèñëîâèå
ßçûê ôîðìèðóåò íàø ñïîñîá ìûøëåíèÿ è îïðåäåëÿåò, î ÷åì ìû ìîæåì ìûñëèòü.
    Á.Ë. Âîðô

Ñ++ ýòî óíèâåðñàëüíûé ÿçûê ïðîãðàììèðîâàíèÿ, çàäóìàííûé òàê, ÷òîáû ñäåëàòü ïðîãðàììèðîâàí

Áëàãîäàðíîñòè
Ñ++ íèêîãäà áû íå ñîçðåë áåç ïîñòîÿííîãî èñïîëüçîâàíèÿ, ïðåäëîæåíèé è êîíñòðóêòèâíîé êðèòèê
Êðîìå òîãî, â ðàçâèòèå Ñ++ âíåñëè ñâîé âêëàä ñîòíè ëþäåé, êîòîðûå ïðèñûëàëè ìíå ïðåäëîæåíèÿ
 èçäàíèè ýòîé êíèãè ìíå ïîìîãëè ìíîãèå ëþäè, â ÷àñòíîñòè, Äæîí Áåíòëè, Ëàóðà Èâñ, Áðàéýí Ê
Ìþððýé Õèëë, Íüþ Äæåðñè Áüÿðí Ñòðàóñòðàï

Çàìåòêè äëÿ ×èòàòåëÿ


«Î ìíîãîì,» ìîëâèë Ìîðæ,  «Ïðèøëà ïîðà ïîãîâîðèòü.»
    Ë. Êýððîë
 ýòîé ãëàâå ñîäåðæèòñÿ îáçîð êíèãè, ñïèñîê áèáëèîãðàôè÷åñêèõ ññûëîê è íåêîòîðûå çàìå÷àíèÿ

Ñòðóêòóðà Ýòîé Êíèãè


Ãëàâà 1 ýòî êîðîòêîå òóðíå ïî îñíîâíûì îñîáåííîñòÿì Ñ+ +, ïðåäíàçíà÷åííîå äëÿ òîãî, ÷òîáû
 Ãëàâàõ 2, 3 è 4 îïèñûâàþòñÿ ñðåäñòâà Ñ++, íå âõîäÿùèå â îïðåäåëåíèå íîâûõ òèïîâ: îñíîâíûå
 Ãëàâàõ 5, 6 è 7 îïèñûâàþòñÿ ñðåäñòâà Ñ++ ïî îïèñàíèþ íîâûõ òèïîâ, îñîáåííîñòè ÿçûêà, íå è
 Ãëàâå 8 ïðåäñòàâëåíû êëàññû ostream è istream, ïðåäîñòàâëÿåìûå ñòàíäàðòíîé áèáëèîòåêîé äë
È, íàêîíåö, â êíèãó âêëþ÷åíî ñïðàâî÷íîå ðóêîâîäñòâî ïî Ñ++.
Ññûëêè íà ðàçëè÷íûå ÷àñòè ýòîé êíèãè äàþòñÿ â ôîðìå #2.3.4 (Ãëàâà 2 ïîäðàçäåë 3.4). Ãëàâà ñ

Çàìå÷àíèÿ ïî Ðåàëèçàöèè
Âî âðåìÿ íàïèñàíèÿ ýòîé êíèãè âñå ðåàëèçàöèè Ñ++ èñïîëüçîâàëè âåðñèè åäèíñòâåííîãî èíòåðôåé
 * Ñ++ ìîæíî êóïèòü â AT amp;T, Software Sales and Marketing, PO Box 25000, Greensboro, NC
) èëè â âàøèõ ìåñòíûõ îðãàíèçàöèÿõ, îñóùåñòâëÿþùèõ ïðîäàæó Ñèñòåìû UNIX. (ïðèì. àâòîðà)

Óïðàæíåíèÿ
Óïðàæíåíèÿ íàõîäÿòñÿ â êîíöå ãëàâ. Âñå óïðàæíåíèÿ ãëàâíûì îáðàçîì òèïà íàïèøèòå-ïðîãðàììó.

Çàìå÷àíèÿ ïî Ïðîåêòó ßçûêà


Ñóùåñòâåííûì êðèòåðèåì ïðè ðàçðàáîòêå ÿçûêà áûëà ïðîñòîòà. Òàì, ãäå âîçíèêàë âûáîð ìåæäó óï

 Ñ++ íåò òèïîâ äàííûõ âûñîêîãî óðîâíÿ è íåò ïåðâè÷íûõ îïåðàöèé âûñîêîãî óðîâíÿ.  íåì íåò,
Èñêëþ÷àëèñü òå ÷åðòû, êîòîðûå ìîãëè áû ïîâëå÷ü äîïîëíèòåëüíûå ðàñõîäû ïàìÿòè èëè âðåìåíè âû
Ñ++ ïðîåêòèðîâàëñÿ äëÿ èñïîëüçîâàíèÿ â äîâîëüíî òðàäèöèîííîé ñðåäå êîìïèëÿöèè è âûïîëíåíèÿ,
Òèïû è ñðåäñòâà ñîêðûòèÿ äàííûõ â Ñ++ îïèðàþòñÿ íà ïðîâîäèìûé âî âðåìÿ êîìïèëÿöèè àíàëèç ïð

Èñòîðè÷åñêèå Çàìå÷àíèÿ
Áåçóñëîâíî, Ñ++ âîñõîäèò ãëàâíûì îáðàçîì ê C [7]. C ñîõðàíåí êàê ïîäìíîæåñòâî, ïîýòîìó ñäåë
Íàçâàíèå Ñ++ èçîáðåòåíèå ñîâñåì íåäàâíåå (ëåòà 1983-åãî). Áîëåå ðàííèå âåðñèè ÿçûêà èñïîë
Íàçâàíèå Ñ++ âûäóìàë Ðèê Ìàññèòòè. Íàçâàíèå óêàçûâàåò íà ýâîëþöèîííóþ ïðèðîäó ïåðåõîäà ê íå
Èçíà÷àëüíî Ñ++ áûë ðàçðàáîòàí, ÷òîáû àâòîðó è åãî äðóçüÿì íå ïðèõîäèëîñü ïðîãðàììèðîâàòü íà
 êà÷åñòâå áàçîâîãî ÿçûêà äëÿ Ñ++ áûë âûáðàí C, ïîòîìó ÷òî îí
1. ìíîãîöåëåâîé, ëàêîíè÷íûé è îòíîñèòåëüíî íèçêîãî óðîâíÿ,
2. îòâå÷àåò áîëüøèíñòâó çàäà÷ ñèñòåìíîãî ïðîãðàììèðîâàíèÿ,
3. èäåò âåçäå è íà âñåì è
4. ïðèãîäåí â ñðåäå ïðîãðàììèðîâàíèÿ UNIX.
 C åñòü ñâîè ñëîæíîñòè, íî â íàñïåõ ñïðîåêòèðîâàííîì ÿçûêå òîæå áûëè áû ñâîè, à ñëîæíîñòè
Ñ++ ñòàë èñïîëüçîâàòüñÿ øèðå, è ïî ìåðå òîãî, êàê âîçìîæíîñòè, ïðåäîñòàâëÿåìûå èì ïîìèìî âî
1. åñòü ìèëëèîíû ñòðîê íà C, êîòîðûå ìîãëè áû ïðèíåñòè ïîëüçó â Ñ++ ïðè óñëîâèè, ÷òî èõ íå
2. åñòü ñîòíè òûñÿ÷ ñòðîê áèáëèîòå÷íûõ ôóíêöèé è ñåðâèñíûõ ïðîãðàìì, íàïèñàííûõ íà C, êîòîð
3. åñòü äåñÿòêè òûñÿ÷ ïðîãðàììèñòîâ, êîòîðûå çíàþò C, è êîòîðûì, ïîýòîìó, íóæíî òîëüêî íàó÷
4. ïîñêîëüêó Ñ++ è C áóäóò èñïîëüçîâàòüñÿ íà îäíèõ è òåõ æå ñèñòåìàõ îäíèìè è òåìè æå ëþäüì
Ïîçäíåå áûëà ïðîâåäåíà ïðîâåðêà îïðåäåëåíèÿ Ñ++, ÷òîáû óäîñòîâåðèòüñÿ â òîì, ÷òî ëþáàÿ êîíñ
ßçûê C ñàì ýâîëþöèîíèðîâàë çà ïîñëåäíèå íåñêîëüêî ëåò, ÷àñòè÷íî ïîä âëèÿíèåì ðàçâèòèÿ Ñ++ (

Ýôôåêòèâíîñòü è Ñòðóêòóðà
Ñ++ áûë ðàçâèò èç ÿçûêà ïðîãðàììèðîâàíèÿ C è çà î÷åíü íåìíîãèìè èñêëþ÷åíèÿìè ñîõðàíÿåò C êà
 Ñ++ èñïîëüçóþòñÿ òå æå ïîñëåäîâàòåëüíîñòè âûçîâà è âîçâðàòà èç ôóíêöèé, ÷òî è â C.  òåõ
Îäíèì èç ïåðâîíà÷àëüíûõ ïðåäíàçíà÷åíèé C áûëî ïðèìåíåíèå åãî âìåñòî ïðîãðàììèðîâàíèÿ íà àññ
Îñîáîå âíèìàíèå, óäåëåííîå ïðè ðàçðàáîòêå Ñ++ ñòðóêòóðå, îòðàçèëîñü íà âîçðàñòàíèè ìàñøòàáà
Íå êàæäàÿ ÷àñòü ïðîãðàììû, îäíàêî, ìîæåò áûòü õîðîøî ñòðóêòóðèðîâàíà, íåçàâèñèìà îò àïïàðàò
 ýòîé êíèãå îñîáûé àêöåíò äåëàåòñÿ íà ìåòîäàõ ñîçäàíèÿ óíèâåðñàëüíûõ ñðåäñòâ, ïîëåçíûõ òèï
Ó êîãî-òî ìîæåò ïîÿâèòüñÿ ïîäîçðåíèå, ÷òî ñïåöèôèêàöèÿ ïðîãðàììû ñ ïîìîùüþ áîëåå ïîäðîáíîé

Ôèëîñîôñêèå Çàìå÷àíèÿ
ßçûê ïðîãðàììèðîâàíèÿ ñëóæèò äâóì ñâÿçàííûì ìåæäó ñîáîé öåëÿì: îí äàåò ïðîãðàììèñòó àïïàðàò
Ñâÿçü ìåæäó ÿçûêîì, íà êîòîðîì ìû äóìàåì/ïðîãðàììèðóåì, è çàäà÷àìè è ðåøåíèÿìè, êîòîðûå ìû
Ñèñòåìà òèïîâ äîëæíà áûòü îñîáåííî ïîëåçíà â íåòðèâèàëüíûõ çàäà÷àõ. Äåéñòâèòåëüíî, êîíöåïöè

Ðàçìûøëåíèÿ î Ïðîãðàììèðîâàíèè íà Ñ++


 èäåàëüíîì ñëó÷àå ïîäõîä ê ðàçðàáîòêå ïðîãðàììû äåëèòñÿ íà òðè ÷àñòè: âíà÷àëå ïîëó÷èòü ÿñí
 áîëüøèíñòâå ðàçðàáîòîê èìåþòñÿ ïîíÿòèÿ, êîòîðûå òðóäíî ïðåäñòàâèòü â ïðîãðàììå â âèäå îäí
Ïðîùå âñåãî èìåòü äåëî ñ òàêèìè ïîíÿòèÿìè, êîòîðûå èìåþò òðàäèöèîííóþ ìàòåìàòè÷åñêóþ ôîðìó:
Ïîíÿòèå íå ñóùåñòâóåò â ïóñòîòå, âñåãäà åñòü ãðóïïû ñâÿçàííûõ ìåæäó ñîáîé ïîíÿòèé. Îðãàíèçî
Îäíèì èç íàèáîëåå ìîùíûõ èíòåëëåêòóàëüíûõ ñðåäñòâ, ïîçâîëÿþùèõ ïðåîäîëåâàòü ñëîæíîñòü, ÿâëÿ

Åñòåñòâåííî, òàêàÿ îðãàíèçàöèÿ èìååò ñâîè îãðàíè÷åíèÿ.  ÷àñòíîñòè, ìíîæåñòâî ïîíÿòèé èíîãä
Èíîãäà äëÿ îðãàíèçàöèè ïîíÿòèé íåêîòîðîé ïðîãðàììû îêàçûâàåòñÿ íåïðèãîäåí äàæå àöèêëè÷åñêèé
Åñëè âû ìîæåòå îðãàíèçîâàòü ïîíÿòèÿ ïðîãðàììû òîëüêî â âèäå îáùåãî ãðàôà (íå äåðåâà èëè àöè
Íàïîìíþ, ÷òî áîëüøóþ ÷àñòü ïðîãðàììèðîâàíèÿ ìîæíî ëåãêî è î÷åâèäíî âûïîëíÿòü, èñïîëüçóÿ òîë
Âîïðîñ «Êàê ïèøóò õîðîøèå ïðîãðàììû íà Ñ++» î÷åíü ïîõîæ íà âîïðîñ «Êàê ïèøóò õîðîøóþ àíãëèé

Ïðàâèëà Ïðàâîé Ðóêè*


Çäåñü ïðèâîäèòñÿ íàáîð ïðàâèë, êîòîðûõ âàì õîðîøî áû ïðèäåðæèâàòüñÿ èçó÷àÿ Ñ++. Êîãäà âû ñò
1. Êîãäà âû ïðîãðàììèðóåòå, âû ñîçäàåòå êîíêðåòíîå ïðåäñòàâëåíèå èäåé âàøåãî ðåøåíèÿ íåêîòî
a) Åñëè âû ñ÷èòàåòå «ýòî» îòäåëüíûì ïîíÿòèåì, ñäåëàéòå åãî êëàññîì.
b) Åñëè âû ñ÷èòàåòå «ýòî» îòäåëüíûì îáúåêòîì, ñäåëàéòå åãî îáúåêòîì íåêîòîðîãî êëàññà.
c) Åñëè äâà êëàññà èìåþò îáùèì íå÷òî ñóùåñòâåííîå, ñäåëàéòå åãî áàçîâûì êëàññîì. Ïî÷òè âñå
2. Êîãäà âû îïðåäåëÿåòå êëàññ, êîòîðûé íå ðåàëèçóåò íåêîòîðûé ìàòåìàòè÷åñêèé îáúåêò, âðîäå
a) Íå èñïîëüçóéòå ãëîáàëüíûå äàííûå.
b) Íå èñïîëüçóéòå ãëîáàëüíûå ôóíêöèè (íå ÷ëåíû).
c) Íå èñïîëüçóéòå îòêðûòûå äàííûå-÷ëåíû.
d) Íå èñïîëüçóéòå äðóçåé, êðîìå êàê äëÿ òîãî, ÷òîáû èçáåæàòü [a], [b] èëè [c].
e) Íå îáðàùàéòåñü ê äàííûì-÷ëåíàì èëè äðóãèì îáúåêòàì íåïîñðåäñòâåííî.
f) Íå ïîìåùàéòå â êëàññ «ïîëå òèïà», èñïîëüçóéòå âèðòóàëüíûå ôóíêöèè.
g) Íå èñïîëüçóéòå inline-ôóíêöèè, êðîìå êàê ñðåäñòâî ñóùåñòâåííîé îïòèìèçàöèè.

Çàìå÷àíèÿ äëÿ Ïðîãðàììèñòîâ íà C


×åì ëó÷øå êòî-íèáóäü çíàåò C, òåì òðóäíåå îêàæåòñÿ èçáåæàòü ïèñàíèÿ íà Ñ++ â ñòèëå C, òåðÿÿ

Áèáëèîãðàôè÷åñêèå Ññûëêè
 òåêñòå ìàëî ïðÿìûõ ññûëîê íà ëèòåðàòóðó, íî çäåñü ïðèâåäåí êîðîòêèé ñïèñîê êíèã è ñòàòåé,
[1] A.V. Aho, J.E. Hopcroft, and J.D. Ulman: Data Structures and Algorithms. Add
ison-Wesley, Reading, Massachusetts. 1983.
[2] O-J. Dahl, B. Myrhaug, and K. Nygaard: SIMULA Common Base Language. Norwegia
n Computer Center S-22, Oslo, Norsay. 1970
[3] O-J. Dahl and C.A.R. Hoare: Hierarchical Program Construction in «Structured P
rogramming.» Academic Press, New York. 1972. pp 174-220.
[4] A. Goldberg and D. Robson: SMALLTALK-80 The Language and Its Implementation.
Addison-Wesley, Reading, Massachusetts. 1983.
[5] R.E. Griswold et.al. The Snobol4 Programming Language. Prentice-Hall, Englew
ood Cliffs, New Jersey. 1970.
[6] R.E. Griswold and M.T. Griswold: The ICON Programming Language. Prentice-Hal
l, Englewood Cliffs, New Jersey. 1983.
[7] Brian W. Kernighan and Dennis M. Ritchie: The C Programming Language. Prenti
ce-Hall, Englewood Cliffs, New Jersey. 1978. Ðóññêèé ïåðåâîä â: Á.Â. Êåðíèãàí, Ä. Ðèò÷è, À.
[8] George Orwell: 1984. Secker and Warburg, London. 1949. Ðóññêèé ïåðåâîä: Äæ. Îðóýëë. 198
[9] Martin Richards and Colin Whitby-Strevens: BCPL The Language and Its Compile
r. Cambridge University Press. 1980.
[10] L. Rosler (Chairman, ANSI X3J11 Language Subcommittee): Preliminary Draft P
roposed Standard The C Language. X3 Secretariat: Computer and Busineess Equipmen
t Manufacturers Association, 311 First Street, N.W, Suite 500, Washington, DC 20
001, USA.
[11] L.Rosler: The Evolution of C Past and Future. AT amp;T Bell Laboratories Te
chnical Journal. Vol.63 No.8 Part 2. October 1984. pp 1685-1700.
[12] Ravi Sethi: Uniform Syntax for Type Expressions and Declarations. Software
Practice amp; Experience, Vol 11 (1981), pp 623-628.
[13] Bjarne Stroustrup: Adding Classes to C: An Exercise in Language Evolution.
Software Practice amp; Experience, 13 (1981), pp 139-61.
[14] P.M. Woodward and S.G. Bond: Algol 68-R Users Guide. Her Majesty's Statione
ry Office, London. 1974.
[15] UNIX System V Release 2.0 User Reference Manual. AT amp;T Bell Laboratories
, Murray Hill, New Jersey. December 1983.
[16] UNIX Time-Sharing System: Programmer's Manual. Research Version, Eighth Edi
tion. AT amp;T Bell Laboratories, Murray Hill, New Jersey. February 1985.
[17] UNIX Programmer's Manual. 4.2 Berkeley Software Distribution University of
California, Berkeley, California. March 1984.

Ãëàâà 1 Òóðíå ïî Ñ++


Åäèíñòâåííûé ñïîñîá èçó÷àòü íîâûé ÿçûê ïðîãðàììèðîâàíèÿ ïèñàòü íà íåì ïðîãðàììû.
    Áðàéýí Êåðíèãàí

Ýòà ãëàâà ïðåäñòàâëÿåò ñîáîé êðàòêèé îáçîð îñíîâíûõ ÷åðò ÿçûêà ïðîãðàììèðîâàíèÿ Ñ++. Ñíà÷àë

1.1 Ââåäåíèå
Ýòî òóðíå ïðîâåäåò âàñ ÷åðåç ðÿä ïðîãðàìì è ÷àñòåé ïðîãðàìì íà Ñ++. Ê êîíöó ó âàñ äîëæíî ñë

1.1.1 Âûâîä
Ïðåæäå âñåãî, äàâàéòå íàïèøåì ïðîãðàììó, âûâîäÿùóþ ñòðîêó âûäà÷è:
#include «stream.h»
main() (* cout « «Hello, world\n ; *)
Ñòðîêà #include «stream.h» ñîîáùàåò êîìïèëÿòîðó, ÷òîáû îí âêëþ÷èë ñòàíäàðòíûå âîçìîæíîñòè ï
 * Ïðîãðàììèðóþùèì íà C «« èçâåñòíî êàê îïåðàöèÿ ñäâèãà âëåâî äëÿ öåëûõ. Òàêîå èñïîëüçîâàí
Îñòàëüíàÿ ÷àñòü ïðîãðàììû
main() (* ... *)

îïðåäåëÿåò ôóíêöèþ, íàçâàííóþ main. Êàæäàÿ ïðîãðàììà äîëæíà ñîäåðæàòü ôóíêöèþ ñ èìåíåì main

1.1.2 Êîìïèëÿöèÿ
Îòêóäà ïîÿâèëèñü âûõîäíîé ïîòîê cout è êîä, ðåàëèçóþùèé îïåðàöèþ âûâîäà ««? Äëÿ ïîëó÷åíèÿ â
Êîìàíäà êîìïèëÿöèè â Ñ++ îáû÷íî íàçûâàåòñÿ CC. Îíà èñïîëüçóåòñÿ òàê æå, êàê êîìàíäà cc äëÿ
$ CC hello.c $ a.out Hello,world $
a.out ýòî ïðèíèìàåìîå ïî óìîë÷àíèþ èìÿ èñïîëíÿåìîãî ðåçóëüòàòà êîìïèëÿöèè. Åñëè âû õîòèòå
$ CC hello.c -o hello $ hello Hello,world $

1.1.3 Ââîä
Ñëåäóþùàÿ (äîâîëüíî ìíîãîñëîâíàÿ) ïðîãðàììà ïðåäëàãàåò âàì ââåñòè ÷èñëî äþéìîâ. Ïîñëå òîãî,
#include «stream.h»
main() (* int inch = 0; // inch äþéì cout « inches ; cin » inch; cout « inch; cout ««
*2.54; cout «« « cm\n ; *)

Ïåðâàÿ ñòðîêà ôóíêöèè main() îïèñûâàåò öåëóþ ïåðåìåííóþ inch. Åå çíà÷åíèå ñ÷èòûâàåòñÿ ñ ïîì
$ a.out inches=12 12 in = 30.48 cm $
 ýòîì ïðèìåðå íà êàæäóþ êîìàíäó âûâîäà ïðèõîäèòñÿ îäèí îïåðàòîð. Ýòî ñëèøêîì äëèííî. Îïåðà
cout « inch «« " in = " «« inch*2.54 «« « cm\n ;
 ïîñëåäóþùèõ ðàçäåëàõ ââîä è âûâîä áóäóò îïèñàíû ãîðàçäî áîëåå ïîäðîáíî. Âñÿ ýòà ãëàâà ôàê

1.2 Êîììåíòàðèè
×àñòî áûâàåò ïîëåçíî âñòàâëÿòü â ïðîãðàììó òåêñò, êîòîðûé ïðåäíàçíà÷àåòñÿ â êà÷åñòâå êîììåí
Ñèìâîëû /* íà÷èíàþò êîììåíòàðèé, çàêàí÷èâàþùèéñÿ ñèìâîëàìè */. Âñÿ ýòà ïîñëåäîâàòåëüíîñòü ñ
Ñèìâîëû // íà÷èíàþò êîììåíòàðèé, êîòîðûé çàêàí÷èâàåòñÿ â êîíöå ñòðîêè, íà êîòîðîé îíè ïîÿâè

1.3 Òèïû è Îïèñàíèÿ


Êàæäîå èìÿ è êàæäîå âûðàæåíèå èìååò òèï, îïðåäåëÿþùèé îïåðàöèè, êîòîðûå ìîãóò íàä íèìè ïðîè
int inch;
îïðåäåëÿåò, ÷òî inch èìååò òèï int, òî åñòü, inch ÿâëÿåòñÿ öåëîé ïåðåìåííîé.
Îïèñàíèå ýòî îïåðàòîð, êîòîðûé ââîäèò èìÿ â ïðîãðàììå. Îïèñàíèå çàäàåò òèï ýòîãî èìåíè. Ò

stream.h, îáúåêò òèïà int ìîæåò òàêæå áûòü âòîðûì îïåðàíäîì ««, êîãäà ïåðâûé îïåðàíä ostrea
cout « inch «« " in = " «« inch*2.54 «« « cm\n ;
ïðàâèëüíî îáðàáàòûâàåò ÷åòûðå âõîäíûõ çíà÷åíèÿ ðàçëè÷íûì îáðàçîì. Ñòðîêè ïå÷àòàþòñÿ áóêâàëü
 Ñ++ åñòü íåñêîëüêî îñíîâíûõ òèïîâ è íåñêîëüêî ñïîñîáîâ ñîçäàâàòü íîâûå. Ïðîñòåéøèå âèäû ò

1.3.1 Îñíîâíûå Òèïû


Îñíîâíûå òèïû, íàèáîëåå íåïîñðåäñòâåííî îòâå÷àþùèå ñðåäñòâàì àïïàðàòíîãî îáåñïå÷åíèÿ, òàêèå
char short int long float double
Ïåðâûå ÷åòûðå òèïà èñïîëüçóþòñÿ äëÿ ïðåäñòàâëåíèÿ öåëûõ, ïîñëåäíèå äâà äëÿ ïðåäñòàâëåíèÿ
1=sizeof(char)«=sizeof(short) «= sizeof(int) «= sizeof(long) sizeof(float) «= sizeof(dou
ble)
 öåëîì, ïðåäïîëàãàòü ÷òî-ëèáî åùå îòíîñèòåëüíî îñíîâíûõ òèïîâ íåðàçóìíî.  ÷àñòíîñòè, òî,
Ê îñíîâíîìó òèïó ìîæíî ïðèìåíÿòü ïðèëàãàòåëüíîå const. Ýòî äàåò òèï, èìåþùèé òå æå ñâîéñòâà
const float pi = 3.14; const char plus = '+';
Ñèìâîë, çàêëþ÷åííûé â îäèíàðíûå êàâû÷êè, ÿâëÿåòñÿ ñèìâîëüíîé êîíñòàíòîé. Çàìåòüòå, ÷òî ÷àñò
Ê ëþáîé êîìáèíàöèè ýòèõ òèïîâ ìîãóò ïðèìåíÿòüñÿ àðèôìåòè÷åñêèå îïåðàöèè:
+ (ïëþñ, óíàðíûé è áèíàðíûé) (ìèíóñ, óíàðíûé è áèíàðíûé) * (óìíîæåíèå) / (äåëåíèå)
À òàêæå îïåðàöèè ñðàâíåíèÿ: == (ðàâíî) != (íå ðàâíî) « (ìåíüøå) » (áîëüøå) «= (ìåíüøå èëè ð
Çàìåòüòå, ÷òî öåëîå äåëåíèå äàåò öåëûé ðåçóëüòàò: 7/2 åñòü 3. Íàä öåëûìè ìîæåò âûïîëíÿòüñÿ
Ïðè ïðèñâàèâàíèè è àðèôìåòè÷åñêèõ îïåðàöèÿõ Ñ++ âûïîëíèò âñå îñìûñëåííûå ïðåîáðàçîâàíèÿ ìåæ
double d = 1; int i = 1; d = d + i; i = d + i;

1.3.2 Ïðîèçâîäíûå Òèïû


Âîò îïåðàöèè, ñîçäàþùèå èç îñíîâíûõ òèïîâ íîâûå òèïû:
* óêàçàòåëü íà *const êîíñòàíòíûé óêàçàòåëü íà amp; ññûëêà íà [] âåêòîð* () ôóíêöèÿ, âîçâðà
 * îäíîìåðíûé ìàññèâ. Ýòî ïðèíÿòûé òåðìèí (íàïðèìåð, âåêòîðà ïðåðûâàíèé), è ìû ñî÷ëè, ÷òî
Íàïðèìåð:
char* p // óêàçàòåëü íà ñèìâîë char *const q // êîíñòàíòíûé óêàçàòåëü íà ñèìâîë char v[10]
Âñå âåêòîðà â êà÷åñòâå íèæíåé ãðàíèöû èíäåêñà èìåþò íîëü, ïîýòîìó â v äåñÿòü ýëåìåíòîâ: v[0
char c; // ... p = amp;c; // p óêàçûâàåò íà c
Óíàðíîå amp; ÿâëÿåòñÿ îïåðàöèåé âçÿòèÿ àäðåñà.

1.4 Âûðàæåíèÿ è Îïåðàòîðû


 Ñ++ èìååòñÿ áîãàòûé íàáîð îïåðàöèé, ñ ïîìîùüþ êîòîðûõ â âûðàæåíèÿõ îáðàçóþòñÿ íîâûå çíà÷å

1.4.1 Âûðàæåíèÿ
 Ñ++ èìååòñÿ áîëüøîå ÷èñëî îïåðàöèé, è îíè áóäóò îáúÿñíÿòüñÿ òàì, ãäå (è åñëè) ýòî ïîòðåáó
~ (äîïîëíåíèå) amp; (È) ^ (èñêëþ÷àþùåå ÈËÈ) ! (âêëþ÷àþùåå ÈËÈ) « (ëîãè÷åñêèé ñäâèã âëåâî)
ïðèìåíÿþòñÿ ê öåëûì, è ÷òî íåò îòäåëüíîãî òèïà äàííûõ äëÿ ëîãè÷åñêèõ äåéñòâèé.
Ñìûñë îïåðàöèè çàâèñèò îò ÷èñëà îïåðàíäîâ. Óíàðíîå amp; ÿâëÿåòñÿ îïåðàöèåé âçÿòèÿ àäðåñà, à
 Ñ++ åñòü îïåðàöèÿ ïðèñâàèâàíèÿ =, à íå îïåðàòîð ïðèñâàèâàíèÿ, êàê â íåêîòîðûõ ÿçûêàõ. Òàê
 áîëüøèíñòâå ïðîãðàìì íà Ñ++ øèðîêî ïðèìåíÿþòñÿ óêàçàòåëè. Óíàðíàÿ îïåðàöèÿ * ðàçûìåíîâûâà
 * àíãë. dereference ïîëó÷èòü çíà÷åíèå îáúåêòà, íà êîòîðûé óêàçûâàåò äàííûé óêàçàòåëü. (

1.4.2 Îïåðàòîðû Âûðàæåíèÿ


Ñàìûé îáû÷íûé âèä îïåðàòîðà âûðàæåíèå;. Îí ñîñòîèò èç âûðàæåíèÿ, çà êîòîðûì ñëåäóåò òî÷êà
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
Ïðîãðàììà â ñëåäóþùåì ïðèìåðå îñóùåñòâëÿåò ïðåîáðàçîâàíèå äþéìîâ â ñàíòèìåòðû è ñàíòèìåòðîâ
#include «stream.h»
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 ñàíòèì
; *) else in = cm = 0;
cout « in «« " in = " «« cm «« « cm\n ; *)
Çàìåòüòå, ÷òî óñëîâèå â îïåðàòîðå if äîëæíî áûòü çàêëþ÷åíî â êðóãëûå ñêîáêè.

1.4.6 Îïåðàòîðû switch


Îïåðàòîð switch ïðîèçâîäèò ñîïîñòàâëåíèå çíà÷åíèÿ ñ ìíîæåñòâîì êîíñòàíò. Ïðîâåðêè â ïðåäûäó
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 äîëæíû áûòü ðàçëè÷íûìè, è åñëè ïðîâåðÿåìîå çíà÷åíèå íå ñ

1.4.7 Îïåðàòîð while


Ðàññìîòðèì êîïèðîâàíèå ñòðîêè, êîãäà çàäàíû óêàçàòåëü p íà åå ïåðâûé ñèìâîë è óêàçàòåëü q í
while (p != 0) (* *q = *p; // ñêîïèðîâàòü ñèìâîë q = q+1; p = p+1; *) *q = 0; // çàâåðøàþùè
Ñëåäóþùåå ïîñëå while óñëîâèå äîëæíî áûòü çàêëþ÷åíî â êðóãëûå ñêîáêè. Óñëîâèå âû÷èñëÿåòñÿ,
Ýòîò ïðèìåð ñëèøêîì ïðîñòðàíåí. Ìîæíî èñïîëüçîâàòü îïåðàöèþ ++ äëÿ íåïîñðåäñòâåííîãî óêàçàí
while (*p) *q++ = *p++; *q = 0;
ãäå êîíñòðóêöèÿ *p++ îçíà÷àåò: «âçÿòü ñèìâîë, íà êîòîðûé óêàçûâàåò p, çàòåì óâåëè÷èòü p.»
Ïðèìåð ìîæíî åùå óïðîñòèòü, òàê êàê óêàçàòåëü p ðàçûìåíîâûâàåòñÿ äâàæäû çà êàæäûé öèêë. Êîï
while (*q++ = *p++) ;
Çäåñü áåðåòñÿ ñèìâîë, íà êîòîðûé óêàçûâàåò p, p óâåëè÷èâàåòñÿ, ýòîò ñèìâîë êîïèðóåòñÿ òóäà,
 * â îðèãèíàëå expression-oriented (expression âûðàçèòåëüíîñòü è âûðàæåíèå). (ïðèì. ïåðå

1.4.8 Îïåðàòîð for


Ðàññìîòðèì êîïèðîâàíèå äåñÿòè ýëåìåíòîâ îäíîãî âåêòîðà â äðóãîé:
for (int i=0; i«10; i++) q[i]=p[i];

Ýòî ýêâèâàëåíòíî int i = 0; while (i«10) (* q[i] = p[i]; i++; *) íî áîëåå óäîáî÷èòàåìî, ïîñ
for (i=0; i«10; i++) q[i]=p[i];
òîæå ýêâèâàëåíòíî ïðåäûäóùåé çàïèñè ïðè óñëîâèè, ÷òî i ñîîòâåòñòâóþùèì îáðàçîì îïèñàíî ðàíü

1.4.9 Îïèñàíèÿ
Îïèñàíèå ýòî îïåðàòîð, ââîäÿùèé èìÿ â ïðîãðàììå. Îíî ìîæåò òàêæå èíèöèàëèçèðîâàòü îáúåêò
for (int i = 1; i«MAX; i++) (* int t = v[i-1]; v[i-1] = v[i]; v[i] = t; *)
Ïðè êàæäîì âûïîëíåíèè îïåðàòîðà for i áóäåò èíèöèàëèçèðîâàòüñÿ îäèí ðàç, à t MAX-1 ðàç.

1.5 Ôóíêöèè
Ôóíêöèÿ ýòî èìåíîâàííàÿ ÷àñòü ïðîãðàììû, ê êîòîðîé ìîæíî îáðàùàòüñÿ èç äðóãèõ ÷àñòåé ïðîã
extern float pow(float, int); //pow() îïðåäåëåíà â äðóãîì ìåñòå
main() (* for (int i=0; i«10; i++) cout « pow(2,i) «« «\n ; *)
Ïåðâàÿ ñòðîêà ôóíêöèè åå îïèñàíèå, óêàçûâàþùåå, ÷òî pow ôóíêöèÿ, ïîëó÷àþùàÿ ïàðàìåòðû ò
Ïðè âûçîâå ôóíêöèè òèï êàæäîãî ïàðàìåòðà ñîïîñòàâëÿåòñÿ ñ îæèäàåìûì òèïîì òî÷íî òàê æå, êàê

float pow(float x, int n) (* if (n « 0) error( sorry, negative exponent to pow() ); //


èçâèíèòå, îòðèöàòåëüíûé ïîêàçàòåëü äëÿ pow() switch (n) (* case 0: return 1; case 1: retur
Ðàçíûå ôóíêöèè, îáû÷íî èìåþò ðàçíûå èìåíà, íî ôóíêöèÿì, âûïîëíÿþùèì ñõîäíûå äåéñòâèÿ íàä îá
overload pow; int pow(int, int); 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 Ñòðóêòóðà ïðîãðàììû


Ïðîãðàììà íà Ñ++ îáû÷íî ñîñòîèò èç áîëüøîãî ÷èñëà èñõîäíûõ ôàéëîâ, êàæäûé èç êîòîðûõ ñîäåðæ
extern double sqrt(double); extern instream cin;
Ñàìûé îáû÷íûé ñïîñîá îáåñïå÷èòü ñîãëàñîâàííîñòü èñõîäíûõ ôàéëîâ ýòî ïîìåñòèòü òàêèå îïèñà
#include «math.h» //... x = sqrt(4);
Ïîñêîëüêó îáû÷íûå çàãîëîâî÷íûå ôàéëû âêëþ÷àþòñÿ âî ìíîãèå èñõîäíûå ôàéëû, îíè íå ñîäåðæàò î
 êîìàíäå âêëþ÷åíèÿ include èìÿ ôàéëà, çàêëþ÷åííîå â óãëîâûå ñêîáêè, íàïðèìåð «math.h», îòí
#include «math1.h» #include «/usr/bs/math2.h»
âêëþ÷èò math1.h èç òåêóùåãî ïîëüçîâàòåëüñêîãî êàòàëîãà, à math2.h èç êàòàëîãà /usr/bs.
Çäåñü ïðèâîäèòñÿ î÷åíü ìàëåíüêèé çàêîí÷åííûé ïðèìåð ïðîãðàììû, â êîòîðîì ñòðîêà îïðåäåëÿåòñ
// header.h
extern char* prog_name; extern void f();
 ôàéëå main.c íàõîäèòñÿ ãëàâíàÿ ïðîãðàììà:
// main.c
#include «header.h» char* prog_name = «äóðàöêèé, íî ïîëíûé»; main() (* f(); *)
à ôàéë f.c ïå÷àòàåò ñòðîêó:
// f.c
#include «stream.h» #include «header.h» void f() (* cout « prog_name «« «\n ; *)
Ñêîìïèëèðîâàòü è çàïóñòèòü ïðîãðàììó âû ìîæåòå íàïðèìåð òàê:
$ CC main.c f.c -o silly $ silly äóðàöêèé, íî ïîëíûé $

1.7 Êëàññû
Äàâàéòå ïîñìîòðèì, êàê ìû ìîãëè áû îïðåäåëèòü òèï ïîòîêà âûâîäà ostream. ×òîáû óïðîñòèòü çà
Ïîæàëóéñòà, íå èñïûòûâàéòå ïðèìåðû, îïðåäåëÿþùèå ostream â ýòîì è ïîñëåäóþùèõ ðàçäåëàõ. Ïîê
Îïðåäåëåíèå òèïà, îïðåäåëÿåìîãî ïîëüçîâàòåëåì (êîòîðûé â Ñ++ íàçûâàåòñÿ class, ò.å. êëàññ),
class ostream (* streambuf* buf; int state; public: void put(char*); void put(lo
ng); void put(double); *)
Îïèñàíèÿ ïîñëå ìåòêè public: çàäàþò èíòåðôåéñ: ïîëüçîâàòåëü ìîæåò îáðàùàòüñÿ òîëüêî ê òðåì
class îïðåäåëÿåò òèï, à íå îáúåêò äàííûõ, ïîýòîìó ÷òîáû èñïîëüçîâàòü ostream, ìû äîëæíû îäè
ostream my_out;
Ñ÷èòàÿ, ÷òî my_out áûë ñîîòâåòñòâóþùèì îáðàçîì ïðîèíèöèàëèçèðîâàí (êàê, îáúÿñíÿåòñÿ â #1.10
my_out.put(«Hello, world\n»);
Ñ ïîìîùüþ îïåðàöèè òî÷êà âûáèðàåòñÿ ÷ëåí êëàññà äëÿ äàííîãî îáúåêòà ýòîãî êëàññà. Çäåñü äëÿ
Ôóíêöèÿ ìîæåò îïðåäåëÿòüñÿ òàê:
void ostream::put(char* p) (* while (*p) buf.sputc(*p++); *)
ãäå sputc() ôóíêöèÿ, êîòîðàÿ ïîìåùàåò ñèìâîë â streambuf. Ïðåôèêñ ostream íåîáõîäèì, ÷òîá
Äëÿ îáðàùåíèÿ ê ôóíêöèè ÷ëåíó äîëæåí áûòü óêàçàí îáúåêò êëàññà.  ôóíêöèè ÷ëåíå ìîæíî ññûëà
void ostream::put(char* p) (* while (*p) this-»buf.sputc(*p++); *) Îïåðàöèÿ -» ïðèìåíÿåòñÿ

1.8 Ïåðåãðóçêà îïåðàöèé


Íàñòîÿùèé êëàññ ostream îïðåäåëÿåò îïåðàöèþ ««, ÷òîáû ñäåëàòü óäîáíûì âûâîä íåñêîëüêèõ îáúå
×òîáû îïðåäåëèòü @, ãäå @ íåêîòîðàÿ îïåðàöèÿ ÿçûêà Ñ++, äëÿ êàæäîãî îïðåäåëÿåìîãî ïîëüçîâ
class ostream (* //... ostream operator««(char*); *);
ostream ostream::operator««(char* p) (* while (*p) buf.sputc(*p++); return *this; *)
îïðåäåëÿåò îïåðàöèþ «« êàê ÷ëåí êëàññà ostream, ïîýòîìó s««p èíòåðïðåòèðóåòñÿ êàê s.operato
Òî, ÷òî â êà÷åñòâå âîçâðàùàåìîãî çíà÷åíèÿ âîçâðàùàåòñÿ ostream, ïîçâîëÿåò ïðèìåíÿòü «« ê ðå
Ñ ïîìîùüþ ìíîæåñòâà îïåðàöèé, çàäàííûõ êàê îòêðûòûå ÷ëåíû êëàññà ostream, âû ìîæåòå òåïåðü
ostream operator««(ostream s, complex z) // ó complex äâå ÷àñòè: äåéñòâèòåëüíàÿ real è ìíèì
'; *)
Ïîñêîëüêó operator««(ostream,complex) íå ÿâëÿåòñÿ ôóíêöèåé ÷ëåíîì, äëÿ áèíàðíîñòè íåîáõîäèì

1.9 Ññûëêè
Ê ñîæàëåíèþ, ïîñëåäíÿÿ âåðñèÿ ostream ñîäåðæèò ñåðüåçíóþ îøèáêó è ê òîìó æå î÷åíü íåýôôåêòè
Ýòî ìîæíî ñäåëàòü ñ ïîìîùüþ ññûëîê. Ññûëêà äåéñòâóåò êàê èìÿ äëÿ îáúåêòà. T amp; îçíà÷àåò ñ
ostream amp; s1 = my_out; ostream amp; s2 = cout;
Òåïåðü ìîæíî èñïîëüçîâàòü ññûëêó s1 è my_out îäèíàêîâî, è îíè áóäóò èìåòü îäèíàêîâûå çíà÷åí
s1 = s2;
êîïèðóåò îáúåêò, íà êîòîðûé ññûëàåòñÿ s2 (òî åñòü, cout), â îáúåêò, íà êîòîðûé ññûëàåòñÿ s1
s1.put(«íå íàäî èñïîëüçîâàòü -»»);
à åñëè ïðèìåíèòü îïåðàöèþ âçÿòèÿ àäðåñà, òî âû ïîëó÷èòå àäðåñ îáúåêòà, íà êîòîðûé ññûëàåòñÿ
amp;s1 == amp;my_out
Ïåðâàÿ î÷åâèäíàÿ ïîëüçà îò ññûëîê ñîñòîèò â òîì, ÷òîáû îáåñïå÷èòü ïåðåäà÷ó àäðåñà îáúåêòà,
ostream amp; operator««(ostream amp; s, complex z) (* return s «« "(" «« z.real «« "," «« z
*)
Äîñòàòî÷íî èíòåðåñíî, ÷òî òåëî ôóíêöèè îñòàëîñü áåç èçìåíåíèé, íî åñëè âû áóäåòå îñóùåñòâëÿ
Ññûëêè òàêæå ñóùåñòâåííû äëÿ îïðåäåëåíèÿ ïîòîêà ââîäà, ïîñêîëüêó îïåðàöèÿ ââîäà ïîëó÷àåò â
class istream (* //... int state; public: istream amp; operator»»(char amp;); istrea
m amp; operator»»(char*); istream amp; operator»»(int amp;); istream amp; operator»»(long a
p;); //... *);
Çàìåòüòå, ÷òî äëÿ ÷òåíèÿ long è int èñïîëüçóþòñÿ ðàçíûå ôóíêöèè, òîãäà êàê äëÿ èõ ïå÷àòè òð

1.10 Êîíñòðóêòîðû
Îïðåäåëåíèå ostream êàê êëàññà ñäåëàëî ÷ëåíû äàííûå çàðûòûìè. Òîëüêî ôóíêöèÿ ÷ëåí èìååò äîñ
class ostream (* //... ostream(streambuf*); ostream(int size, char* s); *);
Çäåñü çàäàíî äâà êîíñòðóêòîðà. Îäèí ïîëó÷àåò âûøåóïîìÿíóòûé streambuf äëÿ ðåàëüíîãî âûâîäà,
ostream my_out( amp;some_stream_buffer); char xx[256]; ostream xx_stream(256,xx)
;
Îïèñàíèå my_out íå òîëüêî çàäàåò ñîîòâåòñòâóþùèé îáúåì ïàìÿòè ãäå-òî â äðóãîì ìåñòå, îíî òà

1.11 Âåêòîðà
Âñòðîåííîå â Ñ++ ïîíÿòèå âåêòîðà áûëî ðàçðàáîòàíî òàê, ÷òîáû îáåñïå÷èòü ìàêñèìàëüíóþ ýôôåêò
Èäåÿ ñîñòîèò â òîì, ÷òîáû êëàññ ñàì áûë ñòðóêòóðîé ôèêñèðîâàííîãî ðàçìåðà, óïðàâëÿþùåé äîñò
vector::vector(int s) (* if (s«=0) error( bad vector size ); // ïëîõîé ðàçìåð âåêòîðà sz =
Òåïåðü âû ìîæåòå îïèñûâàòü âåêòîðà òèïà vector ïî÷òè ñòîëü æå ýëåãàíòíî, êàê è âåêòîðà, âñò
vector v1(100); vector v2(nelem*2-4);
Îïåðàöèþ äîñòóïà ìîæíî îïðåäåëèòü êàê
int amp; vector::operator[](int i) (* if(i«0 !! sz =i) error(«vector index out of rang
e ); // èíäåêñ âûõîäèò çà ãðàíèöû âåêòîðà return v[i]; *)
Îïåðàöèÿ !! (ÈËÈÈËÈ) ýòî ëîãè÷åñêàÿ îïåðàöèÿ ÈËÈ. Åå ïðàâûé îïåðàíä âû÷èñëÿåòñÿ òîëüêî òî
v1[x] = v2[y];
Ôóíêöèÿ ñî ñòðàííûì èìåíåì ~vector ýòî äåñòðóêòîð, òî åñòü ôóíêöèÿ, îïèñàííàÿ äëÿ òîãî, ÷
vector::~vector() (* delete v; *)
òî îí áóäåò, ñ ïîìîùüþ îïåðàöèè delete, îñâîáîæäàòü ïðîñòðàíñòâî, âûäåëåííîå êîíñòðóêòîðîì,
1.12 Inline-ïîäñòàíîâêà
Åñëè ÷àñòî ïîâòîðÿåòñÿ îáðàùåíèå ê î÷åíü ìàëåíüêîé ôóíêöèè, òî âû ìîæåòå íà÷àòü áåñïîêîèòüñ
vector s(100); //... i = s.size(); x = elem(i-1);
ïîðîæäàåò êîä, ýêâèâàëåíòíûé
//... i = 100; x = s.v[i-1];
Ñ++ êîìïèëÿòîð îáû÷íî äîñòàòî÷íî ðàçóìåí, ÷òîáû ãåíåðèðîâàòü íàñòîëüêî õîðîøèé êîä, íàñêîëü
Âû ìîæåòå óêàçàòü, ÷òî âû õîòèòå, ÷òîáû ôóíêöèÿ áûëà inline-ïîäñòàâëÿåìîé, ïîñòàâèâ êëþ÷åâî
Ïðè õîðîøåì èñïîëüçîâàíèè inline-ôóíêöèè ðåçêî ïîâûøàþò ñêîðîñòü âûïîëíåíèÿ è óìåíüøàþò ðàç

1.13 Ïðîèçâîäíûå êëàññû


Òåïåðü äàâàéòå îïðåäåëèì âåêòîð, äëÿ êîòîðîãî ïîëüçîâàòåëü ìîæåò çàäàâàòü ãðàíèöû èçìåíåíèÿ
class vec: public vector (* int low, high; public: vec(int,int);

int amp; elem(int); int amp; operator[](int); *);


Îïðåäåëåíèå vec êàê :public vector
îçíà÷àåò, â ïåðâóþ î÷åðåäü, ÷òî vec ýòî vector. Òî åñòü, òèï vec èìååò (íàñëåäóåò) âñå ñâ
Îïåðàöèÿ ðàçðåøåíèÿ îáëàñòè âèäèìîñòè :: èñïîëüçóåòñÿ äëÿ òîãî, ÷òîáû íå áûëî áåñêîíå÷íîé ð
Êîíñòðóêòîð ìîæíî íàïèñàòü òàê:
vec::vec(int lb, int hb) : (hb-lb+1) (* if (hb-lb«0) hb = lb; low = lb; high = hb;
*)
Çàïèñü: (hb-lb+1) èñïîëüçóåòñÿ äëÿ îïðåäåëåíèÿ ñïèñêà ïàðàìåòðîâ êîíñòðóêòîðà áàçîâîãî êëàñ
#include «streams.h»
void error(char* p) (* cerr « p «« «\n ; // cerr âûõîäíîé ïîòîê ñîîáùåíèé îá îøèáêàõ exi
void vector::set_size(int) (* /* ïóñòûøêà */ *)
int amp; vec::operator[](int i) (* if (i«low !! high i) error(«vec index out of range );
// èíäåêñ vec çà ãðàíèöàìè return elem(i); *)
main() (* vector a(10); for (int i=0; i«a.size(); i++) (* a[i] = i; cout a[i] «« " "; *
) cout «« «\n ; vec b(10,19); for (i=0; i«b.size(); i++) b[i+10] = a[i]; for (i=0; i«b.size
); i++) cout «« b[i+10] «« " "; cout «« «\n ; *)
Îí âûäàåò 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
Ýòî íàïðàâëåíèå ðàçâèòèÿ âåêòîðíîãî òèïà ìîæíî ðàçðàáàòûâàòü äàëüøå. Äîâîëüíî ïðîñòî ñäåëàò
Òàê êëàññ óïðàâëÿåò äîñòóïîì ê íåêîòîðûì äàííûì. Ïîñêîëüêó âåñü äîñòóï îñóùåñòâëÿåòñÿ ÷åðåç

1.14 Åùå îá îïåðàöèÿõ


Äðóãîå íàïðàâëåíèå ðàçâèòèÿ ñíàáäèòü âåêòîðà îïåðàöèÿìè:
class Vec : public vector (* public: Vec(int s) : (s) (**) Vec(Vec amp;); ~Vec()
(**) void operator=(Vec amp;); void operator*=(Vec amp;); void operator*=(int);
//... *);
Îáðàòèòå âíèìàíèå íà ñïîñîá îïðåäåëåíèÿ êîíñòðóêòîðà ïðîèçâîäíîãî êëàññà, Vec::Vec(), êîãäà
void Vec::operator=(Vec amp; a) (* int s = size(); if (s!=a.size()) error(«bad vec
tor size for =»); // ïëîõîé ðàçìåð âåêòîðà äëÿ = for (int i = 0; i«s; i++) elem(i) = a.elem
Ïðèñâàèâàíèå îáúåêòîâ êëàññà Vec òåïåðü äåéñòâèòåëüíî êîïèðóåò ýëåìåíòû, â òî âðåìÿ êàê ïðè

vector ïðîñòî êîïèðóåò ñòðóêòóðó, óïðàâëÿþùóþ äîñòóïîì ê ýëìåíòàì. Ïîñëåäíåå, îäíàêî, ïðîèñ
Vec operator+(Vec amp; a,Vec amp;b) (* int s = a.size(); if (s != b.size()) erro
r(«bad vector size for +»); // ïëîõîé ðàçìåð âåêòîðà äëÿ + Vec sum(s); for (int i=0; i«s; i
; return sum; *)
Âîò ïðèìåð íåáîëüøîé ïðîãðàììû, êîòîðóþ ìîæíî âûïîëíèòü, åñëè ñêîìïèëèðîâàòü åå âìåñòå ñ ðà
#include «stream.h»
void error(char* p) (* cerr « p «« «\n ; exit(1); *)
void vector::set_size(int) (* /*...*/ *)
int amp; vec::operator[](int i) (* /*...*/ *)
main() (* Vec a(10); Vec b(10); for (int i=0; i«a.size(); i++) a[i] = i; b = a; Ve
c c = a+b; for (i=0; i c.size(); i++) cout «« c[i] «« «\n ; *)

1.15 Äðóçüÿ (friend)


Ôóíêöèÿ operator+() íå âîçäåéñòâóåò íåïîñðåäñòâåííî íà ïðåäñòàâëåíèå âåêòîðà. Äåéñòâèòåëüíî
class Vec; // Vec èìÿ êëàññà class vector (* friend Vec operator+(Vec, Vec); //... *);
Òî âû ìîæåòå íàïèñàòü Vec operator+(Vec a, Vec b) (* int s = a.size(); if (s != b.size()) e
; // ïëîõîé ðàçìåð âåêòîðà äëÿ + Vec amp; sum = *new Vec(s); int* sp = sum.v; int* ap = a.v
*ap++ + *bp++; return sum; *)
Îäíèì èç îñîáåííî ïîëåçíûõ àñïåêòîâ ìåõàíèçìà friend ÿâëÿåòñÿ òî, ÷òî ôóíêöèÿ ìîæåò áûòü äð
1.16 Îáîáùåííûå Âåêòîðà
«Ïîêà âñå õîðîøî,» ìîæåòå ñêàçàòü âû,  «íî ÿ õî÷ó, ÷òîáû îäèí èç ýòèõ âåêòîðîâ áûë òèïà
Âû ìîæåòå âîñïîëüçîâàòüñÿ ïðåïðîöåññîðîì (#4.7), ÷òîáû ìåõàíèçèðîâàòü ðàáîòó. Íàïðèìåð, êëà
#include «vector.h»
declare(vector,int);
main() (* vector(int) vv(10); vv[2] = 3; vv[10] = 4; // îøèáêà: âûõîä çà ãðàíèöû *)
Ôàéë vector.h òàêèì îáðàçîì îïðåäåëÿåò ìàêðîñû, ÷òîáû ìàêðîñ declare(vector,int) ïîñëå ðàñø

îïðåäåëåíèå ôóíêöèé, åãî ìîæíî èñïîëüçîâàòü â ïðîãðàììå òîëüêî îäèí ðàç, â òî âðåìÿ êàê dec
declare(vector,char); //... implement(vector,char);
äàñò âàì îòäåëüíûé òèï «âåêòîð ñèìâîëîâ». Ïðèìåð ðåàëèçàöèè îáîáùåííûõ êëàññîâ ñ ïîìîùüþ ìà

1.17 Ïîëèìîðôíûå Âåêòîðà


Ó âàñ åñòü äðóãàÿ âîçìîæíîñòü îïðåäåëèòü âàø âåêòîðíûé è äðóãèå âìåùàþùèå êëàññû ÷åðåç óê
Çàìåòüòå, ÷òî ïîñêîëüêó â òàêèõ âåêòîðàõ õðàíÿòñÿ óêàçàòåëè, à íå ñàìè îáúåêòû, îáúåêò ìîæå
class apple : public common (* /*...*/ *) class orange : public common (* /*...*
/ *) class apple_vector : public cvector (* public:
cvector fruitbowl(100); //... apple aa; orange oo; //... fruitbowl[0] = amp;aa;
fruitbowl[1] = amp;oo; *)
Îäíàêî, òî÷íûé òèï îáúåêòà, âîøåäøåãî â òàêîé âìåùàþùèé êëàññ, áîëüøå êîìïèëÿòîðó íå èçâåñò
class apple_vector : public cvector (* public: apple* amp; elem(int i) (* return
(apple* amp;) cvector::elem(i); *) //... *);
èñïîëüçóÿ çàïèñü ïðèâåäåíèÿ ê òèïó (òèï)âûðàæåíèå, ÷òîáû ïðåîáðàçîâàòü common* amp; (ññûëêó

1.18 Âèðòóàëüíûå Ôóíêöèè


Ïðåäïîëîæèì, ÷òî ìû ïèøåì ïðîãðàììó äëÿ èçîáðàæåíèÿ ôèãóð íà ýêðàíå. Îáùèå àòðèáóòû ôèãóðû
class shape (* point center; color col; //... public: void move(point to) (* cen
ter=to; draw(); *) point where() (* return center; *) virtual void draw(); virtu
al void rotate(int); //... *);
Ôóíêöèè, êîòîðûå ìîæíî îïðåäåëèòü íå çíàÿ òî÷íî îïðåäåëåííîé ôèãóðû (íàïðèìåð, move è where
class circle: public shape (* int radius; public: void draw(); void rotatte(int
i) (**) //... *);
Òåïåðü, åñëè shape_vec âåêòîð ôèãóð, òî ìîæíî íàïèñàòü:
for (int i = 0; i«no_of_shapes; i++) shape_vec[i].rotate(45);
÷òîáû ïîâåðíóòü âñå ôèãóðû íà 45 ãðàäóñîâ (è çàíîâî íàðèñîâàòü)
Òàêîé ñòèëü îñîáåííî ïîëåçåí â èíòåðàêòèâíûõ ïðîãðàììàõ, êîãäà îáúåêòû ðàçíûõ òèïîâ îäèíàêî

ïðîãðàììíûì îáåñïå÷åíèåì. Âåäü ïî ñóòè äåëà, òèïè÷íîå äåéñòâèå ïîëüçîâàòåëÿ ýòî òêíóòü â

Ãëàâà 2 Îïèñàíèÿ è Êîíñòàíòû


Ñîâåðøåíñòâî äîñòèãàåòñÿ òîëüêî ê ìîìåíòó êðàõà.
    Ñ.Í. Ïàðêèíñîí

 ýòîé ãëàâå îïèñàíû îñíîâíûå òèïû (char, int, float è ò.ä.) è îñíîâíûå ñïîñîáû ïîñòðîåíèÿ

2.1 Îïèñàíèÿ
Ïðåæäå ÷åì èìÿ (èäåíòèôèêàòîð) ìîæåò áûòü èñïîëüçîâàíî â Ñ++ ïðîãðàììå, îí äîëæíî áûòü îïèñ
char ch; int count = 1; char* name = «Bjarne»; struct complex (* float re, im; *); c
omplex cvar; extern complex sqrt(complex); extern int error_number; typedef comp
lex point; float real(complex* p) (* return p-»re; *); const double pi = 3.1415926
535897932385; struct user;
Êàê ìîæíî âèäåòü èç ýòèõ ïðèìåðîâ, îïèñàíèå ìîæåò äåëàòü áîëüøå ÷åì ïðîñòî àññîöèèðîâàòü òè
extern complex sqrt(complex); extern int error_number; struct user;
íå ÿâëÿþòñÿ îäíîâðåìåííî îïðåäåëåíèÿìè. Ýòî îçíà÷àåò, ÷òî îáúåêò, ê êîòîðîìó îíè îòíîñÿòñÿ,
int count; int count; // îøèáêà: ïåðåîïðåäåëåíèå extern int error_number; extern int error_
à â ýòîì íè îäíîé (îá èñïîëüçîâàíèè extern ñì. #4.2):
extern int error_number; extern 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; // ãëîáàëüíîå x
f() (* int x; // ëîêàëüíîå x ïðÿ÷åò ãëîáàëüíîå x x = 1; // ïðèñâîèòü ëîêàëüíîìó x (* int x;
int* p = amp;x; // âçÿòü àäðåñ ãëîáàëüíîãî x
Ñîêðûòèå èìåí íåèçáåæíî ïðè íàïèñàíèè áîëüøèõ ïðîãðàìì. Îäíàêî ÷èòàþùèé ÷åëîâåê ëåãêî ìîæåò

î÷åíü òðóäíî îáíàðóæèòü, ãëàâíûì îáðàçîì ïîòîìó, ÷òî îíè ðåäêèå. Çíà÷èò ñîêðûòèå èìåí ñëåäó
Ñ ïîìîùüþ ïðèìåíåíèÿ îïåðàöèè ðàçðåøåíèÿ îáëàñòè âèäèìîñòè :: ìîæíî èñïîëüçîâàòü ñêðûòîå ãë
int x;
f() (* int x = 1; // ñêðûâàåò ãëîáàëüíîå x ::x = 2; // ïðèñâàèâàåò ãëîáàëüíîìó x *)
Íî âîçìîæíîñòè èñïîëüçîâàòü ñêðûòîå ëîêàëüíîå èìÿ íåò.
Îáëàñòü âèäèìîñòè èìåíè íà÷èíàåòñÿ â òî÷êå îïèñàíèÿ. Ýòî îçíà÷àåò, ÷òî èìÿ ìîæíî èñïîëüçîâà
int x;
f() (* int x = x; // èçâðàùåíèå *)
Ýòî íå ÿâëÿåòñÿ íåäîïóñòèìûì, õîòÿ è áåññìûñëåííî, è êîìïèëÿòîð ïðåäóïðåäèò, ÷òî x «used be
int x;
f() // èçâðàùåíèå (* int y = x; // ãëîáàëüíîå x int x = 22; y = x; // ëîêàëüíîå x *)
Ïåðåìåííàÿ y èíèöèàëèçèðóåòñÿ çíà÷åíèåì ãëîáàëüíîãî x, 11, à çàòåì åìó ïðèñâàèâàåòñÿ çíà÷åí
Èìåíà ïàðàìåòðîâ ôóíêöèè ñ÷èòàþòñÿ îïèñàííûìè â ñàìîì âíåøíåì áëîêå ôóíêöèè, ïîýòîìó
f(int x) (* int x; // îøèáêà *)
ñîäåðæèò îøèáêó, òàê êàê x îïðåäåëåíî äâàæäû â îäíîé è òîé æå îáëàñòè âèäèìîñòè.

2.1.2 Îáúåêòû è Àäðåñà (Lvalue)


Ìîæíî íàçíà÷àòü è èñïîëüçîâàòü ïåðåìåííûå, íå èìåþùèå èìåí, è ìîæíî îñóùåñòâëÿòü ïðèñâàèâàí

lvalue åñòü âûðàæåíèå, ññûëàþùååñÿ íà îáúåêò" (#ñ.5). Ñëîâî «lvalue» ïåðâîíà÷àëüíî áûëî ïðè

2.1.3 Âðåìÿ Æèçíè


Åñëè ïðîãðàììèñò íå óêàçàë èíîãî, òî îáúåêò ñîçäàåòñÿ, êîãäà âñòðå÷àåòñÿ åãî îïèñàíèå, è óí
 * Êîìàíäà #include «stream.h» áûëà âûáðîøåíà èç ïðèìåðîâ â ýòîé ãëàâå äëÿ ýêîíîìèè ìåñòà.
int a = 1;
void f() (* int b = 1; // èíèöèàëèçèðóåòñÿ ïðè êàæäîì // âûçîâå f() static int c = 1; // èí
main() (* while (a « 4) f(); *)
ïðîèçâîäèò âûâîä
a = 1 b = 1 c = 1 a = 2 b = 1 c = 2 a = 3 b = 1 c = 3
Íå èíèöèàëèçèðîâàííàÿ ÿâíî ñòàòè÷åñêàÿ (static) ïåðåìåííàÿ íåÿâíî èíèöèàëèçèðóåòñÿ íóëåì.
Ñ ïîìîùüþ îïåðàöèé new è delete ïðîãðàììèñò ìîæåò òàêæå ñîçäàâàòü îáúåêòû, âðåìÿ æèçíè êîòî

2.2 Èìåíà
Èìÿ (èäåíòèôèêàòîð) ñîñòîèò èç ïîñëåäîâàòåëüíîñòè áóêâ è öèôð. Ïåðâûé ñèìâîë äîëæåí áûòü áó
hello this_is_a_most_unusially_long_name DEFINED foO bAr u_name HorseSense var0
var1 CLASS _class ___
Ïðèìåðû ïîñëåäîâàòåëüíîñòåé ñèìâîëîâ, êîòîðûå íå ìîãóò èñïîëüçîâàòüñÿ êàê èäåíòèôèêàòîðû:
012 a fool $sys class 3var pay.due foo~bar .name if
Áóêâû â âåðõíåì è íèæíåì ðåãèñòðàõ ñ÷èòàþòñÿ ðàçëè÷íûìè, ïîýòîìó Count è count ðàçëè÷íûå
Âî âðåìÿ ÷òåíèÿ ïðîãðàììû êîìïèëÿòîð âñåãäà èùåò íàèáîëåå äëèííóþ ñòðîêó, ñîñòàâëÿþùóþ èìÿ,

2.3 Òèïû
Êàæäîå èìÿ (èäåíòèôèêàòîð) â Ñ++ ïðîãðàììå èìååò àññîöèèðîâàííûé ñ íèì òèï. Ýòîò òèï îïðåäå
int error number; float real(complex* p);
Ïîñêîëüêó error_number îïèñàíî êàê int, åãî ìîæíî ïðèñâàèâàòü, èñïîëüçîâàòü â àðèôìåòè÷åñêè
main() (* int* p = new int; cout « "sizeof(int) = " «« sizeof(int) «\n ; *)
Èìÿ òèïà ìîæíî òàêæå èñïîëüçîâàòü äëÿ çàäàíèÿ ÿâíîãî ïðåîáðàçîâàíèÿ îäíîãî òèïà â äðóãîé, í
float f; char* p; //... long ll = long(p); // ïðåîáðàçóåò p â long int i = int(f); // ïðåîá

2.3.1 Îñíîâíûå Òèïû


 Ñ++ åñòü íàáîð îñíîâíûõ òèïîâ, êîòîðûå ñîîòâåòñòâóþò íàèáîëåå îáùèì îñíîâíûì åäèíèöàì ïàì
char short int int long int
äëÿ ïðåäñòàâëåíèÿ öåëûõ ðàçëè÷íûõ ðàçìåðîâ,
float double
äëÿ ïðåäñòàâëåíèÿ ÷èñåë ñ ïëàâàþùåé òî÷êîé,
unsigned char unsigned short int unsigned int unsigned long int
äëÿ ïðåäñòàâëåíèÿ áåççíàêîâûõ öåëûõ, ëîãè÷åñêèõ çíà÷åíèé, áèòîâûõ ìàññèâîâ è ò.ï. Äëÿ áîëüø
const a = 1; static x;
âñå îïðåäåëÿþò îáúåêò òèïà int.
Öåëûé òèï char íàèáîëåå óäîáåí äëÿ õðàíåíèÿ è îáðàáîòêè ñèìâîëîâ íà äàííîì êîìïüþòåðå, îáû÷
Ïðè÷èíà òîãî, ÷òî ïðåäîñòàâëÿåòñÿ áîëåå ÷åì îäèí öåëûé òèï, áîëåå ÷åì îäèí áåççíàêîâûé òèï
1==sizeof(char)«=sizeof(short)«= sizeof(int)«=sizeof(long) sizeof(float)«=sizeof(double)
Îäíàêî îáû÷íî ðàçóìíî ïðåäïîëàãàòü, ÷òî â char ìîãóò õðàíèòüñÿ öåëûå ÷èñëà â äèàïàçîíå 0..1
Áåççíàêîâûå (unsigned) öåëûå òèïû èäåàëüíî ïîäõîäÿò äëÿ ïðèìåíåíèé, â êîòîðûõ ïàìÿòü ðàññìà
unsigned surprise = -1;
äîïóñòèìî (íî êîìïèëÿòîð îáÿçàòåëüíî ñäåëàåò ïðåäóïðåæäåíèå).

2.3.2 Íåÿâíîå Ïðåîáðàçîâàíèå Òèïà


Îñíîâíûå òèïû ìîæíî ñâîáîäíî ñî÷åòàòü â ïðèñâàèâàíèÿõ è âûðàæåíèÿõ. Âåçäå, ãäå ýòî âîçìîæíî
Ñóùåñòâóþò ñëó÷àè, â êîòîðûõ èíôîðìàöèÿ ìîæåò òåðÿòüñÿ èëè èñêàæàòüñÿ. Ïðèñâàèâàíèå çíà÷åíè
int i1 = 256+255; char ch = i1 // ch == 255 int i2 = ch; // i2 == ?
 ïðèñâàèâàíèè ch=i1 òåðÿåòñÿ îäèí áèò (ñàìûé çíà÷èìûé!), è ch áóäåò ñîäåðæàòü äâîè÷íûé êîä

2.3.3 Ïðîèçâîäíûå Òèïû


Äðóãèå òèïû ìîæíî âûâîäèòü èç îñíîâíûõ òèïîâ (è òèïîâ, îïðåäåëåííûõ ïîëüçîâàòåëåì) ïîñðåäñò
* óêàçàòåëü amp; ññûëêà [] âåêòîð () ôóíêöèÿ
è ìåõàíèçìà îïðåäåëåíèÿ ñòðóêòóð. Íàïðèìåð:
int* a; float v[10]; char* p[20]; // âåêòîð èç 20 óêàçàòåëåé íà ñèìâîë void f(int); struct
Ïðàâèëà ïîñòðîåíèÿ òèïîâ ñ ïîìîùüþ ýòèõ îïåðàöèé ïîäðîáíî îáúÿñíÿþòñÿ â #ñ.8.3-4. Îñíîâíàÿ
int v[10]; // îïèñûâàåò âåêòîð i = v[3]; // èñïîëüçóåò ýëåìåíò âåêòîðà
int* p; // îïèñûâàåò óêàçàòåëü i = *p; // èñïîëüçóåò óêàçûâàåìûé îáúåêò
Âñÿ ñëîæíîñòü ïîíèìàíèÿ çàïèñè ïðîèçâîäíûõ òèïîâ ïðîèñòåêàåò èç òîãî, ÷òî îïåðàöèè * è amp;
int* v[10]; // âåêòîð óêàçàòåëåé int (*p)[10]; // óêàçàòåëü íà âåêòîð
Áîëüøèíñòâî ëþäåé ïðîñòî ïîìíÿò, êàê âûãëÿäÿò íàèáîëåå îáû÷íûå òèïû.
Îïèñàíèå êàæäîãî èìåíè, ââîäèìîãî â ïðîãðàììå, ìîæåò îêàçàòüñÿ óòîìèòåëüíûì, îñîáåííî åñëè
int x, y; // int x; int y;
Ïðè îïèñàíèè ïðîèçâîäíûõ òèïîâ ìîæíî óêàçàòü, ÷òî îïåðàöèè ïðèìåíÿþòñÿ òîëüêî ê îòäåëüíûì è
int* p, y; // int* p; int y; ÍÅ int* y; int x, *p; // int x; int* p; int v[10], *p;
// int v[10]; int* p;
Ìíåíèå àâòîðà òàêîâî, ÷òî ïîäîáíûå êîíñòðóêöèè äåëàþò ïðîãðàììó ìåíåå óäîáî÷èòàåìîé, è èõ ñ

2.3.4 Òèï void


Òèï void (ïóñòîé) ñèíòàêñè÷åñêè âåäåò ñåáÿ êàê îñíîâíîé òèï. Îäíàêî èñïîëüçîâàòü åãî ìîæíî
void f() // f íå âîçâðàùàåò çíà÷åíèå void* pv; // óêàçàòåëü íà îáúåêò íåèçâåñòíîãî òèïà
Ïåðåìåííîé òèïà óêàçàòåëü íà 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. Òî åñòü, â ïåðåìåí
int* pi; char** cpp; // óêàçàòåëü íà óêàçàòåëü íà char int (*vp)[10]; // óêàçàòåëü íà âåêòî
Îñíîâíàÿ îïåðàöèÿ íàä óêàçàòåëåì ðàçûìåíîâàíèå, òî åñòü ññûëêà íà îáúåêò, íà êîòîðûé óêàç
char c1 = 'a'; char* p = amp;c1; // â p õðàíèòñÿ àäðåñ c1 char c2 = *p; // c2 = 'a'
Ïåðåìåííàÿ, íà êîòîðóþ óêàçûâàåò p, ýòî c1, à çíà÷åíèå, êîòîðîå õðàíèòñÿ â c1, ýòî 'a', ïî
Íàä óêàçàòåëÿìè ìîæíî îñóùåñòâëÿòü íåêîòîðûå àðèôìåòè÷åñêèå äåéñòâèÿ. Âîò, íàïðèìåð, ôóíêöè
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». Ýëåìåíòû èíäåêñèðóþòñÿ
float v[3]; // âåêòîð èç òðåõ float: v[0], v[1], v[2] int a[2][5]; // äâà âåêòîðà èç ïÿòè i
Öèêë äëÿ ïå÷àòè öåëûõ çíà÷åíèé áóêâ íèæíåãî ðåãèñòðà ìîæíî áûëî áû íàïèñàòü òàê:
extern int strlen(char*);
char alpha[] = «abcdefghijklmnoprstuvwxyz»;
main()

(* int sz = strlen(alpha);
for (int i=0; i«sz; i++) (* char ch = alpha[i]; cout "'" « chr(ch) «« "'" «« " = " «« c
0x «« hex(ch) «« «\n ; *) *)
Ôóíêöèÿ chr() âîçâðàùàåò ïðåäñòàâëåíèå íåáîëüøîãî öåëîãî â âèäå ñòðîêè; íàïðèìåð, chr(80) ý
'a' = 97 = 0141 = 0x61 'b' = 98 = 0142 = 0x62 'c' = 99 = 0143 = 0x63 ...
Çàìåòèì, ÷òî çàäàâàòü ðàçìåð âåêòîðà alpha íåîáÿçàòåëüíî. Êîìïèëÿòîð ñ÷èòàåò ÷èñëî ñèìâîëîâ
char v[9]; v = «ñòðîêà»; // îøèáêà
îøèáî÷íî, ïîñêîëüêó ïðèñâàèâàíèå íå îïðåäåëåíî äëÿ âåêòîðîâ.
Êîíå÷íî, äëÿ èíèöèàëèçàöèè ñèìâîëüíûõ ìàññèâîâ ïîäõîäÿò íå òîëüêî ñòðîêè. Äëÿ îñòàëüíûõ òèï
int v1[] = (* 1, 2, 3, 4 *); int v2[] = (* 'a', 'b', 'c', 'd' *);
char v3[] = (* 1, 2, 3, 4 *); char v4[] = (* 'a', 'b', 'c', 'd' *);
Çàìåòüòå, ÷òî v4 âåêòîð èç ÷åòûðåõ (à íå ïÿòè) ñèìâîëîâ; îí íå îêàí÷èâàåòñÿ íóëåì, êàê òî
Ìíîãîìåðíûå ìàññèâû ïðåäñòàâëÿþòñÿ êàê âåêòîðà âåêòîðîâ, è ïðèìåíåíèå çàïèñè ÷åðåç çàïÿòóþ,
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 «« «][
"; 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 Óêàçàòåëè è Âåêòîðà


Óêàçàòåëè è âåêòîðà â Ñ++ ñâÿçàíû î÷åíü òåñíî. Èìÿ âåêòîðà ìîæíî èñïîëüçîâàòü êàê óêàçàòåëü
char alpha[] = «abcdefghijklmnopqrstuvwxyz»; char* p = alpha; char ch;
while (ch = *p++) cout « chr(ch) « " = " «« ch «« « = 0 «« oct(ch) «« «\n ;
Îïèñàíèå p ìîæíî áûëî òàêæå çàïèñàòü êàê
char* p = amp;alpha[0];
Ýòà ýêâèâàëåíòíîñòü øèðîêî èñïîëüçóåòñÿ â âûçîâàõ ôóíêöèé, â êîòîðûõ âåêòîðíûé ïàðàìåòð âñå
extern int strlen(char*); char v[] = «Annemarie»; char* p = v; strlen(p); strlen(v);
ôóíêöèè strlen â îáîèõ âûçîâàõ ïåðåäàåòñÿ îäíî è òî æå çíà÷åíèå. Âñÿ øòóêà â òîì, ÷òî ýòîãî

îçíà÷àåò ñëåäóþùèé ýëåìåíò ýòîãî âåêòîðà, à 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) ««
äàåò
char* 1 int* 4
ïîñêîëüêó íà ìîåé ìàøèíå êàæäûé ñèìâîë çàíèìàåò îäèí áàéò, à êàæäîå öåëîå çàíèìàåò ÷åòûðå á
Âû÷èòàíèå óêàçàòåëåé îïðåäåëåíî òîëüêî òîãäà, êîãäà îáà óêàçàòåëÿ óêàçûâàþò íà ýëåìåíòû îäí
int v1[10]; int v2[10];
int i = amp;v1[5] amp;v1[3]; // 2 i = amp;v1[5] amp;v2[3]; // ðåçóëüòàò íåîïðåäåëåí
int* p = v2+2; // p == amp;v2[2] p = v2-2; // p íåîïðåäåëåíî

2.3.8 Ñòðóêòóðû
Âåêòîð åñòü ñîâîêóïíîñòü ýëåìåíòîâ îäíîãî òèïà, struct ÿâëÿåòñÿ ñîâîêóïíîñòüþ ýëåìåíòîâ (ïð
struct address (* // ïî÷òîâûé àäðåñ char* name; // èìÿ «Jim Dandy» long number; // íîìåð äî
/ ãîðîä «New Providence» char* state[2]; // øòàò 'N' 'J' int zip; // èíäåêñ 7974 *)
îïðåäåëÿåò íîâûé òèï, íàçâàííûé address (ïî÷òîâûé àäðåñ), ñîñòîÿùèé èç ïóíêòîâ, òðåáóþùèõñÿ

ÿâëÿåòñÿ äîñòàòî÷íûì äëÿ ðàáîòû ñ ïîëíûì ïî÷òîâûì àäðåñîì, íî â êà÷åñòâå ïðèìåðà äîñòàòî÷åí
Ïåðåìåííûå òèïà 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). Çàìåòüòå, ÷òî íåëüçÿ áûëî áû èíèöèàë
Ê ñòðóêòóðíûì îáúåêòàì ÷àñòî îáðàùàþòñÿ ïîñðåäñòâîì óêàçàòåëåé èñïîëüçóÿ îïåðàöèþ -». Íàïðè
void print_addr(address* p) (* cout « p- name \n p- number " " p- street «
p- state[1]) «« " " «« p- zip «« «\n ; *)
Îáúåêòû òèïà ñòðóêòóðà ìîæíî ïðèñâàèâàòü, ïåðåäàâàòü êàê ïàðàìåòðû ôóíêöèè è âîçâðàùàòü èç
address current;
address set_current(address next) (* address prev = current; current = next; ret
urn prev; *)
Îñòàëüíûå îñìûñëåííûå îïåðàöèè, òàêèå êàê ñðàâíåíèå (== è !=) íå îïðåäåëåíû. Îäíàêî ïîëüçîâ
Çàìåòüòå, ÷òî èìÿ òèïà ñòàíîâèòñÿ äîñòóïíûì ñðàçó ïîñëå òîãî, êàê îíî âñòðåòèëîñü, à íå òîë
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; // îøèáêà: íåñîîòâåòñòâèå òèïîâ
Ñòðóêòóðíûå òèïû îòëè÷íû òàêæå îò îñíîâíûõ òèïîâ, ïîýòîìó
s1 x; int i = x; // îøèáêà: íåñîîòâåòñòâèå òèïîâ
Îäíàêî ñóùåñòâóåò ìåõàíèçì äëÿ îïèñàíèÿ íîâîãî èìåíè äëÿ òèïà áåç ââåäåíèÿ íîâîãî òèïà. Îïè
typedef char* Pchar; Pchar p1, p2; char* p3 = p1;
Ýòî ìîæåò ñëóæèòü óäîáíîé ñîêðàùåííîé çàïèñüþ.

2.3.10 Ññûëêè
Ññûëêà ÿâëÿåòñÿ äðóãèì èìåíåì îáúåêòà. Ãëàâíîå ïðèìåíåíèå ññûëîê ñîñòîèò â ñïåöèôèêàöèè îïå
int i = 1; int amp; r = i; // r è i òåïåðü ññûëàþòñÿ íà îäèí int int x = r // x = 1 r = 2;
Ññûëêà äîëæíà áûòü èíèöèàëèçèðîâàíà (äîëæíî áûòü ÷òî-òî, äëÿ ÷åãî îíà ÿâëÿåòñÿ èìåíåì). Çàì
Âîïðåêè îæèäàíèÿì, íè îäíà îïåðàöèÿ íà ññûëêó íå äåéñòâóåò. Íàïðèìåð:
int ii = 0; int amp; rr = ii; rr++; // ii óâåëè÷èâàåòñÿ íà 1
äîïóñòèìî, íî rr++ íå óâåëè÷èâàåò ññûëêó; âìåñòî ýòîãî + + ïðèìåíÿåòñÿ ê int, êîòîðûì îêàçû
Î÷åâèäíûì ñïîñîáîì ðåàëèçàöèè ññûëêè ÿâëÿåòñÿ êîíñòàíòíûé óêàçàòåëü, êîòîðûé ðàçûìåíîâûâàåò
1. Âî-ïåðâûõ, åñëè íåîáõîäèìî, ïðèìåíÿåòñÿ ïðåîáðàçîâàíèå òèïà (#ñ.6.6-8, #ñ.8.5.6),
2. Çàòåì ïîëó÷åííîå çíà÷åíèå ïîìåùàåòñÿ âî âðåìåííóþ ïåðåìåííóþ è
3. Íàêîíåö, åå àäðåñ èñïîëüçóåòñÿ â êà÷åñòâå çíà÷åíèÿ èíèöèàëèçàòîðà.
Ðàññìîòðèì îïèñàíèå
double amp; dr = 1;
Ýòî èíòåðïðåòèðóåòñÿ òàê:
double* drp; // ññûëêà, ïðåäñòàâëåííàÿ êàê óêàçàòåëü double temp; temp = double(1); drp = a
int x = 1; void incr(int amp; aa) (* aa++; *) incr(x) // x = 2
Ïî îïðåäåëåíèþ ñåìàíòèêà ïåðåäà÷è ïàðàìåòðà òà æå, ÷òî ñåìàíòèêà èíèöèàëèçàöèè, ïîýòîìó ïàð
ïðåäïî÷òèòåëüíî ÿâíî âîçâðàùàòü çíà÷åíèå èç ôóíêöèè èëè òðåáîâàòü â êà÷åñòâå ïàðàìåòðà óêàç
int x = 1; int next(int p) (* return p+1; *) x = next(x); // x = 2
void inc(int* p) (* (*p)++; *) inc( amp;x); // x = 3
Ññûëêè òàêæå ìîæíî ïðèìåíÿòü äëÿ îïðåäåëåíèÿ ôóíêöèé, êîòîðûå ìîãóò èñïîëüçîâàòüñÿ è â ëåâî
struct pair (* char* name; int val; *);
Îñíîâíàÿ èäåÿ ñîñòîèò â òîì, ÷òî ñòðîêà èìååò àññîöèèðîâàííîå ñ íåé öåëîå çíà÷åíèå. Ëåãêî î
const large = 1024; static pair vec[large+1*);
pair* find(char* p) /* ïîääåðæèâàåò ìíîæåñòâî ïàð «pair»: èùåò p, åñëè íàõîäèò, âîçâðàùàåò
if (i == large) return amp;vec[large-1];
return amp;vec[i]; *)
Ýòó ôóíêöèþ ìîæåò èñïîëüçîâàòü ôóíêöèÿ value(), ðåàëèçóþùàÿ ìàññèâ öåëûõ, èíäåêñèðîâàííûé ñ
int amp; value(char* p) (* pair* res = find(p); if (res-»name == 0) (* // äî ñèõ ïîð íå âñò
en(p)+1]; // èíèöèàëèçèðîâàòü strcpy(res-»name,p); res-»val = 0; // íà÷àëüíîå çíà÷åíèå 0 *)
Äëÿ äàííîé â êà÷åñòâå ïàðàìåòðà ñòðîêè 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 ; *)
Íà êàæäîì ïðîõîäå öèêë ñ÷èòûâàåò îäíî ñëîâî èç ñòàíäàðòíîé ñòðîêè ââîäà cin â buf (ñì. Ãëàâ
aa bb bb aa aa bb aa aa
òî ïðîãðàììà âûäàñò:
aa: 5 bb: 3
Ëåãêî óñîâåðøåíñòâîâàòü ýòî â ïëàíå ñîáñòâåííîãî òèïà àññîöèèðîâàííîãî ìàññèâà ñ ïîìîùüþ êë

2.3.11 Ðåãèñòðû
Âî ìíîãèõ ìàøèííûõ àðõèòåêòóðàõ ìîæíî îáðàùàòüñÿ ê (íåáîëüøèì) îáúåêòàì çàìåòíî áûñòðåå, êî
register int i; register point cursor; register char* p;
Îïèñàíèå register ñëåäóåò èñïîëüçîâàòü òîëüêî â òåõ ñëó÷àÿõ, êîãäà ýôôåêòèâíîñòü äåéñòâèòåë
Íåâîçìîæíî ïîëó÷èòü àäðåñ èìåíè, îïèñàííîãî êàê register, ðåãèñòð íå ìîæåò òàêæå áûòü ãëîáà

2.4 Êîíñòàíòû
Ñ++ äàåò âîçìîæíîñòü çàïèñè çíà÷åíèé îñíîâíûõ òèïîâ: ñèìâîëüíûõ êîíñòàíò, öåëûõ êîíñòàíò è
ëþáîãî òèïà ìîæíî äàòü èìÿ è èñïîëüçîâàòü åãî êàê êîíñòàíòó, äîáàâèâ ê åãî îïèñàíèþ êëþ÷åâî

2.4.1 Öåëûå Êîíñòàíòû


Öåëûå êîíñòàíòû ïðåäñòàþò â ÷åòûðåõ îáëè÷üÿõ: äåñÿòè÷íûå, âîñüìåðè÷íûå, øåñòíàäöàòåðè÷íûå ê
0 1234 976 12345678901234567890
Äåñÿòè÷íàÿ êîíñòàíòà èìååò òèï int, ïðè óñëîâèè, ÷òî îíà âëåçàåò â int, â ïðîòèâíîì ñëó÷àå
Êîíñòàíòà, êîòîðàÿ íà÷èíàåòñÿ íóëåì çà êîòîðûì èäåò x (0 x), ÿâëÿåòñÿ øåñòíàäöàòåðè÷íûì ÷èñ
0 02 077 0123
èõ äåñÿòè÷íûå ýêâèâàëåíòû ýòî 0, 2, 63, 83.  øåñòíàäöàòèðè÷íîé çàïèñè ýòè êîíñòàíòû âûãë
0x0 0x2 0x3f 0x53
Áóêâû a, b, c, d, e è f, èëè èõ ýêâèâàëåíòû â âåðõíåì ðåãèñòðå, èñïîëüçóþòñÿ äëÿ ïðåäñòàâëå
2.4.2 Êîíñòàíòû ñ Ïëàâàþùåé Òî÷êîé
Êîíñòàíòû ñ ïëàâàþùåé òî÷êîé èìåþò òèï double. Êàê è â ïðåäûäóùåì ñëó÷àå, êîìïèëÿòîð äîëæåí
1.23 .23 0.23 1. 1.0 1.2e10 1.23e-15
Çàìåòüòå, ÷òî â ñåðåäèíå êîíñòàíòû ñ ïëàâàþùåé òî÷êîé íå ìîæåò âñòðå÷àòüñÿ ïðîáåë. Íàïðèìåð
65.43 e 21
è âûçîâåò ñèíòàêñè÷åñêóþ îøèáêó.
Åñëè âû õîòèòå èìåòü êîíñòàíòó êîíñòàíòà ñ ïëàâàþùåé òî÷êîé; òèïà float, âû ìîæåòå îïðåäåëè
const float pi = 3.14159265;

2.4.3 Ñèìâîëüíûå Êîíñòàíòû


Õîòÿ â Ñ++ è íåò îòäåëüíîãî ñèìâîëüíîãî òèïà äàííûõ, òî÷íåå, ñèìâîë ìîæåò õðàíèòüñÿ â öåëîì
'\b', âîçâðàò íàçàä '\f', ïåðåâîä ôîðìàòà '\n', íîâàÿ ñòðîêà '\r', âîçâðàò êàðåòêè '\t', ãî
Âîïðåêè èõ âíåøíåìó âèäó êàæäîå ÿâëÿåòñÿ îäíèì ñèìâîëîì. Ìîæíî òàêæå ïðåäñòàâëÿòü ñèìâîë îä
'\6' '\x6' 6 ASCII ack '\60' '\x30' 48 ASCII '0' '\137' '\x05f' 95 ASCII '_'
Ýòî ïîçâîëÿåò ïðåäñòàâëÿòü êàæäûé ñèìâîë èç ìàøèííîãî íàáîðà ñèìâîëîâ, è â ÷àñòíîñòè âñòàâë

2.4.4 Ñòðîêè
Ñòðîêîâàÿ êîíñòàíòà ýòî ïîñëåäîâàòåëüíîñòü ñèìâîëîâ, çàêëþ÷åííàÿ â äâîéíûå êàâû÷êè "
«ýòî ñòðîêà»
Êàæäàÿ ñòðîêîâàÿ êîíñòàíòà ñîäåðæèò íà îäèí ñèìâîë áîëüøå, ÷åì êàæåòñÿ; âñå îíè çàêàí÷èâàþò
sizeof(«asdf»)==5;
Ñòðîêà èìååò òèï «âåêòîð èç ñîîòâåòñòâóþùåãî ÷èñëà ñèìâîëîâ», ïîýòîìó «asdf» èìååò òèï char
Ñîãëàøåíèå î ïðåäñòàâëåíèè íåãðàôè÷åñêèõ ñèìâîëîâ ñ îáðàòíîé êîñîé ìîæíî èñïîëüçîâàòü òàêæå
cout « «ãóäîê â êîíöå ñîîáùåíèÿ\007\n
ãäå 7 çíà÷åíèå ASKII ñèìâîëà bel (çâîíîê).
 ñòðîêå íåâîçìîæíî èìåòü «íàñòîÿùóþ» íîâóþ ñòðîêó:
«ýòî íå ñòðîêà, à ñèíòàêñè÷åñêàÿ îøèáêà»
Îäíàêî â ñòðîêå ìîæåò ñòîÿòü îáðàòíàÿ êîñàÿ, ñðàçó ïîñëå êîòîðîé èäåò íîâàÿ ñòðîêà; è òî, è
cout « «çäåñü âñå \ ok
íàïå÷àòàåò
çäåñü âñå ok
Íîâàÿ ñòðîêà, ïåðåä êîòîðîé èäåò escape (îáðàòíàÿ êîñàÿ), íå ïðèâîäèò ê ïîÿâëåíèþ â ñòðîêå
 ñòðîêå ìîæíî èìåòü ïóñòîé ñèìâîë, íî áîëüøèíñòâî ïðîãðàìì íå áóäåò ïðåäïîëàãàòü, ÷òî åñòü
Âñòàâëÿÿ ÷èñëåííóþ êîíñòàíòó â ñòðîêó ñ ïîìîùüþ âîñüìåðè÷íîé èëè øåñòíàäöàòåðè÷íîé çàïèñè á
char v1[] = «a\x0fah\0129»; // 'a' '\xfa' 'h' '\12' '9' char v2[] = «a\xfah\129»; // 'a'
'\xfa' 'h' '\12' '9' char v3[] = «a\xfad\127»; // 'a' '\xfad' '\127'
Èìåéòå â âèäó, ÷òî äâóõçíà÷íîé øåñòíàäöàòåðè÷íîé çàïèñè íà ìàøèíàõ ñ 9-áèòîâûì áàéòîì áóäåò

2.4.5 Íîëü
Íîëü ìîæíî óïîòðåáëÿòü êàê êîíñòàíòó ëþáîãî öåëîãî, ïëàâàþùåãî èëè óêàçàòåëüíîãî òèïà. Íèêà

2.4.6 Const
Êëþ÷åâîå ñëîâî const ìîæåò äîáàâëÿòüñÿ ê îïèñàíèþ îáúåêòà, ÷òîáû ñäåëàòü ýòîò îáúåêò êîíñòà
const int model = 145; const int v[] = (* 1, 2, 3, 4 *);
Ïîñêîëüêó êîíñòàíòå íè÷åãî íåëüçÿ ïðèñâîèòü, îíà äîëæíà áûòü èíèöèàëèçèðîâàíà. Îïèñàíèå ÷åã

model = 145; // îøèáêà model++; // îøèáêà


Çàìåòüòå, ÷òî const èçìåíÿåò òèï, òî åñòü îãðàíè÷èâàåò ñïîñîá èñïîëüçîâàíèÿ îáúåêòà, âìåñòî
const char* peek(int i) (* return private[i]; *)
Ôóíêöèþ âðîäå ýòîé ìîæíî áûëî áû èñïîëüçîâàòü äëÿ òîãî, ÷òîáû äàâàòü êîìó-íèáóäü ÷èòàòü ñòð
Ñ äðóãîé ñòîðîíû, êîìïèëÿòîð ìîæåò íåñêîëüêèìè ïóòÿìè âîñïîëüçîâàòüñÿ òåì, ÷òî îáúåêò ÿâëÿå
Èñïîëüçîâàíèå óêàçàòåëÿ âîâëåêàåò äâà îáúåêòà: ñàì óêàçàòåëü è óêàçûâàåìûé îáúåêò. Ñíàáæåíè
const char* pc = «asdf»; // óêàçàòåëü íà êîíñòàíòó pc[3] = 'a'; // îøèáêà pc = «ghjk»; // o
×òîáû îïèñàòü ñàì const óêàçàòåëü, à íå óêàçûâàåìûé îáúåêò, êàê êîíñòàíòíûé, èñïîëüçóåòñÿ î
char *const cp = «asdf»; // êîíñòàíòíûé óêàçàòåëü cp[3] = 'a'; // ok cp = «ghjk»; // îøèáêà
×òîáû ñäåëàòü êîíñòàíòàìè îáà îáúåêòà, èõ îáà íóæíî îïèñàòü const. Íàïðèìåð:
const char *const cpc = «asdf»; // const óêàçàòåëü íà const cpc[3] = 'a'; // îøèáêà cpc = «
Îáúåêò, ÿâëÿþùèéñÿ êîíñòàíòîé ïðè äîñòóïå ê íåìó ÷åðåç îäèí óêàçàòåëü, ìîæåò áûòü ïåðåìåííî
char* strcpy(char* p, const char* q); // íå ìîæåò èçìåíèòü q
Óêàçàòåëþ íà êîíñòàíòó ìîæíî ïðèñâàèâàòü àäðåñ ïåðåìåíîé, ïîñêîëüêó íèêàêîãî âðåäà îò ýòîãî
int a = 1; const c = 2; const* p1 = amp;c; // ok const* p2 = amp;a; // ok int* p
3 = amp;c; // îøèáêà *p3 = 7; // ìåíÿåò çíà÷åíèå c
Êàê îáû÷íî, åñëè òèï â îïèñàíèè îïóùåí, òî îí ïðåäïîëàãàåòñÿ int.

2.4.7 Ïåðå÷èñëåíèÿ
Åñòü äðóãîé ìåòîä îïðåäåëåíèÿ öåëûõ êîíñòàíò, êîòîðûé èíîãäà áîëåå óäîáåí, ÷åì ïðèìåíåíèå c
enum (* ASM, AUTO, BREAK *);
ïåðå÷èñëåíèå îïðåäåëÿåò òðè öåëûõ êîíñòàíòû, íàçûâàåìûõ ïåðå÷èñëèòåëÿìè, è ïðèñâàèâàåò èì ç
const ASM = 0; const AUTO = 1; const BREAK = 2;
Ïåðå÷èñëåíèå ìîæåò áûòü èìåíîâàííûì. Íàïðèìåð:
enum keyword (* ASM, AUTO, BREAK *);
Èìÿ ïåðå÷èñëåíèÿ ñòàíîâèòñÿ ñèíîíèìîì int, à íå íîâûì òèïîì. Îïèñàíèå ïåðåìåííîé keyword, à
keyword key;
switch (key) (* case ASM: // ÷òî-òî äåëàåò break; case BREAK: // ÷òî-òî äåëàåò break; *)
ïîáóæäàåò êîìïèëÿòîð âûäàòü ïðåäóïðåæäåíèå, ïîñêîëüêó òîëüêî äâà çíà÷åíèÿ keyword èç òðåõ è
Ìîæíî òàêæå çàäàâàòü çíà÷åíèÿ ïåðå÷èñëèòåëåé ÿâíî. Íàïðèìåð:
enum int16 (* sign=0100000, // çíàê most_significant=040000, // ñàìûé çíà÷èìûé least_signif
Òàêèå çíà÷åíèÿ íå îáÿçàòåëüíî äîëæíû áûòü ðàçëè÷íûìè, âîçðàñòàþùèìè èëè ïîëîæèòåëüíûìè.

2.5 Ýêîíîìèÿ Ïðîñòðàíñòâà


 õîäå ïðîãðàììèðîâàíèÿ íåòðèâèàëüíûõ ðàçðàáîòîê íåèçáåæíî íàñòóïàåò âðåìÿ, êîãäà õî÷åòñÿ è
1. Ïîìåùåíèå â áàéò áîëåå îäíîãî íåáîëüøîãî îáúåêòà è
2. Èñïîëüçîâàíèå îäíîãî è òîãî æå ïðîñòðàíñòâà äëÿ õðàíåíèÿ ðàçíûõ îáúåêòîâ â ðàçíîå âðåìÿ.
Ïåðâîãî ìîæíî äîñòè÷ü ñ ïîìîùüþ èñïîëüçîâàíèÿ ïîëåé, âòîðîãî ÷åðåç èñïîëüçîâàíèå îáúåäèíå

2.5.1 Ïîëÿ
Èñïîëüçîâàíèå char äëÿ ïðåäñòàâëåíèÿ äâîè÷íîé ïåðåìåíîé, íàïðèìåð, ïåðåêëþ÷àòåëÿ âêëþ÷åíî/â
struct sreg (* unsigned enable : 1; unsigned page : 3; unsigned : 1; // íåèñïîëüçóåìîå unsi
signed : 4: // íåèñïîëüçóåìîå unsigned access : 1; unsigned length : 1; unsigned non_reside
Ïîëó÷èëîñü ðàçìåùåíèå ðåãèñòðà 0 ñîñòîÿíèÿ DEC PDP11/45 (â ïðåäïîëîæåíèè, ÷òî ïîëÿ â ñëîâå
sreg* sr0 = (sreg*)0777572; //... if (sr-»access) (* // íàðóøåíèå äîñòóïà // ÷èñòèò ìàññèâ
Îäíàêî ïðèìåíåíèå ïîëåé äëÿ óïàêîâêè íåñêîëüêèõ ïåðåìåííûõ â îäèí áàéò íå îáÿçàòåëüíî ýêîíî
è êðàòêàÿ çàïèñü äëÿ ïðèìåíåíèÿ ëîãè÷åñêèõ îïåðàöèé ñ öåëüþ èçâëå÷åíèÿ èíôîðìàöèè èç ÷àñòè

2.5.2 Îáúåäèíåíèÿ
Ðàññìîòðèì ïðîåêòèðîâàíèå ñèìâîëüíîé òàáëèöû, â êîòîðîé êàæäûé ýëåìåíò ñîäåðæèò èìÿ è çíà÷å
struct entry (* char* name; char type; char* string_value; // èñïîëüçóåòñÿ åñëè type == 's'
void print_entry(entry* p) (* switch p-»type (* case 's': cout « p- string_value; break
; case 'i': cout p- int_value; break; default: cerr «« «èñïîð÷åí type\n ; break; *) *)
Ïîñêîëüêó string_value è int_value íèêîãäà íå ìîãóò èñïîëüçîâàòüñÿ îäíîâðåìåííî, ÿñíî, ÷òî
struct entry (* char* name; char type; union (* char* string_value; //èñïîëüçóåòñÿ åñëè typ
e; //èñïîëüçóåòñÿ åñëè type == 'i' *); *);
Ýòî îñòàâëÿåò âñþ ÷àñòü ïðîãðàììû, èñïîëüçóþùóþ entry, áåç èçìåíåíèé, íî îáåñïå÷èâàåò, ÷òî
Èñïîëüçîâàíèå îáúåäèíåíèé òàêèì îáðàçîì, ÷òîáû ïðè ÷òåíèè çíà÷åíèÿ âñåãäà ïðèìåíÿëñÿ òîò ÷ë
Îáúåäèíåíèÿ èíîãäà èñïîëüçóþò äëÿ «îáúåäèíåíèÿ è ïðåîáðàçîâàíèå òèïà» (ýòî äåëàþò ãëàâíûì î
struct fudge (* union (* int i; int* p; *); *);
fudge a; a.i = 4096; int* p = a.p; // ïëîõîå èñïîëüçîâàíèå
Íî íà ñàìîì äåëå ýòî ñîâñåì íå ïðåîáðàçîâàíèå: íà íåêîòîðûõ ìàøèíàõ int è int* çàíèìàþò íåî
Èçðåäêà îáúåäèíåíèÿ óìûøëåííî ïðèìåíÿþò, ÷òîáû èçáåæàòü ïðåîáðàçîâàíèÿ òèïîâ. Ìîæíî, íàïðèì
fudge.p = 0; int i = fudge.i; // i íå îáÿçàòåëüíî äîëæíî áûòü 0
Ìîæíî òàêæå äàòü îáúåäèíåíèþ èìÿ, òî åñòü ñäåëàòü åãî ïîëíîïðàâíûì òèïîì. Íàïðèìåð, fudge ì
union fudge (* int i; int* p; *);
è èñïîëüçîâàòü (íåïðàâèëüíî) â òî÷íîñòè êàê ðàíüøå. Èìåþòñÿ òàêæå è îïðàâäàííûå ïðèìåíåíèÿ

2.6 Óïðàæíåíèÿ
1. (*1) Çàñòàâüòå ðàáîòàòü ïðîãðàììó ñ «Hello, world» (1.1.1).
2. (*1) Äëÿ êàæäîãî îïèñàíèÿ â #2.1 ñäåëàéòå ñëåäóþùåå: Åñëè îïèñàíèå íå ÿâëÿåòñÿ îïðåäåëåí
3. (*1) Íàïèøèòå îïèñàíèÿ äëÿ: óêàçàòåëÿ íà ñèìâîë; âåêòîðà èç 10 öåëûõ; ññûëêè íà âåêòîð è
4. (*1.5) Íàïèøèòå ïðîãðàììó, êîòîðàÿ ïå÷àòàåò ðàçìåðû îñíîâíûõ è óêàçàòåëüíûõ òèïîâ. Èñïîë
5. (*1.5) Íàïèøèòå ïðîãðàììó, êîòîðàÿ ïå÷àòàåò áóêâû 'a'...'z' è öèôðû '0'...'9' è èõ ÷èñëî
6. (*1) Íàïå÷àòàéòå íàáîð áèòîâ, êîòîðûì ïðåäñòàâëÿåòñÿ óêàçàòåëü 0 íà âàøåé ñèñòåìå. Ïîäñê
7. (*1.5) Íàïèøèòå ôóíêöèþ, ïå÷àòàþùóþ ïîðÿäîê è ìàíòèññó ïàðàìåòðà òèïà double.
8. (*2) Êàêîâû íàèáîëüøèå è íàèìåíüøèå çíà÷åíèÿ, íà âøåé ñèñòåìå, ñëåäóþùèõ òèïîâ: char, sh
9. (*1) Êàêîå ñàìîå äëèííîå ëîêàëüíîå èìÿ ìîæíî èñïîëüçîâàòü â Ñ++ ïðîãðàììå â âàøåé ñèñòåì
10. (*2) Îïðåäåëèòå one ñëåäóþùèì îáðàçîì:
const one = 1;
Ïîïûòàéòåñü ïîìåíÿòü çíà÷åíèå one íà 2. Îïðåäåëèòå num ñëåäóþùèì îáðàçîì:
const num[] = (* 1, 2 *);
Ïîïûòàéòåñü ïîìåíÿòü çíà÷åíèå num[1] íà 2.
11. (*1) Íàïèøèòå ôóíêöèþ, ïåðåñòàâëÿþùóþ äâà öåëûõ (ìåíÿþùóþ çíà÷åíèÿ). Èñïîëüçóéòå â êà÷å
12. (*1) Êàêîâ ðàçìåð âåêòîðà str â ñëåäóþùåì ïðèìåðå:
char str[] = «a short string»;
Êàêîâà äëèíà ñòðîêè «a short string»?
13. (*1.5) Îïðåäåëèòå òàáëèöó íàçâàíèé ìåñÿöåâ ãîäà è ÷èñëà äíåé â íèõ. Âûâåäèòå åå. Ñäåëàé
14. (*1) Ñ ïîìîùüþ typedef îïðåäåëèòå òèïû: áåççíàêîâûé char, êîíñòàíòíûé áåççíàêîâûé char,

Ãëàâà 3 Âûðàæåíèÿ è Îïåðàòîðû


Ñ äðóãîé ñòîðîíû, ìû íå ìîæåì èãíîðèðîâàòü ýôôåêòèâíîñòü
    Äæîí Áåíòëè

Ñ++ èìååò íåáîëüøîé, íî ãèáêèé íàáîð ðàçëè÷íûõ âèäîâ îïåðàòîðîâ äëÿ êîíòðîëÿ ïîòîêà óïðàâëå
 * Íàì íåèçâåñòåí ðóññêîÿçû÷íûé òåðìèí, ýêâèâàëåíòíûé àíãëèéñêîìó indentation. Èíîãäà ýòî

3.1 Íàñòîëüíûé êàëüêóëÿòîð


Ñ îïåðàòîðàìè è âûðàæåíèÿìè âàñ ïîçíàêîìèò ïðèâåäåííàÿ çäåñü ïðîãðàììà íàñòîëüíîãî êàëüêóëÿ
r=2.5 area=pi*r*r
(pi îïðåäåëåíî çàðàíåå), òî ïðîãðàììà êàëüêóëÿòîðà íàïèøåò:
2.5 19.635
ãäå 2.5 ðåçóëüòàò ïåðâîé ââåäåííîé ñòðîêè, à 19.635 ðåçóëüòàò âòîðîé.
Êàëüêóëÿòîð ñîñòîèò èç ÷åòûðåõ îñíîâíûõ ÷àñòåé: ïðîãðàììû ñèíòàêñè÷åñêîãî ðàçáîðà (parser'à

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
primary: NUMBER // ÷èñëî ñ ïëàâàþùåé òî÷êîé â Ñ++ NAME // èìÿ Ñ++ çà èñêëþ÷åíèåì '_' NAME =
Äðóãèìè ñëîâàìè, ïðîãðàììà åñòü ïîñëåäîâàòåëüíîñòü ñòðîê. Êàæäàÿ ñòðîêà ñîñòîèò èç îäíîãî è
Èñïîëüçóåìûé ìåòîä îáû÷íî íàçûâàåòñÿ ðåêóðñèâíûì ñïóñêîì ýòî ïîïóëÿðíûé è ïðîñòîé íèñõîäÿùè
Ïðîãðàììà ðàçáîðà äëÿ ïîëó÷åíèÿ ââîäà èñïîëüçóåò ôóíêöèþ get_token(). Çíà÷åíèå ïîñëåäíåãî â
enum token_value (* NAME NUMBER END PLUS='+' MINUS='-' MUL='*' DIV='/' PRINT=';'
ASSIGN='=' LP='(' RP=')' *); token_value curr_tok;
 êàæäîé ôóíêöèè ðàçáîðà ïðåäïîëàãàåòñÿ, ÷òî áûëî îáðàùåíèå ê get_token(), è â curr_tok íàõ
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
; *) *)
Ôàêòè÷åñêè ñàìà ôóíêöèÿ äåëàåò íå î÷åíü ìíîãî.  ìàíåðå, äîñòàòî÷íî òèïè÷íîé äëÿ ôóíêöèé áî
Ñòðàííàÿ çàïèñü for(;;) ýòî ñòàíäàðòíûé ñïîñîá çàäàòü áåñêîíå÷íûé öèêë. Ìîæíî ïðîèçíîñèòü
 * èãðà ñëîâ: «for» «forever» (íàâñåãäà). (ïðèì. ïåðåâ.)
Îïåðàöèè +=, -= èñïîëüçóþòñÿ äëÿ îñóùåñòâëåíèÿ ñëîæåíèÿ è âû÷èòàíèÿ. Ìîæíî áûëî áû íå èçìåí
+ * / % amp; ! ^ « »
ïîýòîìó âîçìîæíû ñëåäóþùèå îïåðàöèè ïðèñâàèâàíèÿ:
+= -= *= /= %= amp;= != ^= « = »=
Êàæäàÿ ÿâëÿåòñÿ îòäåëüíîé ëåêñåìîé, ïîýòîìó a+ =1 ÿâëÿåòñÿ ñèíòàêñè÷åñêîé îøèáêîé èç-çà ïðî
Êàê îðãàíèçîâàòü ïðîãðàììó â âèäå íàáîðà ôàéëîâ, îáñóäàåòñÿ â Ãëàâå 4. Çà îäíèì èñêëþ÷åíèåì
Îïèñàíèå
double expr(); // áåç ýòîãî íåëüçÿ
ïåðåä prim() ïðåêðàñíî ñïðàâëÿåòñÿ ñ ýòèì.
Ôóíêöèÿ term() àíàëîãè÷íûì îáðàçîì îáðàáàòûâàåò óìíîæíèå è ñëîæåíèå:
double term() // óìíîæàåò è ñêëàäûâàåò (* double left = prim();
for(;;) switch(curr_tok) (* case MUL: get_token(); // åñò '*' left *= prim(); break; c
ase DIV: get_token(); // åñò '/' double d = prim(); if (d == 0) return error(«äåëåíèå íà 0»
ak; default: return left; *) *)
Ïðîâåðêà, êîòîðàÿ äåëàåòñÿ, ÷òîáû óäîñòîâåðèòüñÿ â òîì, ÷òî íåò äåëåíèÿ íà íîëü, íåîáõîäèìà
 *  ÿçûêå íåìíîãî ëó÷øå ýòîãî ñ ýòèìè èñêëþ÷åíèÿìè òîæå íàäî áû ñïðàâëÿòüñÿ. (ïðèì. àâòîð
Ôóíêöèÿ prim, îáðàáàòûâàþùàÿ primary, íàïèñàíà â îñíîíîì â òîì æå äóõå, íå ñ÷èòàÿ òîãî, ÷òî
double prim() // îáðàáàòûâàåò primary (ïåðâè÷íûå) (* switch (curr_tok) (* case NUMBER: // ê
token() == ASSIGN) (* name* n = insert(name_string); get_token(); n-»value = expr(
); return n-»value; *) return look(name-string)-»value; case MINUS: // óíàðíûé ìèíóñ get_to
im(); case LP: get_token(); double e = expr(); if (curr_tok != RP) return error(«äîëæíà áûò
ken(); return e; case END: return 1; default:
return error(«äîëæíî áûòü primary»); *) *)
Ïðè îáíàðóæåíèè NUMBER (òî åñòü, êîíñòàíòû ñ ïëàâàþùåé òî÷êîé), âîçâðàùàåòñÿ åãî çíà÷åíèå.
Òàê æå, êàê çíà÷åíèå ïîñëåäíåãî âñòðå÷åííîãî NUMBER õðàíèòñÿ â number_value, â name_string
srtuct name (* char* string; char* next; double value; *)
ãäå next èñïîëüçóåòñÿ òîëüêî ôóíêöèÿìè, êîòîðûå ïîääåðæèâàþò ðàáîòó ñ òàáëèöåé:
name* look(char*); name* insert(char*);
Îáå âîçâðàùàþò óêàçàòåëü íà name, ñîîòâåòñòâóþùåå ïàðìåòðó ñèìâîëüíîé ñòðîêå; look() âûðà

3.1.2 Ôóíêöèÿ ââîäà


×òåíèå ââîäà ÷àñòî ñàìàÿ çàïóòàííàÿ ÷àñòü ïðîãðàììû. Ïðè÷èíà â òîì, ÷òî åñëè ïðîãðàììà äî
Äëÿ êàëüêóëÿòîðà ïðàâèëà ñîçíàòåëüíî áûëè âûáðàíû òàêìè, ÷òîáû ôóíêöèÿì ïî ðàáîòå ñ ïîòîêàì
'\n' ÿâëÿåòñÿ äëÿ êàëüêóëÿòîðà ñóùåñòâåííûì, à ôóíêöèè ðàáîòû ñ ïîòîêàìè ñ÷èòàþò åãî ñèìâîë
char ch
do (* // ïðîïóñêàåò ïðîïóñêè çà èñêëþ÷åíèåì '\n' if(!cin.get(ch)) return curr_tok = END; *)
Âûçîâ cin.get(ch) ñ÷èòûâàåò îäèí ñèìâîë èç ñòàíäàðòíîãî ïîòîêà ââîäà â ch. Ïðîâåðêà if(!cin
Ôóíêöèÿ (inline) isspace() èç «ctype.h» îáåñïå÷èâàåò ñòàíäàðòíóþ ïðîâåðêó íà òî, ÿâëÿåòñÿ ë
Ïîñëå òîãî, êàê ïóñòîå ìåñòî ïðîïóùåíî, ñëåäóþùèé ñèìâîë èñïîëüçóåòñÿ äëÿ îïðåäåëåíèÿ òîãî,
switch (ch) (* case ';': case '\n': cin »» WS; // ïðîïóñòèòü ïðîïóñê return curr_tok=PRINT;
Ïðîïóñê ïóñòîãî ìåñòà äåëàòü íåîáÿçàòåëüíî, íî îí ïîçâëÿåò èçáåæàòü ïîâòîðíûõ îáðàùåíèé ê g
×èñëà îáðàáàòûâàþòñÿ òàê:
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, ï
Èìÿ, òî åñòü ëåêñåìà NAME, îïðåäåëÿåòñÿ êàê áóêâà, çà êîòîðîé âîçìîæíî ñëåäóåò íåñêîëüêî áó
if (isalpha(ch)) (* char* p = name_string; *p++ = ch; while (cin.get(ch) amp; am
p; isalnum(ch)) *p++ = ch; cin.putback(ch); *p = 0; return curr_tok=NAME; *)
Ýòà ÷àñòü ñòðîèò â name_string ñòðîêó, çàêàí÷èâàþùóþñÿ íóëåì. Ôóíêöèè isalpha() è isalnum()
Âîò, íàêîíåö, ôóíêöèÿ ââîäà ïîëíîñòüþ:
token_value get_token() (* char ch;
do (* // ïðîïóñêàåò ïðîïóñêè çà èñêëþ÷åíèåì '\n' if(!cin.get(ch)) return curr_tok = END; *)
switch (ch) (* case ';': case '\n': cin »» WS; // ïðîïóñòèòü ïðîïóñê return curr_tok=PRINT;
+': 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
) amp; amp; isalnum(ch)) *p++ = ch; cin.putback(ch); *p = 0; return curr_tok=NAM
E; *) error(«ïëîõàÿ ëåêñåìà»); return curr_tok=PRINT; *) *)
Ïîñêîëüêó token_value (çíà÷åíèå ëåêñåìû) îïåðàöèè áûëî îïðåäåëåíî êàê öåëîå çíà÷åíèå ýòîé î

 * çíàêà ýòîé îïåðàöèè. (ïðèì. ïåðåâ.)

3.1.3 Òàáëèöà èìåí


Ê òàáëèöå èìåí äîñòóï îñóùåñòâëÿåòñÿ ñ ïîìîùüþ îäíîé ôóíêöèè
name* look(char* p, int ins =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];
Ïîñêîëüêó âñå ñòàòè÷åñêèå îáúåêòû èíèöèàëèçèðóþòñÿ íëåì, ýòî òðèâèàëüíîå îïèñàíèå òàáëèöû t
Äëÿ íàõîæäåíèÿ ýëåìåíòà â òàáëèöå â look() ïðèíèìàåòñÿ ïðîñòîé àëãîðèòì õýøèðîâàíèÿ (èìåíà
int ii = 0; // õýøèðîâàíèå char* pp = p; while (*pp) ii = ii««1 ^ *pp++; if (ii « 0) ii = -
Òî åñòü, ñ ïîìîùüþ èñêëþ÷àþùåãî ÈËÈ êàæäûé ñèìâîë âî âõîäíîé ñòðîêå «äîáàâëÿåòñÿ» ê ii («ñó
ii ««= 1; ii ^= *pp++;
Êñòàòè, ïðèìåíåíèå ^ ëó÷øå è áûñòðåå, ÷åì +. Ñäâèã âàæåí äëÿ ïîëó÷åíèÿ ïðèåìëåìîãî õýø-êîäà
if (ii « 0) ii = -ii; ii %= TBLSZ;

îáåñïå÷èâàþò, ÷òî ii áóäåò ëåæàòü â äèàïàçîíå 0...TBLS1; % ýòî îïåðàöèÿ âçÿòèÿ ïî ìîäóëþ
Âîò ôóíêöèÿ ïîëíîñòüþ:
extern int strlen(const char*); extern int strcmp(const char*, const char*); ext
ern int strcpy(const char*, const char*);
name* look(char* p, int ins =0) (* int ii = 0; // õýøèðîâàíèå char* pp = p; while (*pp) ii
; 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); n
= 1; nn-»next = table[ii]; table[ii] = nn; return nn; *)
Ïîñëå âû÷èñëåíèÿ õýø-êîäà ii èìÿ íàõîäèòñÿ ïðîñòûì ïðîìîòðîì ÷åðåç ïîëÿ next. Ïðîâåðêà êàæä
Äîáàâëåíèå íîâîãî name âêëþ÷àåò â ñåáÿ ñîçäàíèå íîâîãî îáúåêòà â ñâîáîäíîé ïàìÿòè ñ ïîìîùüþ

3.1.4 Îáðàáîòêà îøèáîê


Ïîñêîëüêó ïðîãðàììà òàê ïðîñòà, îáðàáîòêà îøèáîê íå ñîòàâëÿåò áîëüøîãî òðóäà. Ôóíêöèÿ îáðàá
int no_of_errors;
double error(char* s) (* cerr « "error: " «« s «« «\n ; no_of_errors++; return 1; *)
Âîçâðàùàåòñÿ çíà÷åíèå ïîòîìó, ÷òî îøèáêè îáû÷íî âñòðå÷àþòñÿ â ñåðåäèíå âû÷èñëåíèÿ âûðàæåíèÿ
×àñòî áûâàåò òàê, ÷òî ïîñëå ïîÿâëåíèÿ îøèáêè ïðîãðàììà äîëæíà çàâåðøèòüñÿ, ïîñêîëüêó íåò íè

3.1.5 Äðàéâåð
Êîãäà âñå ÷àñòè ïðîãðàììû íà ìåñòå, íàì íóæåí òîëüêî äðàéâåð äëÿ èíèöèàëèçàöèè è âñåãî òîãî
int main() (* // âñòàâèòü ïðåäîïðåäåëåííûå èìåíà: insert(«pi»)-»value = 3.14159265358979323
while (cin) (* get_token(); if (curr_tok == END) break; if (curr_tok == PRINT) c
ontinue; cout « expr() «« «\n ; *) return no_of_errors; *)
Ïðèíÿòî îáû÷íî, ÷òî main() âîçâðàùàåò íîëü ïðè íîðìàëíîì çàâåðøåíèè ïðîãðàììû è íå íîëü â ï
Îñíîâíàÿ ðàáîòà öèêëà ÷èòàòü âûðàæåíèÿ è ïèñàòü îòâåò. Ýòî äåëàåò ñòðîêà:
cout « expr() «« «\n ;
Ïðîâåðêà cin íà êàæäîì ïðîõîäå öèêëà îáåñïå÷èâàåò çàâåøåíèå ïðîãðàììû â ñëó÷àå, åñëè ñ ïîòî
while (cin) (* // ... if (curr_tok == PRINT) continue; cout « expr() «« «\n ; *)
ýêâèâàëåíòíî
while (cin) (* // ... if (curr_tok == PRINT) goto end_of_loop; cout « expr() «« «\n ; end_
f_loop *)
Áîëåå ïîäðîáíî öèêëû îïèñûâàþòñÿ â #ñ.9.

3.1.6 Ïàðàìåòðû êîìàíäíîé ñòðîêè


Ïîñëå òîãî, êàê ïðîãðàììà áûëà íàïèñàíà è îòòåñòèðîâàíà, ÿ çàìåòèë, ÷òî ÷àñòî íàáèðàòü âûðà
Êàê óæå ãîâîðèëîñü, ïðîãðàììà çàïóñêàåòñÿ âûçîâîì main(). Êîãäà ýòî ïðîèñõîäèò, main() ïîëó
dc 150/1.1934
ïàðàìåòðû èìåþò çíà÷åíèÿ:
argc 2 argv[0] «dc» argv[1] «150/1.1934»
Íàó÷èòüñÿ ïîëüçîâàòüñÿ ïàðàìåòðàìè êîìàíäíîé ñòðîêè íåëîæíî. Ñëîæíîñòü ñîñòîèò â òîì, êàê è
int main(int argc, char* argv[]) (* switch(argc) (* case 1: // ÷èòàòü èç ñòàíäàðòíîãî ââîäà
gv[1]); break; default: error(«ñëèøêîì ìíîãî ïàðàìåòðîâ»); return 1; *) // êàê ðàíüøå *)
Ïðîãðàììà îñòàëàñü áåç èçìåíåíèé, çà èñêëþ÷åíèåì äîáàëåíèÿ â main() ïàðàìåòðîâ è èñïîëüçîâà
îïåðàòîðå switch. Ìîæíî áûëî áû ëåãêî ìîäèôèöèðîâàòü main() òàê, ÷òîáû îíà ïîëó÷àëà íåñêîëü
Çäåñü êàâû÷êè íåîáõîäèìû, ïîñêîëüêó ; ÿâëÿåòñÿ ðàçäåëòåëåì êîìàíä â ñèñòåìå UNIX.

3.2 Êðàòêàÿ ñâîäêà îïåðàöèé


Îïåðàöèè Ñ++ ïîäðîáíî è ñèñòåìàòè÷åñêè îïèñûâàþòñÿ â #ñ. 7; ïðî÷èòàéòå, ïîæàëóéñòà, ýòîò ðà
Óíàðíûå îïåðàöèè è îïåðàöèè ïðèñâàèâàíèÿ ïðàâîàññîöèòèâíû, âñå îñòàëüíûå ëåâîàññîöèàòèâíû.
Ñâîäêà Îïåðàöèé (÷àñòü 1) =========================================================== :: ðà
++ ïðèðàùåíèå ïîñëå lvalue++ ++ ïðèðàùåíèå äî ++lvalue óìåíüøåíèå ïîñëå lvalue óìåíüøå
=========== « ìåíüøå âûð « âûð
«= ìåíüøå èëè ðàâíî âûð = âûð áîëüøå âûð » âûð »= áîëüøå èëè ðàâíî âûð »= âûð ==========
amp; ïîáèòîâîå È âûð amp; âûð =========================================================== ^
================= ! ïîáèòîâîå âêëþ÷àþùåå ÈËÈ âûð ! âûð ====================================
============================================= !! ëîãè÷åñêîå âêëþ÷àþùåå ÈËÈ âûð !! âûð =====
======= ? : àðèôìåòè÷åñêèé if âûð ? âûð : âûð =============================================
==================
 êàæäîé î÷åð÷åííîé ÷àñòè íàõîäÿòñÿ îïåðàöèè ñ îäèíàêâûì ïðèîðèòåòîì. Îïåðàöèÿ èìååò ïðèîðè

3.2.1 Êðóãëûå ñêîáêè


Ñêîáêàìè ñèíòàêñèñ Ñ++ çëîóïîòðåáëÿåò; êîëè÷åñòâî ñïîñáîâ èõ èñïîëüçîâàíèÿ ïðèâîäèò â çàìåø
if (i«=0 !! max«i) // ...
î÷åâèäíî. Òåì íå ìåíåå, âñåãäà, êîãäà ïðîãðàììèñò ñîìíâàåòñÿ îòíîñèòåëüíî ýòèõ ïðàâèë, ñëåä
if ( (i«=0) !! (max«i) ) // ...
Ïðè óñëîæíåíèè ïîäâûðàæåíèé óïîòðåáëåíèå ñêîáîê ñòàíâèòñÿ áîëåå îáû÷íûì ÿâëåíèåì, íî ñëîæíû
if (i amp;mask == 0) // ...
íå ïðîèñõîäèò ïðèìåíåíèÿ ìàñêè mask ê i è ïîñëåäóþùåé ïðîâåðêè ðåçóëüòàòà íà íîëü. Ïîñêîëüê
if ((i amp;mask) == 0) // ...
Íî, ñ äðóãîé ñòîðîíû, òî, ÷òî ñëåäóþùåå âûðàæåíèå íå ðáîòàåò òàê, êàê ìîæåò îæèäàòü íàèâíûé
if (0 «= a «= 99) // ...
Îíî äîïóñòèìî, íî èíòåðïðåòèðóåòñÿ îíî êàê (0«=a)«=99, ãäå ðåçóëüòàò ïåðâîãî ïîäâûðàæåíèÿ è
if (0«=a amp; amp; a«=99) // ...

3.2.2 Ïîðÿäîê âû÷èñëåíèÿ


Ïîðÿäîê âû÷èñëåíèÿ ïîäâûðàæåíèé â âûðàæåíèè íåîïðåäåëåí. Íàïðèìåð
int i = 1; v[i] = i++;
ìîæåò âû÷èñëÿòüñÿ èëè êàê v[1]=1, èëè êàê v[2]=1. Ïðè îòñóòñòâèè îãðàíè÷åíèé íà ïîðÿäîê âû÷
Îòíîñèòåëüíî îïåðàöèé amp; amp; è !! ãàðàíòèðóåòñÿ, ÷òî èõ ëåâûé îïåðàíä âû÷èñëÿåòñÿ ðàíüøå
f1(v[i],i++); // äâà ïàðàìåòðà f2( (v[i],i++) ) // îäèí ïàðàìåòð
 âûçîâå f1 äâà ïàðàìåòðà, v[i] è i++, è ïîðÿäîê âû÷èëåíèÿ âûðàæåíèé-ïàðàìåòðîâ íåîïðåäåëåí
Ñ ïîìîùüþ ñêîáîê íåëüçÿ çàäàòü ïîðÿäîê âû÷èñëåíèÿ. Íàïðèìåð, a*(b/c) ìîæåò âû÷èñëÿòüñÿ è êà

3.2.3 Óâåëè÷åíèå è óìåíüøåíèå*


 * Ñëåäîâàëî áû ïåðåâîäèòü êàê «èíêðåìåíò» è «äåêðåìåíò», îäíàêî ìû ñëåäîâàëè òåðìèíîëîãèè
ïåðåâ.)
Îïåðàöèÿ ++ èñïîëüçóåòñÿ äëÿ ÿâíîãî âûðàæåíèÿ ïðèðàùåíèÿ âìåñòî åãî íåÿâíîãî âûðàæåíèÿ ñ ïî
Îïåðàöèè ïðèðàùåíèÿ îñîáåííî ïîëåçíû äëÿ óâåëè÷åíèÿ è óìåíüøåíèÿ ïåðåìåííûõ â öèêëàõ. Íàïðè
inline void cpy(char* p, const char* q) (* while (*p++ = *q++) ; *)
Íàïîìíþ, ÷òî óâåëè÷åíèå è óìåíüøåíèå àðèôìåòè÷åñêèõ óêàçàòåëåé, òàê æå êàê ñëîæåíèå è âû÷èò
long(p+1) == long(p)+sizeof(T);
3.2.4 Ïîáèòîâûå ëîãè÷åñêèå îïåðàöèè
Ïîáèòîâûå ëîãè÷åñêèå îïåðàöèè
amp; ! ^ ~ »» ««
ïðèìåíÿþòñÿ ê öåëûì, òî åñòü ê îáúåêòàì òèïà char, short, int, long è èõ unsigned àíàëîãàì,
Îäíî èç ñòàíäàðòíûõ ïðèìåíåíèé ïîáèòîâûõ ëîãè÷åñêèõ îïðàöèé ðåàëèçàöèÿ ìàëåíüêîãî ìíîæåñò
enum state_value (* _good=0, _eof=1, _fail=2, _bad=4 *); // õîðîøî, êîíåö ôàéëà, îøèáêà, ïë
Îïðåäåëåíèå _good íå ÿâëÿåòñÿ íåîáõîäèìûì. ß ïðîñòî õòåë, ÷òîáû ñîñòîÿíèå, êîãäà âñå â ïîðÿ
cout.state = _good;
Íàïðèìåð, òàê ìîæíî ïðîâåðèòü, íå áûë ëè èñïîð÷åí ïîòîê èëè äîïóùåíà îïåðàöèîííàÿ îøèáêà:

if (cout.state amp;(_bad!_fail)) // íå good


Åùå îäíè ñêîáêè íåîáõîäèìû, ïîñêîëüêó amp; èìååò áîëåå âñîêèé ïðèîðèòåò, ÷åì !.
Ôóíêöèÿ, äîñòèãàþùàÿ êîíöà ââîäà, ìîæåò ñîîáùàòü îá ýòîì òàê:
cin.state != _eof;
Îïåðàöèÿ != èñïîëüçóåòñÿ ïîòîìó, ÷òî ïîòîê óæå ìîæåò áûòü èñïîð÷åí (òî åñòü, state==_bad),
cin.state = _eof;
î÷èñòèëî áû ýòîò ïðèçíàê. Ðàçëè÷èå äâóõ ïîòîêîâ ìîæíî íàõîäèòü òàê:
state_value diff = cin.state^cout.state;
 ñëó÷àå òèïà stream_state (ñîñòîÿíèå ïîòîêà) òàêàÿ ðàíîñòü íå î÷åíü íóæíà, íî äëÿ äðóãèõ ï
Ñëåäóåò çàìåòèòü, ÷òî èñïîëüçîâàíèå ïîëåé (#2.5.1) â äåéñòâèòåëüíîñòè ÿâëÿåòñÿ ñîêðàùåííîé
unsigned short middle(int a) (* return (a»»8) amp;0xffff; *)
Íå ïóòàéòå ïîáèòîâûå ëîãè÷åñêèå îïåðàöèè ñ ëîãè÷åñêèìè îïåðàöèÿìè:
amp; amp; !! !
Ïîñëåäíèå âîçâðàùàþò 0 èëè 1, è îíè ãëàâíûì îáðàçîì èïîëüçóþòñÿ äëÿ çàïèñè ïðîâåðêè â îïåðà

3.2.5 Ïðåîáðàçîâàíèå òèïà


Áûâàåò íåîáõîäèìî ÿâíî ïðåîáðàçîâàòü çíà÷åíèå îäíîãî òïà â çíà÷åíèå äðóãîãî. ßâíîå ïðåîáðàç
float r = float(1);
ïåðåä ïðèñâàèâàíèåì ïðåîáðàçóåò öåëîå çíà÷åíèå 1 ê çí÷åíèþ ñ ïëàâàþùåé òî÷êîé 1.0. Ðåçóëüòà
Åñòü äâà ñïîñîáà çàïèñè ÿâíîãî ïðåîáðàçîâàíèÿ òèïà: òðäèöèîííàÿ â C çàïèñü ïðèâåäåíèÿ ê òèï
char* p = (char*)0777;
èëè îïðåäåëèòü íîâîå èìÿ òèïà:
typedef char* Pchar; char* p = Pchar(0777);
Ïî ìîåìó ìíåíèþ, ôóíêöèîíàëüíàÿ çàïèñü â íåòðèâèàëüíûõ ñëó÷àÿõ ïðåäïî÷òèòåëüíà. Ðàññìîòðèì
Pname n2 = Pbase(n1-»tp)-»b_name; //ôóíêöèîíàëüíàÿ çàïèñü Pname n3 = ((Pbase)n2-»tp)-»b_nam
((Pbase)(n2-»tp))-»b_name
Ñ ïîìîùüþ ÿâíîãî ïðåîáðàçîâàíèÿ òèïà ê óêàçàòåëüíûì òïàì ìîæíî ñèìèòèðîâàòü, ÷òî îáúåêò èìå
any_type* p = (any_type*) amp;some_object;
ïîçâîëèò ðàáîòàòü ïîñðåäñòâîì p ñ íåêîòîðûì îáúåêòîì some_object êàê ñ ëþáûì òèïîì any_type
Êîãäà ïðåîáðàçîâàíèå òèïà íå íåîáõîäèìî, åãî ñëåäóåò èáåãàòü. Ïðîãðàììû, â êîòîðûõ èñïîëüçó
int i = 1; char* pc = «asdf»; int* pi = amp;i;
i = (int)pc; pc = (char*)i; // îñòåðåãàéòåñü! çíà÷åíèå pc ìîæåò èçì//íèòüñÿ // íà íåêîòîðûõ
Íà ìíîãèõ ìàøèíàõ íè÷åãî ïëîõîãî íå ïðîèçîéäåò, íî íà äðóãèõ ðåçóëüòàòû áóäóò êàòàñòðîôè÷åñ
 Ñ++ ÿâíîå ïðåîáðàçîâàíèå òèïà îêàçûâàåòñÿ íåíóæíûì âî ìíîãèõ ñëó÷àÿõ, êîãäà C (è äðóãèå ÿ
íåáîëüøîì ÷èñëå ïîäïðîãðàìì.
3.2.6 Ñâîáîäíàÿ ïàìÿòü
Èìåíîâàííûé îáúåêò ÿâëÿåòñÿ ëèáî ñòàòè÷åñêèì, ëèáî àâòîìàòè÷åñêèì (ñì. #2.1.3). Ñòàòè÷åñêèé
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 e
node; n-»oper = curr_tok; n-»left = left; n-»right = term(); left = n; break; default:
return left; *) *)
Ïîëó÷àþùååñÿ äåðåâî ãåíåðàòîð êîäà ìîæåò èñïîëüçîâàòü íàïðèìåð òàê:
void generate(enode* n) (* switch (n-»oper) (* case PLUS: // äåëàåò íå÷òî ñîîòâåòñòâóþùåå d
Îáúåêò, ñîçäàííûé ñ ïîìîùüþ new, ñóùåñòâóåò, ïîêà îí íå áóäåò ÿâíî óíè÷òîæåí delete, ïîñëå
Ñ ïîìîùüþ new ìîæíî òàêæå ñîçäàâàòü âåêòîðà îáúåêòîâ. Íàïðèìåð:
char* save_string(char* p) (* char* s = new char[strlen(p)+1]; strcpy(s,p); retu
rn s; *)
Ñëåäóåò çàìåòèòü, ÷òî ÷òîáû îñâîáîäèòü ïðîñòðàíñòâî, âäåëåííîå new, delete äîëæíà èìåòü âîç
int main(int argc, char* argv[]) (* if (argc « 2) exit(1); char* p = save_string(a
rgv[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; *)
Çàäàííûé ïîëüçîâàòåëåì ðàçìåð âåêòîðà èãíîðèðóåòñÿ çà èñêëþ÷åíèåì íåêîòîðûõ òèïîâ, îïðåäåëÿ
Îïåðàöèè ñâîáîäíîé ïàìÿòè ðåàëèçóþòñÿ ôóíêöèÿìè (#ñ.7.2.3):
void operator new(long); void operator delete(void*);
Ñòàíäàðòíàÿ ðåàëèçàöèÿ new íå èíèöèàëèçèðóåò âîçâðàùàìûé îáúåêò.
×òî ïðîèñõîäèò, êîãäà new íå íàõîäèò ïàìÿòè äëÿ âûäåëíèÿ? Ïîñêîëüêó äàæå âèðòóàëüíàÿ ïàìÿòü
char* p = new char[100000000];
êàê ïðàâèëî, ïðèâîäèò ê êàêèì-òî íåïðèÿòíîñòÿì. Êîãäà ó new íè÷åãî íå ïîëó÷àåòñÿ, îíà âûçûâ
#include «stream.h»
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
g(p) «« «\n ; *)
êàê ïðàâèëî, íå áóäåò ïèñàòü «ñäåëàíî», à áóäåò âìåñòî ýòîãî âûäàâàòü
îïåðàöèÿ new íå ïðîøëà: çà ïðåäåëàìè ïàìÿòè
Ôóíêöèÿ _new_handler ìîæåò äåëàòü è êîå-÷òî ïîóìíåé, ÷åì ïðîñòî çàâåðøàòü âûïîëíåíèå ïðîãðà
Ïî èñòîðè÷åñêèì ïðè÷èíàì new ïðîñòî âîçâðàùàåò óêàçàòåëü 0, åñëè îíà íå ìîæåò íàéòè äîñòàòî
include «stream.h»
main() (* char* p = new char[100000000]; cout « "ñäåëàíî, p = " «« long(p) «« «\n ; *)
âûäàñò
ñäåëàíî, p = 0
Âàì ñäåëàëè ïðåäóïðåæäåíèå! Çàìåòüòå, ÷òî òîò, êòî çàäåò _new_handler, áåðåò íà ñåáÿ çàáîòó

3.3 Ñâîäêà îïåðàòîðîâ


Îïåðàòîðû Ñ++ ñèñòåìàòè÷åñêè è ïîëíîñòüþ èçëîæåíû â #ñ.9, ïðî÷èòàéòå, ïîæàëóéñòà, ýòîò ðàçä
Ñèíòàêñèñ îïåðàòîðà îïåðàòîð: îïèñàíèå (*ñïèñîê_îïåðàòîðîâ opt*) âûðàæåíèå opt

if îïåðàòîð if ( âûðàæåíèå ) îïåðàòîð if ( âûðàæåíèå ) îïåðàòîð else îïåðàòîð switch îïåðàò


while ( âûðàæåíèå ) îïåðàòîð do îïåðàòîð while (âûðàæåíèå) for ( îïåðàòîð âûðàæåíèå opt; âû
case êîíñòàíòíîå_âûðàæåíèå : îïåðàòîð default : îïåðàòîð break ; continue ;
return âûðàæåíèå opt ;
goto èäåíòèôèêàòîð ; èäåíòèôèêàòîð : îïåðàòîð
ñïèñîê_îïåðàòîðîâ: îïåðàòîð îïåðàòîð ñïèñîê_îïåðàòîðîâ
Çàìåòüòå, ÷òî îïèñàíèå ÿâëÿåòñÿ îïåðàòîðîì, è ÷òî íåò îïåðàòîðîâ ïðèñâàèâàíèÿ è âûçîâà ïðîö

3.3.1 Ïðîâåðêè
Ïðîâåðêà çíà÷åíèÿ ìîæåò îñóùåñòâëÿòüñÿ èëè îïåðàòîðîì if, èëè îïåðàòîðîì switch:
if ( âûðàæåíèå ) îïåðàòîð if ( âûðàæåíèå ) îïåðàòîð else îïåðàòîð switch ( âûðàæåíèå ) îïåð
 Ñ++ íåò îòäåëüíîãî áóëåâñêîãî òèïà. Îïåðàöèè ñðàâíåíèÿ
== != « = »=
âîçâðàùàþò öåëîå 1, åñëè ñðàâíåíèå èñòèííî, èíà÷å âîçðàùàþò 0. Íå òàê óæ íåïðèâû÷íî âèäåòü,
 îïåðàòîðå if ïåðâûé (èëè åäèíñòâåííûé) îïåðàòîð âûïîíÿåòñÿ â òîì ñëó÷àå, åñëè âûðàæåíèå í
if (a) // ...
ýêâèâàëåíòíî
if (a != 0) // ...
Ëîãè÷åñêèå îïåðàöèè amp; amp; !! ! íàèáîëåå ÷àñòî èñïîëüçóþòñÿ â óñëîâèÿõ. Îïåðàöèè amp; am
if (p amp; amp; 1«p-»count) // ...
âíà÷àëå ïðîâåðÿåò, ÿâëÿåòñÿ ëè p íå íóëåì, è òîëüêî åñëè ýòî òàê, òî ïðîâåðÿåò 1«p-»count.
Íåêîòîðûå ïðîñòûå îïåðàòîðû if ìîãóò áûòü ñ óäîáñòâîì
çàìåíåíû âûðàæåíèÿìè àðèôìåòè÷åñêîãî if. Íàïðèìåð:
if (a «= d) max = b; else max = a;
ëó÷øå âûðàæàåòñÿ òàê:
max = (a«=b) ? b : a;
Ñêîáêè âîêðóã óñëîâèÿ íåîáÿçàòåëüíû, íî ÿ ñ÷èòàþ, ÷òî êîãäà îíè èñïîëüçóþòñÿ, ïðîãðàììó ëåã
Íåêîòîðûå ïðîñòûå îïåðàòîðû switch ìîæíî ïî-äðóãîìó çïèñàòü â âèäå íàáîðà îïåðàòîðîâ if. Íà
switch (val) (* case 1: f(); break; case 2; g(); break; default: h(); break; *)
èíà÷å ìîæíî áûëî áû çàïèñàòü òàê:
if (val == 1) f(); else if (val == 2) g(); else h();
Ñìûñë òîò æå, îäíàêî ïåðâûé âàðèàíò (switch) ïðåäïî÷òòåëüíåå, ïîñêîëüêó â ýòîì ñëó÷àå ÿâíî
Çàáîòüòåñü î òîì, ÷òî switch äîëæåí êàê-òî çàâåðøàòüñÿ, åñëè òîëüêî âû íå õîòèòå, ÷òîáû âûï
switch (val) (* // îñòîðîæíî case 1: cout « case 1\n ; case 2; cout « «case 2\n ; defaul
ïðè val==1 íàïå÷àòàåò
case 1 case 2 default: case íå íàéäåí
ê âåëèêîìó èçóìëåíèþ íåïîñâÿùåííîãî. Ñàìûé îáû÷íûé ñïñîá çàâåðøèòü ñëó÷àé ýòî break, èíîã
switch (val) (* // îñòîðîæíî
case 0: cout « case 0\n ; case1: case 1: cout «case 1\n ; return; case 2; cout «« «cas
case1; default: cout «« «default: case íå íàéäåí\n ; return; *)
Ïðè îáðàùåíèè ê íåìó ñ val==2 âûäàñò
case 2 case 1
Çàìåòüòå, ÷òî ìåòêà case íå ïîäõîäèò êàê ìåòêà äëÿ óïîðåáëåíèÿ â îïåðàòîðå goto:
goto case 1; // ñèíòàêñè÷åñêàÿ îøèáêà

3.3.2 Goto
Ñ++ ñíàáæåí èìåþùèì äóðíóþ ðåïóòàöèþ îïåðàòîðîì goto.
goto èäåíòèôèêàòîð; èäåíòèôèêàòîð : îïåðàòîð
 îáùåì, â ïðîãðàììèðîâàíèè âûñîêîãî óðîâíÿ îí èìååò î÷åíü ìàëî ïðèìåíåíèé, íî îí ìîæåò áûò
Îäíî èç íåìíîãèõ ðàçóìíûõ ïðèìåíåíèé ñîñòîèò â âûõîäå èç âëîæåííîãî öèêëà èëè ïåðåêëþ÷àòåëÿ
for (int i = 0; i«n; i++) for (int j = 0; j«m; j++) if (nm[i][j] == a) goto found //
íàéäåíî // íå íàéäåíî // ...
found: // íàéäåíî // nm[i][j] == a
Èìååòñÿ òàêæå îïåðàòîð continue, êîòîðûé ïî ñóòè äåëàåò ïåðåõîä íà êîíåö îïåðàòîðà öèêëà, ê

3.4 Êîììåíòàðèè è Âûðàâíèâàíèå


Ïðîäóìàííîå èñïîëüçîâàíèå êîììåíòàðèåâ è ñîãëàñîâàííîå èñïîëüçîâàíèå îòñòóïîâ ìîæåò ñäåëàòü

Íåïðàâèëüíîå èñïîëüçîâàíèå êîììåíòàðèåâ ìîæåò ñåðüåçíî ïîâëèÿòü íà óäîáî÷èòàåìîñòü ïðîãðàìì


1. îñìûñëåí,
2. îïèñûâàåò ïðîãðàììó è
3. íå óñòàðåë.
Íåïîíÿòíûå, äâóñìûñëåííûå è ïðîñòî íåïðàâèëüíûå êîììåòàðèè ñîäåðæàòñÿ â áîëüøèíñòâå ïðîãðàì
Åñëè ÷òî-òî ìîæíî ñôîðìóëèðîâàòü ñðåäñòâàìè ñàìîãî ÿçêà, ñëåäóåò ýòî ñäåëàòü, à íå ïðîñòî î
// ïåðåìåííàÿ "v" äîëæíà áûòü èíèöèàëèçèðîâàíà.
//ïåðåìåííàÿ"v"äîëæíà èñïîëüçîâàòüñÿ òîëüêî ôóíêöèåé «f()».
// âûçâàòü ôóíêöèþ init() ïåðåä âûçîâîì // ëþáîé äðóãîé ôóíêöèè â ýòîì ôàéëå.
// âûçîâèòå ôóíêöèþ î÷èñòêè «cleanup()» â êîíöå âàøåé // ïðîãðàììû.
// íå èñïîëüçóéòå ôóíêöèþ «wierd()».
// ôóíêöèÿ «f()» ïîëó÷àåò äâà ïàðàìåòðà.
Ïðè ïðàâèëüíîì èñïîëüçîâàíèè Ñ++ ïîäîáíûå êîììåíòàðèè êàê ïðàâèëî ñòàíîâÿòñÿ íåíóæíûìè. ×òî
Åñëè ÷òî-òî áûëî ÿñíî ñôîðìóëèðîâàíî íà ÿçûêå, âòîðîé ðàç óïîìèíàòü ýòî â êîììåíòàðèè íå ñë
a = b+c; // a ñòàíîâèòñÿ b+c count++; // óâåëè÷èòü ñ÷åò÷èê
Òàêèå êîììåíòàðèè õóæå ÷åì ïðîñòî èçëèøíè, îíè óâåëè÷âàþò îáúåì òåêñòà, êîòîðûé íàäî ïðî÷èò
Àâòîð ïðåäïî÷èòàåò:
1. Êîììåíòàðèé äëÿ êàæäîãî èñõîäíîãî ôàéëà, ñîîáùàþùèé, äëÿ ÷åãî â öåëîì ïðåäíàçíà÷åíû íàõî
2. Êîììåíòàðèé äëÿ êàæäîé íåòðèâèàëüíîé ôóíêöèè, â êòîðîì ñôîðìóëèðîâàíî åå íàçíà÷åíèå, èñï
3. Íåáîëüøîå ÷èñëî êîììåíòàðèåâ â òåõ ìåñòàõ, ãäå ïðîðàììà íåî÷åâèäíà è/èëè íåïåðåíîñèìà è
4. Î÷åíü ìàëî ÷òî åùå.

Íàïðèìåð:
// tbl.c: Ðåàëèçàöèÿ òàáëèöû èìåí /* Ãàóññîâñêîå èñêëþ÷åíèå ñ ÷àñòè÷íûì Ñì. Ralston: «A fir
// swap() ïðåäïîëàãàåò ðàçìåùåíèå ñòåêà AT amp;T sB20.
/**************************************
Copyright (c) 1984 AT amp;T, Inc. All rights reserved
****************************************/
Óäà÷íî ïîäîáðàííûå è õîðîøî íàïèñàííûå êîììåíòàðèè ñùåñòâåííàÿ ÷àñòü ïðîãðàììû. Íàïèñàíèå
Çàìåòüòå òàêæå, ÷òî åñëè â ôóíêöèè èñïîëüçóþòñÿ èñêëþ÷òåëüíî êîììåíòàðèè //, òî ëþáóþ ÷àñòü

3.5 Óïðàæíåíèÿ
1. (*1) Ïåðåïèøèòå ñëåäóþùèé îïåðàòîð for â âèäå ýêâèâàëåíòíîãî îïåðàòîðà while: for (i=0;
2. (*1) Ïîëíîñòüþ ðàññòàâüòå ñêîáêè â ñëåäóþùèõ âûðàæíèÿõ: a = b + c * d «« 2 amp; 8 a amp;
5 a = b == c ++ a = b = c = 0 a[4][2] *= * b ? c : * d * 2 a-b,c=d
3. (*2) Íàéäèòå ïÿòü ðàçëè÷íûõ êîíñòðóêöèé Ñ++, çíà÷åíèå êîòîðûõ íåîïðåäåëåíî.
4. (*2) Íàéäèòå äåñÿòü ðàçëè÷íûõ ïðèìåðîâ íåïåðåíîñèìîé Ñ++ ïðîãðàììû.
5. (*1) ×òî ïðîèñõîäèò â âàøåé ñèñòåìå, åñëè âû äåëèòå íà íîëü? ×òî ïðîèñõîäèò ïðè ïåðåïîëí
6. (*1) Ïîëíîñòüþ ðàññòàâüòå ñêîáêè â ñëåäóþùèõ âûðàæíèÿõ: *p++ * p ++a (int*)p-»m *p.m *a
7. (*2) Íàïèøèòå ôóíêöèè: strlen(), êîòîðàÿ âîçâðàùàåò äëèíó ñòðîêè, strcpy(), êîòîðàÿ êîïè
8. (*1) Ïîñìîòðèòå, êàê âàø êîìïèëÿòîð ðåàãèðóåò íà îøèáêè: a := b+1; if (a = 3) // ... if
9. (*2) Íàïèøèòå ôóíêöèþ cat(), ïîëó÷àþùóþ äâà ñòðîêîâûõ ïàðàìåòðà è âîçâðàùàþùóþ ñòðîêó, ê
10. (*2) ×òî äåëàåò ñëåäóþùàÿ ïðîãðàììà?
void send(register* to, register* from, register count) // Ïîëåçíûå êîììåíòàðèè íåñîìíåííî
do (* *to++ = *from++; case 7: do (* *to++ = *from++; case 6: do (* *to++ = *fro
m++; 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); *) *) Çà÷åì êòî-òî ìîã íàïèñàòü íå÷òî ïîõîæåå?
11. (*2) Íàïèøèòå ôóíêöèþ atoi(), êîòîðàÿ ïîëó÷àåò ñòðêó, ñîäåðæàùóþ öèôðû, è âîçâðàùàåò ñî
12. (*2) Ïåðåïèøèòå get_token() (#3.1.2), ÷òîáû îíà çà îäèí ðàç ÷èòàëà ñòðîêó â áóôåð, à çà
13. (*2) Äîáàâüòå â íàñòîëüíûé êàëüêóëÿòîð èç #3.1 òàêèå ôóíêöèè, êàê sqrt(), log() è sin()
14. (*3) Äàéòå ïîëüçîâàòåëþ âîçìîæíîñòü îïðåäåëÿòü ôóíöèè â íàñòîëüíîì êàëüêóëÿòîðå. Ïîäñêà
15. (*1.5) Ïðåîáðàçóéòå íàñòîëüíûé êàëüêóëÿòîð òàê, ÷òáû âìåñòî ñòàòè÷åñêèõ ïåðåìåííûõ name
16. (*2.5) Íàïèøèòå ïðîãðàììó, êîòîðàÿ âûáðàñûâàåò êîìåíòàðèè èç Ñ++ ïðîãðàììû. Òî åñòü, ÷è
17. (*2) Ïîñìîòðèòå êàêèå-íèáóäü ïðîãðàììû, ÷òîáû ïîíÿòü ïðèíöèï ðàçëè÷íûõ ñòèëåé êîììåíòèð

Ãëàâà 4 Ôóíêöèè è Ôàéëû


Èòåðàöèÿ ñâîéñòâåííà ÷åëîâåêó, ðåêóðñèÿ áîæåñòâåííà.
    Ë. Ïèòåð Äîé÷

Âñå íåòðèâèàëüíûå ïðîãðàììû ñîáèðàþòñÿ èç íåñêîëüêèõ ðàçäåëüíî êîìïèëèðóåìûõ åäèíèö (èõ ïðè

4.1 Ââåäåíèå
Èìåòü âñþ ïðîãðàììó â îäíîì ôàéëå îáû÷íî íåâîçìîæíî, ïîñêîëüêó êîäû ñòàíäàðòíûõ áèáëèîòåê è
Ðàññìîòðèì ïðèìåð ñ êàëüêóëÿòîðîì. Îí áûë ïðåäñòàâëåí â âèäå îäíîãî èñõîäíîãî ôàéëà. Åñëè â
Ïðîãðàììà, ñîñòîÿùàÿ èç íåñêîëüêèõ ðàçäåëüíî êîìïèëèðóìûõ ôàéëîâ, äîëæíà áûòü ñîãëàñîâàííîé
 * èëè ëèíêåð. (ïðèì. ïåðåâ.)
Ïðîãðàììèñò ìîæåò ñêîìïåíñèðîâàòü íåäîñòàòîê ïîääåðæêè ñî ñòîðîíû êîìïîíîâùèêà, ïðåäîñòàâèâ
íàõîäÿòñÿ â îòäåëüíî êîìïèëèðóåìûõ ÷àñòÿõ. Ñðåäñòâà, êîòîðûå ýòî îáåñïå÷èâàþò, â âàøåé ñèñò
 * C ðàçðàáîòàí òàê, ÷òîáû â áîëüøèíñòâå ñëó÷àåâ ïîçâëÿòü îñóùåñòâëÿòü íåÿâíóþ êîìïîíîâêó.

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. Êëþ÷åâîå
// 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
Ñëåäóþùàÿ ïðîãðàììà íå ÿâëÿåòñÿ Ñ++ ïðîãðàììîé (õîòÿ C ïðîãðàììîé ÿâëÿåòñÿ):
// file1.c: int a; int f() (* return a; *)
// file2.c: int a; int g() (* return f(); *)
Âî-ïåðâûõ, file2.c íå Ñ++, ïîòîìó ÷òî f() íå áûëà îïèñàíà, è ïîýòîìó êîìïèëÿòîð áóäåò íåäîâ
Èìÿ ìîæíî ñäåëàòü ëîêàëüíûì â ôàéëå, îïèñàâ åãî static. Íàïðèìåð:
// file1.c: static int a = 6; static int f() (* /* ... */ *)
// file2.c: static int a = 7; static int f() (* /* ... */ *)
Ïîñêîëüêó êàæäîå a è f îïèñàíî êàê static, ïîëó÷àþùàÿñÿ â ðåçóëüòàòå ïðîãðàììà ÿâëÿåòñÿ ïðà
Êîãäà ïåðåìåííûå è ôóíêöèè ÿâíî îïèñàíû êàê static, ÷àñòü ïðîãðàììû ëåã÷å ïîíÿòü (âàì íå íà
Ðàññìîòðèì äâà ôàéëà:
// 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-ôóíêöèÿì è îïðåäåëåíèÿ

4.3 Çàãîëîâî÷íûå Ôàéëû


Òèïû âî âñåõ îïèñàíèÿõ îäíîãî è òîãî æå îáúåêòà äîëæíû áûòü ñîãëàñîâàííûìè. Îäèí èç ñïîñîáî
 * Ëåãêî èçìåíèòü îäèí êîìïîíîâùèê, íî ñäåëàâ ýòî è íàïñàâ ïðîãðàììó, êîòîðàÿ çàâèñèò îò ó
Ìåõàíèçì âêëþ÷åíèÿ ñ ïîìîùüþ #include ýòî ÷ðåçâû÷àéíî ïðîñòîå ñðåäñòâî îáðàáîòêè òåêñòà ä
#include «to_be_included»
çàìåùàåò ñòðîêó, â êîòîðîé âñòðåòèëîñü #include, ñîäåæèìûì ôàéëà «to_be_included». Åãî ñîäå
CC -E file.c
äëÿ ïðåïðîöåññèðîâàíèÿ ôàéëà file.c òî÷íî òàêæå, êàê ýòî ñäåëàëà áû CC ïåðåä çàïóñêîì ñîáñò
#include «stream.h» //èç ñòàíäàðòíîé äèðåêòîðèè âêëþ÷åíèÿ #define «myheader.h» // èç òåêóùå
Èñïîëüçîâàíèå «» èìååò òî ïðåèìóùåñòâî, ÷òî â ïðîãðàììó ôàêòè÷åñêîå èìÿ äèðåêòîðèè âêëþ÷åíè
#include « stream.h » // íå íàéäåò «stream.h»
Ìîæåò ïîêàçàòüñÿ, ÷òî ïåðåêîìïèëèðîâàòü ôàéë çàíîâî êàäûé ðàç, êîãäà îí êóäà-ëèáî âêëþ÷àåòñ
Ñëåäóþùåå ýìïèðè÷åñêîå ïðàâèëî îòíîñèòåëüíî òîãî, ÷òî ñëåäóåò, à ÷òî íå ñëåäóåò ïîìåùàòü â
 çàãîëîâî÷íîì ôàéëå ìîãóò ñîäåðæàòüñÿ:
Îïðåäåëåíèÿ òèïîâ struct point (* int x, y; *) Îïèñàíèÿ ôóíêöèé extern int strlen(const cha
, true *); Äèðåêòèâû include #include «signal.h» Îïðåäåëåíèÿ ìàêðîñîâ #define Case break;ca
íî íèêîãäà
Îïðåäåëåíèÿ îáû÷íûõ ôóíêöèé char get() (* return *p++; *) Îïðåäåëåíèÿ äàííûõ int a;
Îïðåäåëåíèÿ ñëîæíûõ êîíñòàíòíûõ îáúåêòîâ const tbl[]=(*/* ... */ *)
 ñèñòåìå UNIX ïðèíÿòî, ÷òî çàãîëîâî÷íûå ôàéëû èìåþò ñóôôèêñ (ðàñøèðåíèå) .h. Ôàéëû, ñîäåðæ
Ïðè÷èíà òîãî, ïî÷åìó â çàãîëîâî÷íûõ ôàéëàõ äîïóñêàåòñÿ îïðåäåëåíèå ïðîñòûõ êîíñòàíò, íî íå

4.3.1 Îäèí Çàãîëîâî÷íûé Ôàéë


Ïðîùå âñåãî ðåøèòü ïðîáëåìó ðàçáèåíèÿ ïðîãðàììû íà íåêîëüêî ôàéëîâ ïîìåñòèâ ôóíêöèè è îïðåä
// dc.h: îáùèå îïèñàíèÿ äëÿ êàëüêóëÿòîðà
enum token_value (* NAME, NUMBER, END, PLUS='+', MINUS='-', MUL='*', DIV='/', PR
INT=';', ASSIGN='=', LP='(', RP=')' *);
extern int no_of_errors; extern double error(char* s); extern token_value get_to
ken(); 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); inline name* insert(char* s) (* return
look(s,1); *)
Åñëè îïóñòèòü ôàêòè÷åñêèé êîä, òî lex.c áóäåò âûãëÿäåòü ïðèìåðíî òàê:
// lex.c: ââîä è ëåêñè÷åñêèé àíàëèç #include «dc.h»
#include «ctype.h»
token_value curr_tok; double number_value; char name_string[256];
token_value get_token() (* /* ... */ *)
Çàìåòüòå, ÷òî òàêîå èñïîëüçîâàíèå çàãîëîâî÷íûõ ôàéëîâ ãàðàíòèðóåò, ÷òî êàæäîå îïèñàíèå â çà
extern token_value get_token(); // ... token_value get_token() (* /* ... */ *)
Ýòî îáåñïå÷èâàåò òî, ÷òî êîìïèëÿòîð îáíàðóæèò ëþáóþ íñîãëàñîâàííîñòü â òèïàõ, óêàçàííûõ äëÿ
Ôàéë 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 ñàì îïèñûâàåò ñòàíäàðòíûå ôóíêöèè äëÿ ðàáîòû ñî ñòðîêàìè, ïîýòîìó íèê
È 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[]) (* /* ... */ *)
Âàæíûé ñëó÷àé, êîãäà ðàçìåð çàãîëîâî÷íûõ ôàéëîâ ñòàíâèòñÿ ñåðüåçíîé ïîìåõîé. Íàáîð çàãîëîâî

4.3.2 Ìíîæåñòâåííûå Çàãîëîâî÷íûå Ôàéëû


Ñòèëü ðàçáèåíèÿ ïðîãðàììû ñ îäíèì çàãîëîâî÷íûì ôàéëîì íàèáîëåå ïðèãîäåí â òåõ ñëó÷àÿõ, êîãä
Ðàññìàòðèâàÿ îðãàíèçàöèþ êàëüêóëÿòîðà, ìû çàìå÷àåì, ÷òî error() èñïîëüçóåòñÿ ïî÷òè êàæäîé ô
// error.h: îáðàáîòêà îøèáîê
extern int no_errors;
extern double error(char* s);
// error.c
#include «stream.h» #include «error.h»
int no_of_errors;
double error(char* s) (* /* ... */ *)
Ïðè òàêîì ñòèëå èñïîëüçîâàíèÿ çàãîëîâî÷íûõ ôàéëîâ .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 «string.h» #include «table.h»
const TBLSZ = 23; name* table[TBLSZ];
name* look(char* p; int ins) (* /* ... */ *)
Çàìåòüòå, ÷òî îïèñàíèÿ ôóíêöèé ðàáîòû ñî ñòðîêàìè òåïåðü âêëþ÷àþòñÿ èç «string.h». Ýòî èñêë
// lex.h: îïèñàíèÿ äëÿ ââîäà è ëåêñè÷åñêîãî àíàëèçà
enum token_value (* NAME, NUMBER, END, PLUS='+', MINUS='-', MUL='*', DIV='/', PR
INT=';', ASSIGN='=', LP='(', RP=')' *);
extern token_value curr_tok; extern double number_value; extern char name_string
[256];
extern token_value get_token();
Ýòîò èíòåðôåéñ ëåêñè÷åñêîãî àíàëèçàòîðà äîñòàòî÷íî áåïîðÿäî÷åí. Íåäîñòàòîê â íàäëåæàùåì òèï
// lex.c: îïðåäåëåíèÿ äëÿ ââîäà è ëåêñè÷åñêîãî àíàëèçà
#include «stream.h» #include «ctype.h» #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 «stream.h» #include «error.h» #include «lex.h» #include «syn.h» #include «table.h»
«string.h»
main(int argc, char* argv[]) (* /* ... */ *)
Ñêîëüêî çàãîëîâî÷íûõ ôàéëîâ èñïîëüçîâàòü â ïðîãðàììå, çàâèñèò îò ìíîãèõ ôàêòîðîâ. Ìíîãèå èç

4.3.3 Ñîêðûòèå Äàííûõ


Èñïîëüçóÿ çàãîëîâî÷íûå ôàéëû ïîëüçîâàòåëü ìîæåò îïðåäëÿòü ÿâíûé èíòåðôåéñ, ÷òîáû îáåñïå÷èòü
Çàìåòüòå, ÷òî òàêîé ñòèëü êîìïîíîâêè íå ðåêîìåíäóåòñÿ:
// 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() (*
n f(a+c); *)
Ïîñêîëüêó îïèñàíèÿ extern â file2.c íå âêëþ÷àþòñÿ âìåñòå ñ îïðåäåëåíèÿìè â ôàéëå file1.c, ê
Ïîëüçîâàòåëü ìîæåò çàùèòèòü ôàéë îò òàêîé íåäèñöèïëèíðîâàííîé êîìïîíîâêè, îïèñàâ èìåíà, êîò
// table.c: îïðåäåëåíèÿ òàáëèöû èìåí
#include «error.h» #include «string.h» #include «table.h»
const TBLSZ = 23; static name* table[TBLSZ];
name* look(char* p; int ins) (* /* ... */ *)
Ýòî ãàðàíòèðóåò, ÷òî ëþáîé äîñòóï ê table äåéñòâèòåëüíî áóäåò îñóùåñòâëÿòüñÿ èìåííî ÷åðåç l

4.4 Ôàéëû êàê Ìîäóëè


 ïðåäûäóùåì ðàçäåëå .c è .h ôàéëû âìåñòå îïðåäåëÿëè ÷àñòü ïðîãðàììû. Ôàéë .h ÿâëÿåòñÿ èíòå
Èíîãäà âîçíèêàåò ñëîæíîñòü, ñîñòîÿùàÿ â òîì, ÷òî ïîäîíàÿ ãèáêîñòü äîñòèãàåòñÿ áåç ôîðìàëüíî
 äðóãèõ ñëó÷àÿõ ìîæåò âîçíèêíóòü òà ïðîáëåìà, ÷òî ìäóëü îïðåäåëÿåò ìíîæåñòâî îáúåêòîâ, à í
Êàæäûé ñòàòè÷åñêè ðàçìåùåííûé îáúåêò ïî óìîë÷àíèþ èíèöàëèçèðóåòñÿ íóëåì, ïðîãðàììèñò ìîæåò

4.5 Êàê Ñîçäàòü Áèáëèîòåêó


Ôðàçû òèïà «ïîìåùåí â áèáëèîòåêó» è «èùåòñÿ â êàêîé-òî áèáëèîòåêå» èñïîëüçóþòñÿ ÷àñòî (è â
Áèáëèîòåêà â ñâîåé îñíîâå ÿâëÿåòñÿ ìíîæåñòâîì .o ôàéëîâ, ïîëó÷åííûõ â ðåçóëüòàòå êîìïèëÿöèè
extern double sqrt(double); // ïîäìíîæåñòâî «math.h» extern double sin(double); extern doub
xtern double exp(double); extern double log(double);
à îïðåäåëåíèÿ ýòèõ ôóíêöèé õðàíèëèñü áû, ñîîòâåòñòâåííî, â ôàéëàõ sqrt.c, sin.c, cos.c, exp
Áèáëèîòåêó ñ èìåíåì 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 l
og.o $ ranlib math.a
Âíà÷àëå èñõîäíûå ôàéëû êîìïèëèðóþòñÿ â ýêâèâàëåíòíûå èì îáúåêòíûå ôàéëû. Çàòåì èñïîëüçóåòñÿ
$ CC myprog.c math.a
Òåïåðü ðàçáåðåìñÿ, â ÷åì æå ïðåèìóùåñòâà èñïîëüçîâàíèÿ math.a ïåðåä ïðîñòî íåïîñðåäñòâåííûì
$ CC myprog.c sqrt.o sin.o cos.o exp.o log.o
Äëÿ áîëüøèíñòâà ïðîãðàìì îïðåäåëèòü ïðàâèëüíûé íàáîð .o ôàéëîâ, íåñîìíåííî, íåïðîñòî. Â ïðè
$ CC myprog.c sqrt.o cos.o
Íî ýòî íå òàê, ïîñêîëüêó cos.c èñïîëüçóåò sin.c.
Êîìïîíîâùèê, âûçûâàåìûé êîìàíäîé CC äëÿ îáðàáîòêè .a ôàéëà (â äàííîì ñëó÷àå, ôàéëà math.a)
Äðóãèìè ñëîâàìè, èñïîëüçóÿ áèáëèîòåêó ìîæíî âêëþ÷àòü ìíîãî îïðåäåëåíèé ñ ïîìîùüþ îäíîãî èìå
íèêîãäà íå âèäíû ïîëüçîâàòåëþ), è, êðîìå òîãî, îáåñïå÷èòü, ÷òî â ðåçóëüòàòå â ïðîãðàììó áóä

4.6 Ôóíêöèè
Îáû÷íûé ñïîñîá ñäåëàòü ÷òî-ëèáî â Ñ++ ïðîãðàììå ýòî âûçâàòü ôóíêöèþ, êîòîðàÿ ýòî äåëàåò.

4.6.1 Îïèñàíèÿ Ôóíêöèé


Îïèñàíèå ôóíêöèè çàäàåò èìÿ ôóíêöèè, òèï âîçâðàùàåìîãî ôóíêöèåé çíà÷åíèÿ (åñëè òàêîâîå åñòü
extern double sqrt(double); extern elem* next_elem(); extern char* strcpy(char*
to, const char* from); extern void exit(int);
Ñåìàíòèêà ïåðåäà÷è ïàðàìåòðîâ èäåíòè÷íà ñåìàíòèêå èíèöàëèçàöèè. Ïðîâåðÿþòñÿ òèïû ïàðàìåòðîâ
double sr2 = sqrt(2);
áóäåò ïðàâèëüíî îáðàùàòüñÿ ê ôóíêöèè 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), à ÷òîáû

4.6.3 Ïåðåäà÷à Ïàðàìåòðîâ


Êîãäà âûçûâàåòñÿ ôóíêöèÿ, äîïîëíèòåëüíî âûäåëÿåòñÿ ïìÿòü ïîä åå ôîðìàëüíûå ïàðàìåòðû, è êàæ
ñòàíäàðòíûå è îïðåäåëåííûå ïîëüçîâàòåëåì ïðåîáðàçîâàíèÿ òïîâ. Åñòü îñîáûå ïðàâèëà äëÿ ïåðåä
void f(int val, int amp; ref) (* val++; ref++; *)
Êîãäà âûçûâàåòñÿ f(), val++ óâåëè÷èâàåò ëîêàëüíóþ êîïèþ ïåðâîãî ôàêòè÷åñêîãî ïàðàìåòðà, òîã
int i = 1; int j = 1; f(i,j);
óâåëè÷èâàåò j, íî íå i. Ïåðâûé ïàðàìåòð i, ïåðåäàåòñÿ ïî çíà÷åíèþ, âòîðîé ïàðàìåòð j, ï
void f(const large amp; arg) (* // çíà÷åíèå «arg» íå ìîæåò áûòü èçìåíåíî *)
Àíàëîãè÷íî, îïèñàíèå ïàðàìåòðà óêàçàòåëÿ êàê const ñîîùàåò ÷èòàòåëþ, ÷òî çíà÷åíèå îáúåêòà,
extern int strlen(const char*); // èç «string.h» extern char* strcpy(char* to, const cha
r* from); extern int strcmp(const char*, const char*);
Âàæíîñòü òàêîé ïðàêòèêè âîçðàñòàåò ñ ðàçìåðîì ïðîãðàììû.
Çàìåòüòå, ÷òî ñåìàíòèêà ïåðåäà÷è ïàðàìåòðîâ îòëè÷íà îò ñåìàíòèêè ïðèñâàèâàíèÿ. Ýòî âàæíî äë

4.6.4 Âîçâðàò Çíà÷åíèÿ


Èç ôóíêöèè, êîòîðàÿ íå îïèñàíà êàê void, ìîæíî (è äîëíî) âîçâðàùàòü çíà÷åíèå. Âîçâðàùàåìîå
int fac(int n) (*return (n»1) ? n*fac(n-1) : 1; *)
 ôóíêöèè ìîæåò áûòü áîëüøå îäíîãî îïåðàòîðà return: int fac(int n) (* if (n » 1) return n*
Êàê è ñåìàíòèêà ïåðåäà÷è ïàðàìåòðîâ, ñåìàíòèêà âîçâðàòà ôóíêöèåé çíà÷åíèÿ èäåíòè÷íà ñåìàíòè
double f() (* // ... return 1; // íåÿâíî ïðåîáðàçóåòñÿ ê double(1) *)
Êàæäûé ðàç, êîãäà âûçûâàåòñÿ ôóíêöèÿ, ñîçäàåòñÿ íîâàÿ êîïèÿ åå ïàðàìåòðîâ è àâòîìàòè÷åñêèõ
int* f() (* int local = 1; // ... return amp;local; // òàê íå äåëàéòå *)
Ýòà îøèáêà ìåíåå îáû÷íà, ÷åì ýêâèâàëåíòíàÿ îøèáêà ïðè èñïîëüçîâàíèè ññûëîê:
int amp; f() (* int local = 1; // ... return local; // òàê íå äåëàéòå *)
Ê ñ÷àñòüþ, î òàêèõ âîçâðàùàåìûõ çíà÷åíèÿõ ïðåäóïðåæäàåò êîìïèëÿòîð. Âîò äðóãîé ïðèìåð:
int amp; f() (* return 1;*) // òàê íå äåëàéòå

4.6.5 Âåêòîðíûå Ïàðàìåòðû


Åñëè â êà÷åñòâå ïàðàìåòðà ôóíêöèè èñïîëüçóåòñÿ âåêòîð, òî ïåðåäàåòñÿ óêàçàòåëü íà åãî ïåðâû
int strlen(const char*);
void f() (* char v[] = «a vector» strlen(v); strlen(«Nicholas»); *);
Èíà÷å ãîâîðÿ, ïðè ïåðåäà÷å êàê ïàðàìåòð ïàðàìåòð òèïà T[] ïðåîáðàçóåòñÿ ê T*. Ñëåäîâàòåëüíî
Ðàçìåð âåêòîðà íåäîñòóïåí âûçûâàåìîé ôóíêöèè. Ýòî ìîæåò áûòü íåóäîáíî, íî ýòó ñëîæíîñòü ìîæ
ïàðàìåòð, êîòîðûé çàäàåò ðàçìåð, èëè îïðåäåëèòü òèï, ñîäåðæùèé óêàçàòåëü è èíäèêàòîð äëèíû,
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«dim1; i++) (* for (int j
= 0; j 4; j++) cout «« " " «« m[i][j]; cout «« «\n ; *) *)
Ñëîæíûé ñëó÷àé âîçíèêàåò, êîãäà íóæíî ïåðåäàâàòü îáå ðàçìåðíîñòè. «Î÷åâèäíîå ðåøåíèå» ïðîñò
void print_mij(int m[][], int dim1, int dim2) // îøèáêà (* for (int i = 0; i«dim1; i++) (*
(int j = 0; j dim2; j++) cout «« " " «« m[i][j]; // ñþðïðèç! cout «« «\n ; *) *)
Âî-ïåðâûõ, îïèñàíèå ïàðàìåòðà m[][] íåäîïóñòèìî, ïîêîëüêó äëÿ íàõîæäåíèÿ ïîëîæåíèÿ ýëåìåíòà
void print_mij(int** m, int dim1, int dim2) (* for (int i = 0; i«dim1; i++) (* for
(int j = 0; j dim2; j++) cout «« " " «« (int*)m[i*dim2+j]; // òóìàííî cout «« «\n ; *) *)
Âûðàæåíèå, êîòîðîå ïðèìåíÿåòñÿ äëÿ äîñòóïà ê ýëåìåíòàì, ýêâèâàëåíòíî òîìó, êîòîðîå ãåíåðèðó
int* v = (int*)m; // ... v[i*dim2+j]

4.6.6 Ïàðàìåòðû ïî Óìîë÷àíèþ


×àñòî â ñàìîì îáùåì ñëó÷àå ôóíêöèè òðåáóåòñÿ áîëüøå ïðàìåòðîâ, ÷åì â ñàìîì ïðîñòîì è áîëåå
extern char* hex(long, int =0);
Èíèöèàëèçàòîð âòîðîãî ïàðàìåòðà ÿâëÿåòñÿ ïàðàìåòðîì ïî óìîë÷àíèþ. Òî åñòü, åñëè â âûçîâå äà
cout « ** «« hex(31) «« hex(32,3) «« «** ;
èíòåðïðåòèðóåòñÿ êàê
cout « ** «« hex(31,0) «« hex(32,3) «« «** ;
è íàïå÷àòàåò:
** 1f 20**
Ïàðàìåòð ïî óìîë÷àíèþ ïðîõîäèò ïðîâåðêó òèïà âî âðåìÿ îïèñàíèÿ ôóíêöèè è âû÷èñëÿåòñÿ âî âðå
int f(int, int =0, char* =0); // ok int g(int =0, int =0, char*); // îøèáêà int f(int =0, i
t, char* =0); // îøèáêà
Çàìåòüòå, ÷òî â ýòîì êîíòåêñòå ïðîáåë ìåæäó * è = ÿâëåòñÿ ñóùåñòâåííûì (*= ÿâëÿåòñÿ îïåðàöè
int nasty(char*=0); // ñèíòàêñè÷åñêàÿ îøèáêà

4.6.7 Ïåðåãðóçêà Èìåí Ôóíêöèé


Êàê ïðàâèëî, äàâàòü ðàçíûì ôóíêöèÿì ðàçíûå èìåíà ìûñëü õîðîøàÿ, íî êîãäà íåêîòîðûå ôóíêöè
overload print; void print(int); void print(char*);
×òî êàñàåòñÿ êîìïèëÿòîðà, åäèíñòâåííîå îáùåå, ÷òî èìåþò ôóíêöèè ñ îäèíàêîâûì èìåíåì, ýòî èì
1. Èñêàòü ôóíêöèþ ñîîòâåòñòâóþùóþ òî÷íî, è èñïîëüçîâàòü åå, åñëè îíà íàéäåíà,
2. Èñêàòü ñîîòâåòñòâóþùóþ ôóíêöèþ èñïîëüçóÿ âñòðîåííûå ïðåîáðàçîâàíèÿ è èñïîëüçîâàòü ëþáóþ
3. Èñêàòü ñîîòâåòñòâóþùóþ ôóíêöèþ èñïîëüçóÿ ïðåîáðàçâàíèÿ, îïðåäåëåííûå ïîëüçîâàòåëåì (#6.3
Íàïðèìåð:
overload print(double), print(int);
void f(); (* print(1); print(1.0); *)
Ïðàâèëî òî÷íîãî ñîîòâåòñòâèÿ ãàðàíòèðóåò, ÷òî f íàïå÷òàåò 1 êàê öåëîå è 1.0 êàê ÷èñëî ñ ïëà
Ê ïàðàìåòðàì ôóíêöèé ñ ïåðåãðóæåííûìè èìåíàìè ñòàíäàðíûå Ñ++ ïðàâèëà íåÿâíîãî ïðåîáðàçîâàíè
Âîò ïðèìåð, â êîòîðîì ïðåîáðàçîâàíèå íåîáõîäèìî:
overload print(double), print(long);
void f(int a); (* print(a); *)
Çäåñü a ìîæåò áûòü íàïå÷àòàíî èëè êàê double, èëè êàê long. Íåîäíîçíà÷íîñòü ðàçðåøàåòñÿ ÿâí
Ïðè ýòèõ ïðàâèëàõ ìîæíî ãàðàíòèðîâàòü, ÷òî êîãäà ýôôåòèâíîñòü èëè òî÷íîñòü âû÷èñëåíèé äëÿ è
overload pow; int pow(int, int); double pow(double, double); // èç «math.h» complex pow(
double, complex); // èç «complex.h» complex pow(complex, int); complex pow(complex, doub
le); 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 +
3,5);
Òàêàÿ ôóíêöèÿ ïîëàãàåòñÿ íà èíôîðìàöèþ, êîòîðàÿ íåäîòóïíà êîìïèëÿòîðó ïðè èíòåðïðåòàöèè åå
îòêîìïèëèðóåòñÿ è â ëó÷øåì ñëó÷àå ïðèâåäåò ê êàêîé-íáóäü ñòðàííîãî âèäà âûäà÷å. Î÷åâèäíùå õ

5.3.2 Çàêîí÷åííûé Êëàññ


Ïðîãðàììèðîâàíèå áåç ñîêðûòèÿ äàííûõ (ñ ïðèìåíåíèåì ñòðóêòóð) òðåáóåò ìåíüøåé ïðîäóìàííîñòè
Âîò ïðèìåð çàêîí÷åííîãî òèïà intset, êîòîðûé ðåàëèçóåò ïîíÿòèå «ìíîæåñòâî öåëûõ»:
class intset (* int cursize, maxsize; int *x; public: intset(int m, int n); // ñàìîå áîëüøå
~intset();
int member(int t); // ÿâëÿåòñÿ ëè t ýëåìåíòîì? void insert(int t); // äîáàâèòü "t" â ìíîæåñ
void iterate(int amp; i) (* i = 0; *) int ok(int amp; i) (* return i«cursize; *) i
nt next(int amp; i) (* return x[i++]; *) *);
×òîáû ïðîòåñòèðîâàòü ýòîò êëàññ, ìîæíî ñîçäàòü è ðàñï÷àòàòü ìíîæåñòâî ñëó÷àéíûõ öåëûõ ÷èñåë
#include «stream.h»
void error(char* s) (* cerr « "set: " «« s «« «\n ; exit(1); *)
Êëàññ intset èñïîëüçóåòñÿ â main(), êîòîðàÿ ïðåäïîëàãàåò äâà öåëûõ ïàðàìåòðà. Ïåðâûé ïàðàìå
main(int argc, char* argv[]) (* if (argc != 3) error(«îæèäàåòñÿ äâà ïàðàìåòðà»); int count
/ â äèàïàçîíå 1..n intset s(m,n);
while (count«m) (* int t = randint(n);
if (s.member(t)==0) (* s.insert(t); count++; *) *)
print_in_order( amp;s); *)
 ïðîãðàììå, äëÿ êîòîðîé òðåáóåòñÿ äâà ïàðàìåòðà, ñ÷å÷èê ÷èñëà ïàðàìåòðîâ, argc, äîëæåí ðàâ
extern int atoi(char*);
ôóíêöèÿ atoi() ýòî ñòàíäàðòíàÿ áèáëèîòå÷íàÿ ôóíêöèÿ äëÿ ïðåîáðàçîâàíèÿ ïðåäñòàâëåíèÿ öåëîãî
extern int rand(); // Íå î÷åíü ñëó÷àéíûå, áóäüòå îñòîðîæíû
int randint(int u) // â äèàïàçîíå 1..u (* int r = rand(); if (r « 0) r = -r; return 1 + r%u
Ïîäðîáíîñòè ðåàëèçàöèè êëàññà äîëæíû ïðåäñòàâëÿòü äëÿ ïîëüçîâàòåëÿ âåñüìà íåçíà÷èòåëüíûé èí
intset::intset(int m, int n)//ñàìîå áîëüøåå,m int'îâ â 1..n (* if (m«1 !! n m) error(«íåäîï
maxsize]; *)
intset::~intset() (* delete x; *)
Öåëûå ÷èñëà âñòàâëÿþòñÿ, ïîýòîìó îíè õðàíÿòñÿ â âîçðàòàþùåì ïîðÿäêå:
void intset::insert(int t) (* if (++cursize » maxsize) error(«ñëèøêîì ìíîãî ýëåìåíòîâ»); in
while (i»0 amp; amp; x[i-1]»x[i]) (* int t = x[i]; // ïåðåñòàâèòü x[i] è [i-1] x[i] = x[i-1
*) *)
Äëÿ íàõîæäåíèÿ ÷ëåíîâ èñïîëüçóåòñÿ ïðîñòî äâîè÷íûé ïèñê:
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; // íå íàéäåíî *)
È, íàêîíåö, íàì íóæíî îáåñïå÷èòü ìíîæåñòâî îïåðàöèé, ÷òîáû ïîëüçîâàòåëü ìîã îñóùåñòâëÿòü öè
Äàåòñÿ òðè ôóíêöèè: iterate() äëÿ èíèöèàëèçàöèè èòåðöèè, ok() äëÿ ïðîâåðêè, åñòü ëè ñëåäóþù
class intset (* // ... void iterate(int amp; i) (* i = 0; *) int ok(int amp; i)
(* return i«cursize; *) int next(int amp; i) (* return x[i++]; *) *);
×òîáû äàòü âîçìîæíîñòü ýòèì òðåì îïåðàöèÿì ðàáîòàòü ñîìåñòíî è ÷òîáû çàïîìíèòü, êóäà äîøåë
void print_in_order(intset* set) (* int var; set-»iterate(var); while (set-»ok(var))
cout « set- next(var) « «\n ; *)
Äðóãîé ñïîñîá çàäàòü èòåðàòîð ïðèâîäèòñÿ â #6.8.

5.4 Äðóçüÿ è Îáúåäèíåíèÿ


 ýòî ðàçäåëå îïèñûâàþòñÿ åùå íåêîòîðûå îñîáåííîñòè, êñàþùèåñÿ êëàññîâ. Ïîêàçàíî, êàê ïðåäî
5.4.1 Äðóçüÿ
Ïðåäïîëîæèì, âû îïðåäåëèëè äâà êëàññà, vector è matrix (âåêòîð è ìàòðèöà). Êàæäûé ñêðûâàåò
vector multiply(matrix amp; m, vector amp; 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; *)
Ýòî ñâîåãî ðîäà «åñòåñòâåííûé» ñïîñîá, íî îí î÷åíü íåýôåêòèâåí. Ïðè êàæäîì îáðàùåíèè ê mult
Òåïåðü, åñëè ìû ñäåëàåì multiply() ÷ëåíîì êëàññà vector, ìû ñìîæåì îáîéòèñü áåç ïðîâåðêè èí
class matrix;
class vector (* float v[4]; // ... friend vector multiply(matrix amp;, vector am
p;); *);
class matrix (* vector v[4]; // ... friend vector multiply(matrix amp;, vector a
mp;); *);
Ôóíêöèÿ äðóã íå èìååò íèêàêèõ îñîáåííîñòåé, ïîìèìî ïðàâà äîñòóïà ê çàêðûòîé ÷àñòè êëàññà. Â
Òåïåðü ìîæíî íàïèñàòü ôóíêöèþ óìíîæåíèÿ, êîòîðàÿ èñïîëçóåò ýëåìåíòû âåêòîðîâ è ìàòðèöû íåïî
vector multiply(matrix amp; m, vector amp; 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 (ì
Ôóíêöèÿ ÷ëåí îäíîãî êëàññà ìîæåò áûòü äðóãîì äðóãîãî. Íàïðèìåð:
class x (* // ... void f(); *);
class y (* // ... friend void x::f(); *);
Íåò íè÷åãî íåîáû÷íîãî â òîì, ÷òî âñå ôóíêöèè ÷ëåíû îäíãî êëàññà ÿâëÿþòñÿ äðóçüÿìè äðóãîãî.
class x (* friend class y; // ... *);
Òàêîå îïèñàíèå friend äåëàåò âñå ôóíêöèè ÷ëåíû êëàññà y äðóçüÿìè x.

5.4.2 Óòî÷íåíèå* Èìåíè ×ëåíà


 * Èíîãäà íàçûâàåòñÿ òàêæå êâàëèôèêàöèåé. (ïðèì. ïåðåâ.)
Èíîãäà ïîëåçíî äåëàòü ÿâíîå ðàçëè÷èå ìåæäó èìåíàìè ÷ëíîâ êëàññà è ïðî÷èìè èìåíàìè. Äëÿ ýòîã
class x (* int m; public: int readm() (* return x::m; *) void setm(int m) (* x::
m = m; *) *);
 x::setm() èìÿ ïàðàìåòðà m ïðÿ÷åò ÷ëåí m, ïîýòîìó åäèíñòâåííûé ñïîñîá ñîñëàòüñÿ íà ÷ëåí
Èìÿ ñ ïðåôèêñîì :: (ïðîñòî) äîëæíî áûòü ãëîáàëüíûì èìíåì. Ýòî îñîáåííî ïîëåçíî äëÿ òîãî, ÷ò
class my_file (* // ... public: int open(char*, char*); *);
int my_file::open(char* name, char* spec) (* // ... if (::open(name,flag))(*//èñïîëüçîâàòü
// ... *) // ... *)

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);*) // ... *);
Åñëè òîëüêî âëîæåííûé êëàññ íå ÿâëÿåòñÿ î÷åíü ïðîñòûì, â òàêîì îïèñàíèè òðóäíî ðàçîáðàòüñÿ.
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* ne
xt=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); voi
d wait(event); // ... *);
Îïèñàíèå ÷ëåíà task_chain (öåïî÷êà çàäà÷) êàê static îáåñïå÷èâàåò, ÷òî îí áóäåò âñåãî ëèøü
task::task_chain
 ôóíêöèè ÷ëåíå íà íåãî ìîæíî ññûëàòüñÿ ïðîñòî task_chain. Èñïîëüçîâàíèå ñòàòè÷åñêèõ ÷ëåíîâ

5.4.5 Óêàçàòåëè íà ×ëåíû


Ìîæíî áðàòü àäðåñ ÷ëåíà êëàññà. Ïîëó÷åíèå àäðåñà ôóíêöèè ÷ëåíà ÷àñòî áûâàåò ïîëåçíî, ïîñêîë
ïðåîáðàçîâàòü ñ èñïîëüçîâàíèåì ñîîòâåòñòâóþùåé ÿçûêîâîé êîíòðóêöèè, êîãäà ïîÿâèòñÿ òàêàÿ âî
typedef void (cl::*PROC)(int); PROC pf1 = amp;cl::print; // ïðèâåäåíèå ê òèïó íåíóæíî PROC
Äëÿ âûçîâîâ ÷åðåç óêàçàòåëü íà ôóíêöèþ ÷ëåí èñïîëüçóþòñÿ îïåðàöèè . è -». Íàïðèìåð:
(z1.*pf1)(2); (( amp;z2)-»*pf2)(4);
(ïðèì. àâòîðà)
#include «stream.h»
struct cl (* char* val; void print(int x) (* cout « val «« x «« «\n ; *); cl(char* v) (* v
v; *) *);
// ``ôàëüøèâûé'' òèï äëÿ ôóíêöèé ÷ëåíîâ: typedef void (*PROC)(void*, int);
main() (* cl z1("z1 "); cl z2("z2 "); PROC pf1 = PROC( amp;z1.print); PROC pf2 =
PROC( amp;z2.print); z1.print(1); (*pf1)( amp;z1,2); z2.print(3); (*pf2)( amp;z
2,4); *)
Âî ìíîãèõ ñëó÷àÿõ ìîæíî âîñïîëüçîâàòüñÿ âèðòóàëüíûìè ôóíêöèÿìè (ñì. Ãëàâó 7) òàì, ãäå èíà÷å
5.4.6 Ñòðóêòóðû è Îáúåäèíåíèÿ
Ïî îïðåäåëåíèþ struct ýòî ïðîñòî êëàññ, âñå ÷ëåíû êòîðîãî îòêðûòûå, òî åñòü
struct s (* ...
åñòü ïðîñòî ñîêðàùåííàÿ çàïèñü
class s (* public: ...
Ñòðóêòóðû èñïîëüçóþòñÿ â òåõ ñëó÷àÿõ, êîãäà ñîêðûòèå äàííûõ íåóìåñòíî.
Èìåíîâàííîå îáúåäèíåíèå îïðåäåëÿåòñÿ êàê struct, â êîòðîé âñå ÷ëåíû èìåþò îäèí è òîò æå àäð
Ñëîæíîñòü ñîñòîèò â òîì, ÷òî êîìïèëÿòîð, âîîáùå ãîâîðÿ, íå çíàåò, êàêîé ÷ëåí èñïîëüçóåòñÿ â
void strange(int i) (* tok_val x; if (i) x.p = "2"; else x.d = 2; sqrt(x.d); // îøèáêà åñëè
)
Êðîìå òîãî, îáúåäèíåíèå, îïðåäåëåííîå òàê, êàê ýòî, íåëüçÿ èíèöèàëèçèðîâàòü. Íàïðèìåð:

Ãëàâà 5 Êëàññû
Ýòè òèïû íå «àáñòðàêòíû», îíè ñòîëü æå ðåàëüíû, êàê int è float.  Äóã ÌàêÈëðîé
 ýòîé ãëàâå îïèñûâàþòñÿ âîçìîæíîñòè îïðåäåëåíèÿ íîâûõ òèïîâ â Ñ++, äëÿ êîòîðûõ äîñòóï ê äà

5.1 Çíàêîìñòâî è Êðàòêèé Îáçîð


Ïðåäíàçíà÷åíèå ïîíÿòèÿ êëàññà, êîòîðîìó ïîñâÿùåíû ýòà è äâå ïîñëåäóþùèå ãëàâû, ñîñòîèò â òî
Òèï åñòü êîíêðåòíîå ïðåäñòàâëåíèå íåêîòîðîé êîíöåïöèè (ïîíÿòèÿ). Íàïðèìåð, èìåþùèéñÿ â Ñ++
 îïðåäåëåíèè íîâîãî òèïà îñíîâíàÿ èäåÿ îòäåëèòü íåñùåñòâåííûå ïîäðîáíîñòè ðåàëèçàöèè (íà
Ýòà ãëàâà ñîñòîèò èç ÷åòûðåõ ïðàêòè÷åñêè îòäåëüíûõ ÷àòåé:
#5.2 Êëàññû è ×ëåíû. Ýòîò ðàçäåë çíàêîìèò ñ îñíîâíûì ïîíÿòèåì òèïà, îïðåäåëÿåìîãî ïîëüçîâàò
#5.3 Èíòåðôåéñû è Ðåàëèçàöèè. Â ýòîì ðàçäåëå ïðèâîäèòñÿ äâà ïðèìåðà òîãî, êàê êëàññ ïðîåêòè
#5.4 Äðóçüÿ è Îáúåäèíåíèÿ. Â ýòîì ðàçäåëå ïðèâîäèòñÿ ìíîãî äîïîëíèòåëüíûõ ïîäðîáíîñòåé, êàñ
#5.5 Êîíñòðóêòîðû è Äåñòðóêòîðû. Îáúåêò ìîæåò ñîçäàâàòñÿ êàê àâòîìàòè÷åñêèé, ñòàòè÷åñêèé èë

5.2 Êëàññû è ×ëåíû


Êëàññ ýòî îïðåäåëÿåìûé ïîëüçîâàòåëåì òèï. Ýòîò ðàçäåë çíàêîìèò ñ îñíîâíûìè ñðåäñòâàìè îïð

5.2.1 Ôóíêöèè ×ëåíû


Ðàññìîòðèì ðåàëèçàöèþ ïîíÿòèÿ äàòû ñ èñïîëüçîâàíèåì struct äëÿ òîãî, ÷òîáû îïðåäåëèòü ïðåäñ
struct date (* int month, day, year; *); // äàòà: ìåñÿö, äåíü, ãîä *) date today; void set_
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 Êëàññû
Îïèñàíèå date â ïðåäûäóùåì ïîäðàçäåëå äàåò ìíîæåñòâî ôóíêöèé äëÿ ðàáîòû ñ date, íî íå óêàçû
class date (* int month, day, year; public: void set(int, int, int); void get(in
t*, int*, int*); void next(); void print(); *);
Ìåòêà public: äåëèò òåëî êëàññà íà äâå ÷àñòè. Èìåíà â ïåðâîé, çàêðûòîé ÷àñòè, ìîãóò èñïîëüç
void date::ptinr() // ïå÷àòàåò â çàïèñè, ïðèíÿòîé â ÑØÀ (* cout «« month «« "/" «« day «« "
Îäíàêî ôóíêöèè íå ÷ëåíû îòãîðîæåíû îò èñïîëüçîâàíèÿ çàðûòûõ ÷ëåíîâ êëàññà date. Íàïðèìåð:
void backdate() (* today.day ; // îøèáêà *)
 òîì, ÷òî äîñòóï ê ñòðóêòóðå äàííûõ îãðàíè÷åí ÿâíî îïñàííûì ñïèñêîì ôóíêöèé, åñòü íåñêîëüê

Çàùèòà çàêðûòûõ äàííûõ ñâÿçàíà ñ îãðàíè÷åíèåì èñïîëüçâàíèÿ èìåí ÷ëåíîâ êëàññà. Ýòî ìîæíî îá

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.
Óêàçàòåëü íà îáúåêò, äëÿ êîòîðîãî âûçâàíà ôóíêöèÿ ÷ëåí, ÿâëÿåòñÿ ñêðûòûì ïàðàìåòðîì ôóíêöèè
x* this;
è èíèöèàëèçèðîâàí òàê, ÷òî îí óêàçûâàåò íà îáúåêò, äëÿ êîòîðîãî áûëà âûçâàíà ôóíêöèÿ ÷ëåí.
class x (* int m; public: int readm() (* return this-»m; *) *);
Ïðè ññûëêå íà ÷ëåíû èñïîëüçîâàíèå this èçëèøíå. Ãëàâíûì îáðàçîì this èñïîëüçóåòñÿ ïðè íàïèñ
class dlink (* dlink* pre; // ïðåäøåñòâóþùèé dlink* suc; // ñëåäóþùèé public: void append(d
void dlink::append(dlink* p) (* p-»suc = suc; // òî åñòü, p-»suc = this-»suc p-»pre = 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); *)
Öåïî÷êè òàêîé îáùåé ïðèðîäû ÿâëÿþòñÿ îñíîâîé äëÿ ñïèñêâûõ êëàññîâ, êîòîðûå îïèñûâàþòñÿ â Ãë

5.2.4 Èíèöèàëèçàöèÿ
Èñïîëüçîâàíèå äëÿ îáåñïå÷åíèÿ èíèöèàëèçàöèè îáúåêòà êëàññà ôóíêöèé âðîäå set_date() (óñòàíî
class date (* // ... date(int, int, int); *);
Êîãäà êëàññ èìååò êîíñòðóêòîð, âñå îáúåêòû ýòîãî êëàññà áóäóò èíèöèàëèçèðîâàòüñÿ. Åñëè äëÿ
date today = date(23,6,1983); date xmas(25,12,0); // ñîêðàùåííàÿ ôîðìà // (xmas ðîæäåñòâî
×àñòî áûâàåò õîðîøî îáåñïå÷èòü íåñêîëüêî ñïîñîáîâ èíèöàëèçàöèè îáúåêòà êëàññà. Ýòî ìîæíî ñä
class date (* int month, day, year; public: // ... date(int, int, int); // äåíü ìåñÿö ãîä d
/ äàòà â ñòðîêîâîì ïðåäñòàâëåíèè date(int); // äåíü, ìåñÿö è ãîä ñåãîäíÿøíèå date(); // äàò
Êîíñòðóêòîðû ïîä÷èíÿþòñÿ òåì æå ïðàâèëàì îòíîñèòåëüíî òèïîâ ïàðàìåòðîâ, ÷òî è ïåðåãðóæåííûå

date today(4); date july4(«Èþëü 4, 1983»); date guy(«5 Íîÿ»); date now; // èíèöèàëèçèðóåòñÿ
Çàìåòüòå, ÷òî ôóíêöèè ÷ëåíû ìîãóò áûòü ïåðåãðóæåíû áåç ÿâíîãî èñïîëüçîâàíèÿ êëþ÷åâîãî ñëîâà
Ðàçìíîæåíèå êîíñòðóêòîðîâ â ïðèìåðå ñ date òèïè÷íî. Ïðè ðàçðàáîòêå êëàññà âñåãäà åñòü ñîáëà
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 : toda
y.month; year = y ? y : today.year; // ïðîâåðêà, ÷òî äàòà äîïóñòèìàÿ // ... *)
Êîãäà èñïîëüçóåòñÿ çíà÷åíèå ïàðàìåòðà, óêàçûâàþùåå «áðàòü ïî óìîë÷àíèþ», âûáðàííîå çíà÷åíèå
Îáúåêò êëàññà áåç êîíñòðóêòîðîâ ìîæíî èíèöèàëèçèðîâàòü ïóòåì ïðèñâàèâàíèÿ åìó äðóãîãî îáúåê
date d = today; // èíèöèàëèçàöèÿ ïîñðåäñòâîì ïðèñâàèâàíèÿ
Ïî ñóùåñòâó, èìååòñÿ êîíñòðóêòîð ïî óìîë÷àíèþ, îïðåäëåííûé êàê ïîáèòîâàÿ êîïèÿ îáúåêòà òîãî

5.2.5 Î÷èñòêà
Îïðåäåëÿåìûé ïîëüçîâàòåëåì òèï ÷àùå èìååò, ÷åì íå èìååò, êîíñòðóêòîð, êîòîðûé îáåñïå÷èâàåò
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) (
= 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, ÷òîáû âûäåëèòü âåêòîð èç 10

5.2.6 Inline
Ïðè ïðîãðàììèðîâàíèè ñ èñïîëüçîâàíèåì êëàññîâ î÷åíü ÷àòî èñïîëüçóåòñÿ ìíîãî ìàëåíüêèõ ôóíêö
×òîáû ñïðàâèòüñÿ ñ ýòîé ïðîáëåìîé, áûë ðàçðàáîòàí àïïðàò inline-ôóíêöèé. Ôóíêöèÿ, îïðåäåëåí
Ôóíêöèþ ÷ëåí ìîæíî òàêæå îïèñàòü êàê inline âíå îïèñàíèÿ êëàññà. Íàïðèìåð: char char_stack
char* s; public: char pop(); // ... *);
inline char char_stack::pop() (* return * top; *)

5.3 Èíòåðôåéñû è Ðåàëèçàöèè


×òî ïðåäñòàâëÿåò ñîáîé õîðîøèé êëàññ? Íå÷òî, èìåþùåå íáîëüøîå è õîðîøî îïðåäåëåííîå ìíîæåñò
Äëÿ âñåõ âèäîâ êîíòåéíåðîâ ñóùåñòâóþò î÷åâèäíûå ïðèìåðû: òàáëèöû, ìíîæåñòâà, ñïèñêè, âåêòîð
Ñîêðûòèå äàííûõ è ïðîäóìàííûé èíòåðôåéñ ìîæåò äàòü êîöåïöèÿ ìîäóëÿ (ñì. íàïðèìåð #4.4: ôàéë

5.3.1 Àëüòåðíàòèâíûå Ðåàëèçàöèè


Ïîêà îïèñàíèå îòêðûòîé ÷àñòè êëàññà è îïèñàíèå ôóíêöèé ÷ëåíîâ îñòàþòñÿ íåèçìåííûìè, ðåàëèçà
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
#include «string.h»
name* table::look(char* p, int ins) (* for (name* n = tbl; n; n=n-»next) if (strcm
p(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-»val
ue = 1; nn-»next = tbl; tbl = nn; return nn; *)
Òåïåðü ðàññìîòðèì êëàññ 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*[
for (int i = 0; i«sz; i++) tbl[i] = 0; *)
table::~table() (* for (int i = 0; i«size; i++) for (name* n = tbl[i]; n; n=n-»next)
(* delete n-»string; delete n; *) delete tbl; *)
Îïèñàâ äåñòðóêòîð äëÿ êëàññà name ìîæíî ïîëó÷èòü áîëåå ïðîñòîé è ÿñíûé âàðèàíò table::~tabl
#include «string.h»
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-»val
ue = 1; nn-»next = tbl[ii]; tbl[ii] = nn; return nn;
*)
Î÷åâèäíî, ÷òî ôóíêöèè ÷ëåíû êëàññà äîëæíû çàíîâî êîìïëèðîâàòüñÿ âñåãäà, êîãäà âíîñèòñÿ êàêî
Ïî÷åìó, ìîæåòå âû ñïðîñèòü, Ñ++ ðàçðàáîòàí òàê, ÷òî ïîëå èçìåíåíèÿ çàêðûòîé ÷àñòè íåîáõîäèì

Ýòîé ñëîæíîñòè ìîæíî èçáåæàòü, ïðåäñòàâèâ êàæäûé îáúåêò êëàññà êàê óêàçàòåëü íà «íàñòîÿùèé»
5.3.2 Çàêîí÷åííûé Êëàññ
Ïðîãðàììèðîâàíèå áåç ñîêðûòèÿ äàííûõ (ñ ïðèìåíåíèåì ñòðóêòóð) òðåáóåò ìåíüøåé ïðîäóìàííîñòè
Âîò ïðèìåð çàêîí÷åííîãî òèïà intset, êîòîðûé ðåàëèçóåò ïîíÿòèå «ìíîæåñòâî öåëûõ»:
class intset (* int cursize, maxsize; int *x; public: intset(int m, int n); // ñàìîå áîëüøå
~intset();
int member(int t); // ÿâëÿåòñÿ ëè t ýëåìåíòîì? void insert(int t); // äîáàâèòü "t" â ìíîæåñ
void iterate(int amp; i) (* i = 0; *) int ok(int amp; i) (* return i«cursize; *) i
nt next(int amp; i) (* return x[i++]; *) *);
×òîáû ïðîòåñòèðîâàòü ýòîò êëàññ, ìîæíî ñîçäàòü è ðàñï÷àòàòü ìíîæåñòâî ñëó÷àéíûõ öåëûõ ÷èñåë
#include «stream.h»
void error(char* s) (* cerr « "set: " «« s «« «\n ; exit(1); *)
Êëàññ intset èñïîëüçóåòñÿ â main(), êîòîðàÿ ïðåäïîëàãàåò äâà öåëûõ ïàðàìåòðà. Ïåðâûé ïàðàìå

main(int argc, char* argv[]) (* if (argc != 3) error(«îæèäàåòñÿ äâà ïàðàìåòðà»); int count
/ â äèàïàçîíå 1..n intset s(m,n);
while (count«m) (* int t = randint(n); if (s.member(t)==0) (* s.insert(t); count++
; *) *)
print_in_order( amp;s); *)
 ïðîãðàììå, äëÿ êîòîðîé òðåáóåòñÿ äâà ïàðàìåòðà, ñ÷å÷èê ÷èñëà ïàðàìåòðîâ, argc, äîëæåí ðàâ
extern int atoi(char*);
ôóíêöèÿ atoi() ýòî ñòàíäàðòíàÿ áèáëèîòå÷íàÿ ôóíêöèÿ äëÿ ïðåîáðàçîâàíèÿ ïðåäñòàâëåíèÿ öåëîãî
extern int rand(); // Íå î÷åíü ñëó÷àéíûå, áóäüòå îñòîðîæíû
int randint(int u) // â äèàïàçîíå 1..u (* int r = rand(); if (r « 0) r = -r; return 1 + r%u
Ïîäðîáíîñòè ðåàëèçàöèè êëàññà äîëæíû ïðåäñòàâëÿòü äëÿ ïîëüçîâàòåëÿ âåñüìà íåçíà÷èòåëüíûé èí
intset::intset(int m, int n)//ñàìîå áîëüøåå,m int'îâ â 1..n (* if (m«1 !! n m) error(«íåäîï
maxsize]; *)
intset::~intset() (* delete x; *)
Öåëûå ÷èñëà âñòàâëÿþòñÿ, ïîýòîìó îíè õðàíÿòñÿ â âîçðàòàþùåì ïîðÿäêå:
void intset::insert(int t) (* if (++cursize » maxsize) error(«ñëèøêîì ìíîãî ýëåìåíòîâ»); in

while (i»0 amp; amp; x[i-1]»x[i]) (* int t = x[i]; // ïåðåñòàâèòü x[i] è [i-1] x[i] = x[i-1
*) *)
Äëÿ íàõîæäåíèÿ ÷ëåíîâ èñïîëüçóåòñÿ ïðîñòî äâîè÷íûé ïèñê:
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; // íå íàéäåíî *)
È, íàêîíåö, íàì íóæíî îáåñïå÷èòü ìíîæåñòâî îïåðàöèé, ÷òîáû ïîëüçîâàòåëü ìîã îñóùåñòâëÿòü öè
Äàåòñÿ òðè ôóíêöèè: iterate() äëÿ èíèöèàëèçàöèè èòåðöèè, ok() äëÿ ïðîâåðêè, åñòü ëè ñëåäóþù
class intset (* // ... void iterate(int amp; i) (* i = 0; *) int ok(int amp; i)
(* return i«cursize; *) int next(int amp; i) (* return x[i++]; *) *);
×òîáû äàòü âîçìîæíîñòü ýòèì òðåì îïåðàöèÿì ðàáîòàòü ñîìåñòíî è ÷òîáû çàïîìíèòü, êóäà äîøåë
void print_in_order(intset* set) (* int var; set-»iterate(var); while (set-»ok(var))
cout « set- next(var) « «\n ; *)
Äðóãîé ñïîñîá çàäàòü èòåðàòîð ïðèâîäèòñÿ â #6.8.

5.4 Äðóçüÿ è Îáúåäèíåíèÿ


 ýòî ðàçäåëå îïèñûâàþòñÿ åùå íåêîòîðûå îñîáåííîñòè, êñàþùèåñÿ êëàññîâ. Ïîêàçàíî, êàê ïðåäî

5.4.1 Äðóçüÿ
Ïðåäïîëîæèì, âû îïðåäåëèëè äâà êëàññà, vector è matrix (âåêòîð è ìàòðèöà). Êàæäûé ñêðûâàåò
vector multiply(matrix amp; m, vector amp; 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; *)
Ýòî ñâîåãî ðîäà «åñòåñòâåííûé» ñïîñîá, íî îí î÷åíü íåýôåêòèâåí. Ïðè êàæäîì îáðàùåíèè ê mult
Òåïåðü, åñëè ìû ñäåëàåì multiply() ÷ëåíîì êëàññà vector, ìû ñìîæåì îáîéòèñü áåç ïðîâåðêè èí
class matrix;
class vector (* float v[4]; // ... friend vector multiply(matrix amp;, vector am
p;); *);
class matrix (* vector v[4]; // ... friend vector multiply(matrix amp;, vector a
mp;); *);
Ôóíêöèÿ äðóã íå èìååò íèêàêèõ îñîáåííîñòåé, ïîìèìî ïðàâà äîñòóïà ê çàêðûòîé ÷àñòè êëàññà. Â
ïðîãðàììû è ñîïîñòàâëÿåòñÿ ñ äðóãèìè îïèñàíèÿìè ýòîãî èìåíè. Îïèñàíèå äðóãà ìîæåò ðàñïîëàãà
Òåïåðü ìîæíî íàïèñàòü ôóíêöèþ óìíîæåíèÿ, êîòîðàÿ èñïîëçóåò ýëåìåíòû âåêòîðîâ è ìàòðèöû íåïî
vector multiply(matrix amp; m, vector amp; 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 (ì
Ôóíêöèÿ ÷ëåí îäíîãî êëàññà ìîæåò áûòü äðóãîì äðóãîãî. Íàïðèìåð:
class x (* // ... void f(); *);
class y (* // ... friend void x::f(); *);
Íåò íè÷åãî íåîáû÷íîãî â òîì, ÷òî âñå ôóíêöèè ÷ëåíû îäíãî êëàññà ÿâëÿþòñÿ äðóçüÿìè äðóãîãî.
class x (* friend class y; // ... *);
Òàêîå îïèñàíèå friend äåëàåò âñå ôóíêöèè ÷ëåíû êëàññà y äðóçüÿìè x.

5.4.2 Óòî÷íåíèå* Èìåíè ×ëåíà


 * Èíîãäà íàçûâàåòñÿ òàêæå êâàëèôèêàöèåé. (ïðèì. ïåðåâ.)
Èíîãäà ïîëåçíî äåëàòü ÿâíîå ðàçëè÷èå ìåæäó èìåíàìè ÷ëíîâ êëàññà è ïðî÷èìè èìåíàìè. Äëÿ ýòîã
class x (* int m; public: int readm() (* return x::m; *) void setm(int m) (* x::
m = m; *)
*);
 x::setm() èìÿ ïàðàìåòðà m ïðÿ÷åò ÷ëåí m, ïîýòîìó åäèíñòâåííûé ñïîñîá ñîñëàòüñÿ íà ÷ëåí
Èìÿ ñ ïðåôèêñîì :: (ïðîñòî) äîëæíî áûòü ãëîáàëüíûì èìíåì. Ýòî îñîáåííî ïîëåçíî äëÿ òîãî, ÷ò
class my_file (* // ... public: int open(char*, char*); *);
int my_file::open(char* name, char* spec) (* // ... if (::open(name,flag))(*//èñïîëüçîâàòü
// ... *) // ... *)

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);*) // ... *);
Åñëè òîëüêî âëîæåííûé êëàññ íå ÿâëÿåòñÿ î÷åíü ïðîñòûì, â òàêîì îïèñàíèè òðóäíî ðàçîáðàòüñÿ.
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(), íå ÿâëÿåòñÿ íè íåîáõîäèìîé, íè äîïóñòèìîé. Åäèíñòâ
4.4). Áîëüøóþ ÷àñòü íåòðèâèàëüíûõ êëàññîâ ëó÷øå îïèñûâàòü ðàçäåëüíî:
class setmem (* friend class set; // äîñòóï òîëüêî ñ ïîìîùüþ ÷ëåíîâ set int mem; setmem* ne
xt=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); voi
d wait(event); // ... *);
Îïèñàíèå ÷ëåíà task_chain (öåïî÷êà çàäà÷) êàê static îáåñïå÷èâàåò, ÷òî îí áóäåò âñåãî ëèøü
task::task_chain
 ôóíêöèè ÷ëåíå íà íåãî ìîæíî ññûëàòüñÿ ïðîñòî task_chain. Èñïîëüçîâàíèå ñòàòè÷åñêèõ ÷ëåíîâ

5.4.5 Óêàçàòåëè íà ×ëåíû


Ìîæíî áðàòü àäðåñ ÷ëåíà êëàññà. Ïîëó÷åíèå àäðåñà ôóíêöèè ÷ëåíà ÷àñòî áûâàåò ïîëåçíî, ïîñêîë

 * Áîëåå ïîçäíèå âåðñèè Ñ++ ïîääåðæèâàþò ïîíÿòèå óêàçòåëü íà ÷ëåí: cl::* îçíà÷àåò «óêàçàòå
typedef void (cl::*PROC)(int); PROC pf1 = amp;cl::print; // ïðèâåäåíèå ê òèïó íåíóæíî PROC
Äëÿ âûçîâîâ ÷åðåç óêàçàòåëü íà ôóíêöèþ ÷ëåí èñïîëüçóþòñÿ îïåðàöèè . è -». Íàïðèìåð:
(z1.*pf1)(2); (( amp;z2)-»*pf2)(4);
(ïðèì. àâòîðà)
#include «stream.h»
struct cl (* char* val; void print(int x) (* cout « val «« x «« «\n ; *); cl(char* v) (* v
v; *) *);
// ``ôàëüøèâûé'' òèï äëÿ ôóíêöèé ÷ëåíîâ: typedef void (*PROC)(void*, int);
main() (* cl z1("z1 "); cl z2("z2 "); PROC pf1 = PROC( amp;z1.print); PROC pf2 =
PROC( amp;z2.print); z1.print(1); (*pf1)( amp;z1,2); z2.print(3); (*pf2)( amp;z
2,4); *)
Âî ìíîãèõ ñëó÷àÿõ ìîæíî âîñïîëüçîâàòüñÿ âèðòóàëüíûìè ôóíêöèÿìè (ñì. Ãëàâó 7) òàì, ãäå èíà÷å

5.4.6 Ñòðóêòóðû è Îáúåäèíåíèÿ


Ïî îïðåäåëåíèþ struct ýòî ïðîñòî êëàññ, âñå ÷ëåíû êòîðîãî îòêðûòûå, òî åñòü
struct s (* ...
åñòü ïðîñòî ñîêðàùåííàÿ çàïèñü
class s (* public: ...
Ñòðóêòóðû èñïîëüçóþòñÿ â òåõ ñëó÷àÿõ, êîãäà ñîêðûòèå äàííûõ íåóìåñòíî.
Èìåíîâàííîå îáúåäèíåíèå îïðåäåëÿåòñÿ êàê struct, â êîòðîé âñå ÷ëåíû èìåþò îäèí è òîò æå àäð

union tok_val (* char* p; // ñòðîêà char v[8]; // èäåíòèôèêàòîð (ìàêñèìóì 8 char) long i; /
Ñëîæíîñòü ñîñòîèò â òîì, ÷òî êîìïèëÿòîð, âîîáùå ãîâîðÿ, íå çíàåò, êàêîé ÷ëåí èñïîëüçóåòñÿ â
void strange(int i) (* tok_val x; if (i) x.p = "2"; else x.d = 2; sqrt(x.d); // îøèáêà åñëè
)
Êðîìå òîãî, îáúåäèíåíèå, îïðåäåëåííîå òàê, êàê ýòî, íåëüçÿ èíèöèàëèçèðîâàòü. Íàïðèìåð:
tok_val curr_val = 12; //îøèáêà:int ïðèñâàèâàåòñÿ tok_val'ó
ÿâëÿåòñÿ íåäîïóñòèìûì. Äëÿ òîãî, ÷òîáû ýòî ïðåîäîëåòü, ìîæíî âîñïîëüçîâàòüñÿ êîíñòðóêòîðàìè
union tok_val (* char* p; // ñòðîêà char v[8]; // èäåíòèôèêàòîð (ìàêñèìóì 8 char) long i; /
tok_val(char*); // äîëæíà âûáðàòü ìåæäó p è v tok_val(int ii) (* i = ii; *) tok_val() (* d
Ýòî ïîçâîëÿåò ñïðàâëÿòüñÿ ñ òåìè ñèòóàöèÿìè, êîãäà òèïû ÷ëåíîâ ìîãóò áûòü ðàçðåøåíû ïî ïðàâ
void f() (* tok_val a = 10; // a.i = 10 tok_val b = 10.0; // b.d = 10.0 *)
Êîãäà ýòî íåâîçìîæíî (äëÿ òàêèõ òèïîâ, êàê char* è char[8], int è char, è ò.ï.), íóæíûé ÷ëå
tok_val::tok_val(char* pp) (* if (strlen(pp) «= 8) strncpy(v,pp,8); // êîðîòêàÿ ñòðîêà else
Òàêèõ ñèòóàöèé âîîáùå-òî ëó÷øå èçáåãàòü.
Èñïîëüçîâàíèå êîíñòðóêòîðîâ íå ïðåäîõðàíÿåò îò òàêîãî ñëó÷àéíîãî íåïðàâèëüíîãî óïîòðåáëåíèÿ
ïðèñâàèâàåòñÿ çíà÷åíèå îäíîãî òèïà, à ïîòîì ðàññìàòðèâàåòñÿ êàê äðóãîé òèï. Ýòà ïðîáëåìà ðå
class tok_val (* char tag; union (* char* p; char v[8]; long i; double d; *); in
t check(char t, char* s) (* if (tag!=t) (* error(s); return 0; *) return 1; *) p
ublic: tok_val(char* pp); tok_val(long ii) (* i=ii; tag='I'; *) tok_val(double d
d) (* d=dd; tag='D'; *)
long amp; ival() (* check('I',"ival"); return i; *) double amp; fval() (* check(
'D',"fval"); return d; *) char* amp; sval() (* check('S',"sval"); return p; *) c
har* id() (* check('N',"id"); return v; *) *);
Êîíñòðóêòîð, ïîëó÷àþùèé ñòðîêîâûé ïàðàìåòð, èñïîëüçóåò äëÿ êîïèðîâàíèÿ êîðîòêèõ ñòðîê strnc
tok_val::tok_val(char* pp) (* if (strlen(pp) «= 8) (* // êîðîòêàÿ ñòðîêà tag = 'N' strncpy(
// ïðîñòî ñîõðàíèòü óêàçàòåëü *) *)
Òèï tok_val ìîæíî èñïîëüçîâàòü òàê:
void f() (* tok_val t1(«short»); // êîðîòêàÿ, ïðèñâîèòü v tok_val t2(«long string»); //äëèí
id(),8); // ïðîâåðêà check() íå ïðîéäåò *)

5.5 Êîíñòðóêòîðû è Äåñòðóêòîðû


Åñëè ó êëàññà åñòü êîíñòðóêòîð, òî îí âûçûâàåòñÿ âñåãäà, êîãäà ñîçäàåòñÿ îáúåêò êëàññà. Åñë
1. Àâòîìàòè÷åñêèé îáúåêò: ñîçäàåòñÿ êàæäûé ðàç, êîãäà åãî îïèñàíèå âñòðå÷àåòñÿ ïðè âûïîëíåí
2. Ñòàòè÷åñêèé îáúåêò: ñîçäàåòñÿ îäèí ðàç, ïðè çàïóñêå ïðîãðàììû, è óíè÷òîæàåòñÿ îäèí ðàç,
3. Îáúåêò â ñâîáîäíîé ïàìÿòè: ñîçäàåòñÿ ñ ïîìîùüþ îïðàöèè new è óíè÷òîæàåòñÿ ñ ïîìîùüþ îïåð
4. Îáúåêò ÷ëåí: êàê îáúåêò äðóãîãî êëàññà èëè êàê ýëìåíò âåêòîðà.
Îáúåêò òàêæå ìîæåò áûòü ïîñòðîåí ñ ïîìîùüþ ÿâíîãî ïðèìíåíèÿ êîíñòðóêòîðà â âûðàæåíèè (ñì. #

5.5.1 Ïðåäîñòåðåæåíèå
Åñëè x è y îáúåêòû êëàññà cl, òî x=y â ñòàíäàðòíîì ñëó÷àå îçíà÷àåò ïîáèòîâîå êîïèðîâàíèå
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) (
= c; *) char pop() (* return * top; *) *);
void h() (* char_stack s1(100); char_stack s2 = s1; // íåïðèÿòíîñòü char_stack s3(99); s3 =
Çäåñü char_stack::char_stack() âûçûâàåòñÿ äâàæäû: äëÿ s1 è äëÿ s3. Äëÿ s2 îí íå âûçûâàåòñÿ,

5.5.2 Ñòàòè÷åñêàÿ Ïàìÿòü


Ðàññìîòðèì ñëåäóþùåå:
table tbl1(100);
void f() (* static table tbl2(200); *)
main() (*
f(); *)
Çäåñü êîíñòðóêòîð table::table(), îïðåäåëåííûé â #5.3.1, áóäåò âûçûâàòüñÿ äâàæäû: îäèí ðàç
Ïàðàìåòðû êîíñòðóêòîðîâ äëÿ ñòàòè÷åñêèõ îáúåêòîâ äîëæíû áûòü êîíñòàíòíûìè âûðàæåíèÿìè:
void g(int a) (* static table t(a); // îøèáêà *)
Òðàäèöèîííî âûïîëíåíèåì ïðîãðàììû ñ÷èòàëîñü âûïîëíåíèå main(). Òàê íèêîãäà íå áûëî, äàæå â
Âûçîâ êîíñòðóêòîðîâ è äåñòðóêòîðîâ äëÿ ñòàòè÷åñêèõ îáåêòîâ èãðàåò â Ñ++ ÷ðåçâû÷àéíî âàæíóþ
Åñëè ïðîãðàììà çàâåðøàåòñÿ ñ ïîìîùüþ ôóíêöèè exit(), òî äåñòðóêòîðû äëÿ ñòàòè÷åñêèõ îáúåêòî
Èíîãäà, êîãäà âû ðàçðàáàòûâàåòå áèáëèîòåêó, íåîáõîäèìî èëè ïðîñòî óäîáíî ñîçäàòü òèï ñ êîíñ

5.5.3 Ñâîáîäíàÿ Ïàìÿòü


Ðàññìîòðèì:
main() (* table* p = new table(100); table* q = new table(200); delete p; delete
p; // âîçìîæíî, îøèáêà *)
Êîíñòðóêòîð table::table() áóäåò âûçâàí äâàæäû, êàê è äåñòðóêòîð table::~table(). Òî, ÷òî Ñ
Ïîëüçîâàòåëü ìîæåò îïðåäåëèòü íîâóþ ðåàëèçàöèþ îïåðàöèé new è delete (ñì. #3.2.6). Ìîæíî òà

5.5.4 Îáúåêòû Êëàññà êàê ×ëåíû


Ðàññìîòðèì
class classdef (* table members; int no_of_members; // ... classdef(int size); ~
classdef(); *);
Î÷åâèäíîå íàìåðåíèå ñîñòîèò â òîì, ÷òî classdef äîëæåí ñîäåðæàòü òàáëèöó äëèíîé size èç ÷ëå
classdef::classdef(int size) : members(size) (* no_of_members = size; // ... *)
Ïàðàìåòðû äëÿ êîíñòðóêòîðà ÷ëåíà (çäåñü ýòî table::table ()) ïîìåùàþòñÿ â îïðåäåëåíèå (íå â
Åñëè åñòü åùå ÷ëåíû, êîòîðûì íóæíû ñïèñêè ïàðàìåòðîâ äëÿ êîíñòðóêòîðîâ, èõ ìîæíî çàäàòü àíà
class classdef (* table members; table friends; int no_of_members; // ... classd
ef(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_o
size; // ... *)
Åñëè êîíñòðóêòîðó äëÿ ÷ëåíà íå íóæíî íè îäíîãî ïàðàìåðà, òî íèêàêîãî ñïèñêà ïàðàìåòðîâ çàäà
classdef::classdef(int size) : members(size) (* no_of_members = size; // ... *)
è ðàçìåð size òàáëèöû friends áóäåò ðàâåí 15.
Êîãäà îáúåêò êëàññà, ñîäåðæàùèé îáúåêò êëàññà, (íàïðìåð, classdef) óíè÷òîæàåòñÿ, ïåðâûì âûï
Ðàññìîòðèì òðàäèöèîííóþ àëüòåðíàòèâó òîìó, ÷òîáû èìåòü îáúåêòû êëàññà êàê ÷ëåíû,  èìåòü ÷ë
class classdef (* table* members; table* friends; int no_of_members; // ... clas
sdef(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; *)

Ðàçäåëüíî ñîçäàâàåìûå îáúåêòû âðîäå ýòèõ ìîãóò îêàçàòüñÿ ïîëåçíûìè, íî ó÷òèòå, ÷òî members
5.5.5 Âåêòîðà Îáúåêòîâ Êëàññà
×òîáû îïèñàòü âåêòîð îáúåêòîâ êëàññà, èìåþùåãî êîíñòðóòîð, ýòîò êëàññ äîëæåí èìåòü êîíñòðóê
table tblvec[10];
áóäåò îøèáêîé, òàê êàê äëÿ table::table() òðåáóåòñÿ öåëûé ïàðàìåòð. Íåò ñïîñîáà çàäàòü ïàðà
class table (* // ... void init(int sz); // êàê ñòàðûé êîíñòðóêòîð public: table(int sz) //
Êîãäà âåêòîð óíè÷òîæàåòñÿ, äåñòðóêòîð äîëæåí âûçûâàòüñÿ äëÿ êàæäîãî ýëåìåíòà ýòîãî âåêòîðà.
void f() (* table* t1 = new table; table* t2 = new table[10]; delete t1; // îäíà òàáëèöà de
íåïðèÿòíîñòü: 10 òàáëèö *)
 ýòîì ñëó÷àå äëèíó âåêòîðà äîëæåí çàäàâàòü ïðîãðàììèñò:
void g(int sz) (* table* t1 = new table; table* t2 = new table[sz]; delete t1; d
elete[] t2; *)
Íî ïî÷åìó æå êîìïèëÿòîð íå ìîæåò íàéòè ÷èñëî ýëåìåíòîâ âåêòîðà èç îáúåìà âûäåëåííîé ïàìÿòè?

5.5.6 Íåáîëüøèå Îáúåêòû


Êîãäà âû èñïîëüçóåòå ìíîãî íåáîëüøèõ îáúåêòîâ, ðàçìåùàìûõ â ñâîáîäíîé ïàìÿòè, òî âû ìîæåòå
ïðîãðàììà òðàòèò ìíîãî âðåìåíè âûäåëÿÿ è îñâîáîæäàÿ ïàìÿòü ïîä ýòè îáúåêòû. Ïåðâîå ðåøåíèå
Ðàññìîòðèì êëàññ name, êîòîðûé èñïîëüçîâàëñÿ â ïðèìåðàõ table. Åãî ìîæíî áûëî áû îïðåäåëèòü
struct name (* char* string; name* next; double value;
name(char*, double, name*); ~name(); *);
Ïðîãðàììèñò ìîæåò âîñïîëüçîâàòüñÿ òåì, ÷òî ðàçìåùåíèå è îñâîáîæäåíèå îáúåêòîâ çàðàíåå èçâåñ
const NALL = 128; name* nfree;
Ðàñïðåäåëèòåëü, èñïîëüçóåìûé îïåðàöèåé new, õðàíèò ðàìåð îáúåêòà âìåñòå ñ îáúåêòîì, ÷òîáû î
name::name(char* s, double v, name* n) (* register name* p = nfree; // ñíà÷àëà âûäåëèòü
if (p) nfree = p-»next; else (* // âûäåëèòü è ñöåïèòü name* q = (name*)new char[ NALL*sizeo
= amp;q[NALL-1]; q«p; p ) p-»next = p-1; (p+1)-»next = 0; *)
this = p; // çàòåì èíèöèàëèçèðîâàòü string = s; value = v; next = n; *)
Ïðèñâîåíèå óêàçàòåëþ this èíôîðìèðóåò êîìïèëÿòîð î òîì, ÷òî ïðîãðàììèñò âçÿë ñåáå óïðàâëåíè

Çàìåòüòå, ÷òî ïðîñòî êàê


name* q = new name[NALL];
ïàìÿòü âûäåëÿòü íåëüçÿ, ïîñêîëüêó ýòî ïðèâåäåò ê áåñêíå÷íîé ðåêóðñèè, êîãäà new âûçîâåò nam
Îñâîáîæäåíèå ïàìÿòè îáû÷íî òðèâèàëüíî:
name::~name() (* next = nfree; nfree = this; this = 0; *)
Ïðèñâàèâàíèå óêàçàòåëþ this 0 â äåñòðóêòîðå îáåñïå÷èâåò, ÷òî ñòàíäàðòíûé ðàñïðåäåëèòåëü ïàì

5.5.7 Ïðåäîñòåðåæåíèå
Êîãäà â êîíñòðóêòîðå ïðîèçâîäèòñÿ óêàçàòåëþ this, çíà÷íèå this äî ýòîãî ïðèñâàèâàíèÿ íåîïðå
mytype::mytype(int i) (* if (i) this = mytype_alloc(); // ïðèñâàèâàíèå ÷ëåíàì *);
îòêîìïèëèðóåòñÿ, è ïðè i==0 íèêàêîé îáúåêò ðàçìåùåí íå áóäåò.
Êîíñòðóêòîð ìîæåò îïðåäåëèòü, áûë ëè îí âûçâàí îïåðàöèåé new, èëè íåò. Åñëè îí âûçâàí new,
mytype::mytype(int i) (* if (this == 0) this = mytype_alloc(); // ïðèñâàèâàíèå ÷ëåíàì *);
Ýêâèâàëåíòíîãî ñðåäñòâà, êîòîðîå ïîçâîëÿåò äåñòðóêòîðó ðåøèòü âîïðîñ, áûë ëè åãî îáúåêò ñîç
Åñëè òîò, êòî ðåàëèçóåò êëàññ, ÿâëÿåòñÿ îäíîâðåìåííî è åãî åäèíñòâåííûì ïîëüçîâàòåëåì, òî è

5.5.8 Îáúåêòû Ïåðåìåííîãî Ðàçìåðà


Êîãäà ïîëüçîâàòåëü áåðåò óïðàâëåíèå ðàñïðåäåëåíèåì è îâîáîæäåíèåì ïàìÿòè, îí ìîæåò êîíñòðóè
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) (
= 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() (* return * top; *) *);
char_stack::char_stack(int sz) (* if (this) error(«ñòåê íå â ñâîáîäíîé ïàìÿòè»); if (sz « 1
har_stack)+sz-1]; size = sz; top = s; *)
Çàìåòüòå, ÷òî äåñòðóêòîð áîëüøå íå íóæåí, ïîñêîëüêó ïìÿòü, êîòîðóþ èñïîëüçóåò char_stack, ì

5.6 Óïðàæíåíèÿ
1. (*1) Ìîäèôèöèðóéòå íàñòîëüíûé êàëüêóëÿòîð èç Ãëàâû 3, ÷òîáû èñïîëüçîâàòü êëàññ table.
2. (*1) Ðàçðàáîòàéòå tnode (#ñ.8.5) êàê êëàññ ñ êîíòðóêòîðàìè, äåñòðóêòîðàìè è ò.ï. Îïðåäåë
3. (*1) Ïðåîáðàçóéòå êëàññ intset (#5.3.2) â ìíîæåñòâî ñòðîê.
4. (*1) Ïðåîáðàçóéòå êëàññ intset â ìíîæåñòâî óçëîâ node, ãäå node îïðåäåëÿåìàÿ âàìè ñòðó
5. (*3) Îïðåäåëèòå êëàññ äëÿ àíàëèçà, õðàíåíèÿ, âû÷èñëíèÿ è ïå÷àòè ïðîñòûõ àðèôìåòè÷åñêèõ â
class expr (* // ... public: expr(char*); int eval(); void print(); *) Ïàðàìåòð ñòðîêà êîíñ
expr x(«123/4+123*4-3»); cout « "x = " «« x.eval() «« «\n ; x.print();
Îïðåäåëèòå êëàññ expr äâà ðàçà: îäèí ðàç èñïîëüçóÿ â ê÷åñòâå ïðåäñòàâëåíèÿ ñâÿçàííûé ñïèñîê
6. (*1) Îïðåäåëèòå êëàññ char_queue (ñèìâîëüíàÿ î÷åðåäü) òàêèì îáðàçîì, ÷òîáû îòêðûòûé èíòå
7. (*2) Îïðåäåëèòå êëàññ histogram (ãèñòîãðàììà), â êòîðîì âåäåòñÿ ïîäñ÷åò ÷èñåë â îïðåäåëå
8. (*2) Îïðåäåëèòå íåñêîëüêî êëàññîâ, ïðåäîñòàâëÿþùèõ ñëó÷àéíûå ÷èñëà ñ îïðåäåëåííûìè ðàñïð
9. (*2) Ïåðåïèøèòå ïðèìåð date (#5.8.2), ïðèìåð char_stack (#5.2.5) è ïðèìåð intset (#5.3.2
10. (*3) Äëÿ êàêîãî-íèáóäü ÿçûêà ñïðîåêòèðóéòå êëàññ òàáëèöà èìåí è êëàññ âõîæäåíèå â òàáëè
11. (*2) Ìîäèôèöèðóéòå êëàññ âûðàæåíèå èç Óïðàæíåíèÿ 5 òàê, ÷òîáû îáðàáàòûâàòü ïåðåìåííûå è
12. (*1) Äàíà ïðîãðàììà:
#include «stream.h»
main() (* cout « «Hello, world\n ; *)
ìîäèôèöèðóéòå åå, ÷òîáû ïîëó÷èòü âûäà÷ó
Initialize Hello, world Clean up
Íå äåëàéòå íèêàêèõ èçìåíåíèé â main().

Ãëàâà 6 Ïåðåãðóçêà Îïåðàöèé


Çäåñü âîäÿòñÿ Äðàêîíû!
    ñòàðèííàÿ êàðòà

 ýòîé ãëàâå îïèñûâàåòñÿ àïïàðàò, ïðåäîñòàâëÿåìûé â Ñ++ äëÿ ïåðåãðóçêè îïåðàöèé. Ïðîãðàììèñ

6.1 Ââåäåíèå
×àñòî ïðîãðàììû ðàáîòàþò ñ îáúåêòàìè, êîòîðûå ÿâëÿþòñÿ êîíêðåòíûìè ïðåäñòàâëåíèÿìè àáñòðàêò
class complex (* double re, im; public: complex(double r, double i) (* re=r; im=
i; *) friend complex operator+(complex, complex); friend complex operator*(compl
ex, complex); *);
îïðåäåëÿåò ïðîñòóþ ðåàëèçàöèþ ïîíÿòèÿ êîìïëåêñíîãî ÷èëà, â êîòîðîé ÷èñëî ïðåäñòàâëÿåòñÿ ïàð
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

6.2 Ôóíêöèè Îïåðàöèè


Ìîæíî îïèñûâàòü ôóíêöèè, îïðåäåëÿþùèå çíà÷åíèÿ ñëåäóþùèõ îïåðàöèé:
+ * / % ^ amp; ! ~ ! = « » += -= *= /= %= ^= amp;= != « » »»= « = == != «= = amp; amp;
w delete
Ïîñëåäíèå ÷åòûðå ýòî èíäåêñèðîâàíèå (#6.7), âûçîâ ôóíêöèè (#6.8), âûäåëåíèå ñâîáîäíîé ïàì
Èìÿ ôóíêöèè îïåðàöèè åñòü êëþ÷åâîå ñëîâî operator (òî åñòü, îïåðàöèÿ), çà êîòîðûì ñëåäóåò ñ
void f(complex a, complex b) (* complex c = a + b; // ñîêðàùåííàÿ çàïèñü complex d = operat
Ïðè íàëè÷èè ïðåäûäóùåãî îïèñàíèÿ complex îáà èíèöèàëèçòîðà ÿâëÿþòñÿ ñèíîíèìàìè.

6.2.1 Áèíàðíûå è Óíàðíûå Îïåðàöèè


Áèíàðíàÿ îïåðàöèÿ ìîæåò áûòü îïðåäåëåíà èëè êàê ôóíêöèÿ ÷ëåí, ïîëó÷àþùàÿ îäèí ïàðàìåòð, èëè
class X (* // äðóçüÿ
friend X operator-(X); // óíàðíûé ìèíóñ friend X operator-(X,X); // áèíàðíûé ìèíóñ friend X
friend X operator-(X,X,X); // îøèáêà: òåðíàðíàÿ
// ÷ëåíû (ñ íåÿâíûì ïåðâûì ïàðàìåòðîì: this)
X* operator amp;(); // óíàðíîå amp; (âçÿòèå àäðåñà) X operator amp;(X); // áèíàðíîå amp; (î
*);
Êîãäà îïåðàöèè ++ è ïåðåãðóæåíû, ïðåôèêñíîå èñïîëüçâàíèå è ïîñòôèêñíîå ðàçëè÷èòü íåâîçìîæ

6.2.2 Ïðåäîïðåäåëåííûé Ñìûñë Îïåðàöèé


Îòíîñèòåëüíî ñìûñëà îïåðàöèé, îïðåäåëÿåìûõ ïîëüçîâàòëåì, íå äåëàåòñÿ íèêàêèõ ïðåäïîëîæåíèé.
Çíà÷åíèÿ íåêîòîðûõ âñòðîåííûõ îïåðàöèé îïðåäåëåíû êàê ðàâíîñèëüíûå îïðåäåëåííûì êîìáèíàöèÿì
Ïî èñòîðè÷åñêîìó ñîâïàäåíèþ îïåðàöèè = è amp; èìåþò îïðåäëåííûé ñìûñë äëÿ îáúåêòîâ êëàññîâ.
____________________ * Â íåêîòîðûõ ñèñòåìàõ êîìïîíîâùèê íàñòîëüêî «óìåí», ÷òî ðóãàåòñÿ, äàæ

6.2.3 Îïåðàöèè è Îïðåäåëÿåìûå Ïîëüçîâàòåëåì Òèïû


Ôóíêöèÿ îïåðàöèÿ äîëæíà èëè áûòü ÷ëåíîì, èëè ïîëó÷àòü â êà÷åñòâå ïàðàìåòðà ïî ìåíüøåé ìåðå
Ôóíêöèÿ îïåðàöèÿ, ïåðâûì ïàðàìåòðîì êîòîðîé ïðåäïîëàãåòñÿ îñíîâíîé âñòðîåííûé òèï, íå ìîæåò
òîãî, ÷òîáû îáðàáîòàòü è 2+aa è aa+2, ïîíàäîáèëîñü áû äâå ðàçëè÷íûõ ôóíêöèè ÷ëåíà. Òàê êàê
Âñå ôóíêöèè îïåðàöèè ïî îïðåäåëåíèþ ïåðåãðóæåíû. Ôóíêöèÿ îïåðàöèÿ çàäàåò íîâûé ñìûñë îïåðàö

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, do
uble); friend complex operator+(double, complex);
friend complex operator-(complex, complex); friend complex operator-(complex, do
uble); friend complex operator-(double, complex); complex operator-() // óíàðíûé -
friend complex operator*(complex, complex); friend complex operator*(complex, do
uble); friend complex operator*(double, complex);
// ... *);
Òåïåðü, èìåÿ îïèñàíèå 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, êàê ýòî äåëàëîñü âûøå äëÿ operato

6.3.1 Êîíñòðóêòîðû
Àëüòåðíàòèâó èñïîëüçîâàíèþ íåñêîëüêèõ ôóíêöèé (ïåðåãðæåííûõ) ñîñòàâëÿåò îïèñàíèå êîíñòðóêòî
class complex (* // ... complex(double r) (* re=r; im=0; *) *);
Êîíñòðóêòîð, òðåáóþùèé òîëüêî îäèí ïàðàìåòð, íåîáÿçòåëüíî âûçûâàòü ÿâíî:
complex z1 = complex(23); complex z2 = 23;
È z1, è z2 áóäóò èíèöèàëèçèðîâàíû âûçîâîì complex(23).
Êîíñòðóêòîð ýòî ïðåäïèñàíèå, êàê ñîçäàâàòü çíà÷åíèå äàííîãî òèïà. Êîãäà òðåáóåòñÿ çíà÷åíè
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, co
mplex); *);
è äåéñòâèÿ, â êîòîðûå áóäóò âõîäèòü ïåðåìåííûå complex è öåëûå êîíñòàíòû, ñòàëè áû äîïóñòèì
a=operator*( b, complex( double(2), double(0) ) )
Îïðåäåëåííîå ïîëüçîâàòåëåì ïðåîáðàçîâàíèå òèïà ïðèìåíåòñÿ íåÿâíî òîëüêî òîãäà, êîãäà îíî ÿâ
Îáúåêò, ñêîíñòðóèðîâàííûé ñ ïîìîùüþ ÿâíîãî èëè íåÿâíîãî âûçîâà êîíñòðóêòîðà, ÿâëÿåòñÿ àâòîì

6.3.2 Îïåðàöèè Ïðåîáðàçîâàíèÿ


Èñïîëüçîâàíèå êîíñòðóêòîðà äëÿ çàäàíèÿ ïðåîáðàçîâàíèÿ òèïà ÿâëÿåòñÿ óäîáíûì, íî èìååò ñëåäñ
1. Íå ìîæåò áûòü íåÿâíîãî ïðåîáðàçîâàíèÿ èç îïðåäåëåíîãî ïîëüçîâàòåëåì òèïà â îñíîâíîé òèï
2. Íåâîçìîæíî çàäàòü ïðåîáðàçîâàíèå èç íîâîãî òèïà â ñòàðûé, íå èçìåíÿÿ îïèñàíèå ñòàðîãî
3. Íåâîçìîæíî èìåòü êîíñòðóêòîð ñ îäíèì ïàðàìåòðîì, íå èìåÿ ïðè ýòîì ïðåîáðàçîâàíèÿ.
Ïîñëåäíåå íå ÿâëÿåòñÿ ñåðüåçíîé ïðîáëåìîé, à ñ ïåðâûìè äâóìÿ ìîæíî ñïðàâèòüñÿ, îïðåäåëèâ äë

class tiny (* char v; int assign(int i) (*return v=(i amp;~63) ? (error(«îøèáêà äèàïàçîíà»)
nt i) (* assign(i); *) tiny(tiny amp; i) (* v = t.v; *) int operator=(tiny amp;
i) (* return v = t.v; *) int operator=(int i) (* return assign(i); *) operator i
nt() (* return v; *) *)
Äèàïàçîí çíà÷åíèÿ ïðîâåðÿåòñÿ âñåãäà, êîãäà tiny èíèöèëèçèðóåòñÿ int, è âñåãäà, êîãäà åìó ï
void main() (* tiny c1 = 2; tiny c2 = 62; tiny c3 = c2 c1; // c3 = 60 tiny c4 =
c3; // íåò ïðîâåðêè äèàïàçîíà (íåîáÿçàòåëüíà) int i = c1 + c2; // i = 64 c1 = c2 + 2 * c1;
Òèï âåêòîð èç tiny ìîæåò îêàçàòüñÿ áîëåå ïîëåçíûì, ïîêîëüêó îí ýêîíîìèò ïðîñòðàíñòâî. ×òîáû
Äðóãîå ïðèìåíåíèå îïðåäåëÿåìûõ îïåðàöèé ïðåîáðàçîâàíèÿ ýòî òèïû, êîòîðûå ïðåäîñòàâëÿþò íå
Ôóíêöèè ïðåîáðàçîâàíèÿ îêàçûâàþòñÿ îñîáåííî ïîëåçíûìè äëÿ ðàáîòû ñî ñòðóêòóðàìè äàííûõ, êîã
Òèïû istream è ostream îïèðàþòñÿ íà ôóíêöèþ ïðåîáðàçîâíèÿ, ÷òîáû ñäåëàòü âîçìîæíûìè òàêèå î
while (cin»»x) cout««x;
Äåéñòâèå ââîäà cin»»x âûøå âîçâðàùàåò istream amp;. Ýòî çí÷åíèå íåÿâíî ïðåîáðàçóåòñÿ ê çíà÷

6.3.3 Íåîäíîçíà÷íîñòè
Ïðèñâàèâàíèå îáúåêòó (èëè èíèöèàëèçàöèÿ îáúåêòà) êëàññà X ÿâëÿåòñÿ äîïóñòèìûì, åñëè èëè ïðè
class x (* /* ... */ x(int); x(char*); *); class y (* /* ... */ y(int); *); clas
s z (* /* ... */ z(x); *);
overload f; 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»); // í
Îïðåäåëÿåìûå ïîëüçîâàòåëåì ïðåîáðàçîâàíèÿ ðàññìàòðèâàþñÿ òîëüêî â òîì ñëó÷àå, åñëè áåç íèõ
class x (* /* ... */ x(int); *) overload h(double), h(x); h(1);
Âûçîâ ìîã áû áûòü ïðîèíòåðïðåòèðîâàí èëè êàê h(double(1)), èëè êàê h(x(1)), è áûë áû íåäîïó
Ïðàâèëà ïðåîáðàçîâàíèÿ íå ÿâëÿþòñÿ íè ñàìûìè ïðîñòûìè äëÿ ðåàëèçàöèè è äîêóìåíòàöèè, íè íàè
Ñàìûé îáùèé ïîäõîä ó÷èòûâàë áû âñþ èìåþùóþñÿ èíôîðìàöèþ î òèïàõ è ðàññìàòðèâàë áû âñå âîçìî

6.4 Êîíñòàíòû
Êîíñòàíòû êëàññîâîãî òèïà îïðåäåëèòü íåâîçìîæíî â òîì ñìûñëå, â êàêîì 1.2 è 12e ÿâëÿþòñÿ êî

6.5 Áîëüøèå Îáúåêòû


Ïðè êàæäîì ïðèìåíåíèè äëÿ comlpex áèíàðíûõ îïåðàöèé, îïèñàííûõ âûøå, â ôóíêöèþ, êîòîðàÿ ðåà
class matrix (* double m[4][4]; public: matrix(); friend matrix operator+(matrix
amp;, matrix amp;); friend matrix operator*(matrix amp;, matrix amp;); *);
Ññûëêè ïîçâîëÿþò èñïîëüçîâàòü âûðàæåíèÿ, ñîäåðæàùèå îáû÷íûå àðèôìåòè÷åñêèå îïåðàöèè íàä áîë
matrix operator+(matrix amp;, matrix amp;); (* 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 amp; operator+(matrix amp;, matrix amp;);
friend matrix amp; operator*(matrix amp;, matrix amp;); *);
Ýòî ÿâëÿåòñÿ äîïóñòèìûì, íî ïðèâîäèò ê ñëîæíîñòè ñ âûäëåíèåì ïàìÿòè. Ïîñêîëüêó ññûëêà íà ðå

6.6 Ïðèñâàèâàíèå è Èíèöèàëèçàöèÿ


Ðàññìîòðèì î÷åíü ïðîñòîé êëàññ ñòðîê string:
struct string (* char* p; int size; // ðàçìåð âåêòîðà, íà êîòîðûé óêàçûâàåò p
string(int sz) (* p = new char[size=sz]; *) ~string() (* delete p; *) *);
Ñòðîêà ýòî ñòðóêòóðà äàííûõ, ñîñòîÿùàÿ èç âåêòîðà ñèâîëîâ è äëèíû ýòîãî âåêòîðà. Âåêòîð ñ
void f() (* string s1(10); string s2(20); s1 = s2; *)
áóäåò ðàçìåùàòü äâà âåêòîðà ñèìâîëîâ, à ïðèñâàèâàíèå s1= s2 áóäåò ïîðòèòü óêàçàòåëü íà îäèí
struct string (* char* p; int size; // ðàçìåð âåêòîðà, íà êîòîðûé óêàçûâàåò p
string(int sz) (* p = new char[size=sz]; *) ~string() (* delete p; *) void opera
tor=(string amp;) *);
void string::operator=(string amp; a) (* if (this == amp;a) return; // îñòåðåãàòüñÿ s=s; de
char[size=a.size]; strcpy(p,a.p); *)
Ýòî îïðåäåëåíèå string ãàðàíòèðóåò,è ÷òî ïðåäûäóùèé ïðìåð áóäåò ðàáîòàòü êàê ïðåäïîëàãàëîñü

void f() (* string s1(10); s2 = s1; *)


Òåïåðü ñîçäàåòñÿ òîëüêî îäíà ñòðîêà, à óíè÷òîæàåòñÿ äâå. Ê íåèíèöèàëèçèðîâàííîìó îáúåêòó îï
struct string (* char* p; int size; // ðàçìåð âåêòîðà, íà êîòîðûé óêàçûâàåò p
string(int sz) (* p = new char[size=sz]; *) ~string() (* delete p; *) void opera
tor=(string amp;); string(string amp;); *);
void string::string(string amp; a) (* p=new char[size=a.size]; strcpy(p,a.p); *)
Äëÿ òèïà X èíèöèàëèçàöèþ òåì æå òèïîì X îáðàáàòûâàåò êîíñòðóêòîð X(X amp;). Íåëüçÿ íå ïîä÷å
class X (* // ... X(something); // êîíñòðóêòîð: ñîçäàåò îáúåêò X( amp;X); // êîíñòðóêòîð: ê
Åñòü åùå äâà ñëó÷àÿ, êîãäà îáúåêò êîïèðóåòñÿ: êàê ïàðìåòð ôóíêöèè è êàê âîçâðàùàåìîå çíà÷åí
string g(string arg) (* return arg; *)
main() (* string s = «asdf»; s = g(s);
*) ßñíî, ÷òî ïîñëå âûçîâà g() çíà÷åíèå s îáÿçàíî áûòü «asdf». Êîïèðîâàíèå çíà÷åíèÿ s â ïàðà

6.7 Èíäåêñèðîâàíèå
×òîáû çàäàòü ñìûñë èíäåêñîâ äëÿ îáúåêòîâ êëàññà, èñïîëçóåòñÿ ôóíêöèÿ operator[]. Âòîðîé ïàð
struct pair (* char* name; int val; *);
class assoc (* pair* vec; int max; int free; public: assoc(int); int amp; operat
or[](char*); void print_all(); *);
 assoc õðàíèòñÿ âåêòîð ïàð pair äëèíû max. Èíäåêñ ïåâîãî íåèñïîëüçîâàííîãî ýëåìåíòà âåêòîð
assoc::assoc(int s) (* max = (s«16) ? s : 16; free = 0; vec = new pair[max]; *)
Ïðè ðåàëèçàöèè ïðèìåíÿåòñÿ âñå òîò æå ïðîñòîé è íåýôôåòèâíûé ìåòîä ïîèñêà, ÷òî èñïîëüçîâàëñ
#include «string.h»
int assoc::operator[](char* p) /* ðàáîòà ñ ìíîæåñòâîì ïàð «pair»: ïîèñê p, âîçâðàò ññûëêè í
for (pp= amp;vec[free-1]; vec«=pp; pp ) if (strcmp(p,pp-»name)==0) return pp-»val;
if (free==max) (* // ïåðåïîëíåíèå: âåêòîð óâåëè÷èâàåòñÿ
pair* nvec = new pair[max*2]; for ( int i=0; i«max; i++) nvec[i] = vec[i]; delete
vec; vec = nvec; max = 2*max; *)
pp = amp;vec[free++]; pp-»name = new char[strlen(p)+1]; strcpy(pp-»name,p); pp-»val =
0; // íà÷àëüíîå çíà÷åíèå: 0 return pp-»val; *)
Ïîñêîëüêó ïðåäñòàâëåíèå assoc ñêðûòî, íàì íóæåí ñïîñîá åãî ïå÷àòè.  ñëåäóþùåì ðàçäåëå áóäå
vouid assoc::print_all() (* for (int i = 0; i«free; i++) cout « vec[i].name «« ": " «« vec
.val «« «\n ; *)
Ìû ìîæåì, íàêîíåö, íàïèñàòü ïðîñòóþ ãëàâíóþ ïðîãðàììó:
main() // ñ÷èòàåò âõîæäåíèÿ êàæäîãî ñëîâà âî ââîäå (* const MAX = 256; // áîëüøå ñàìîãî áîë

6.8 Âûçîâ Ôóíêöèè


Âûçîâ ôóíêöèè, òî åñòü çàïèñü âûðàæåíèå(ñïèñîê_âûðàæíèé), ìîæíî ïðîèíòåðïðåòèðîâàòü êàê áèí
Äëÿ òèïà àññîöèàòèâíîãî ìàññèâà assoc ìû íå îïðåäåëèëè èòåðàòîð. Ýòî ìîæíî ñäåëàòü, îïðåäåë
class assoc (* friend class assoc_iterator; pair* vec; int max; int free; public
: assoc(int); int amp; operator[](char*); *);
Èòåðàòîð îïðåäåëÿåòñÿ êàê

class assoc_iterator(* assoc* cs; // òåêóùèé ìàññèâ assoc int i; // òåêóùèé èíäåêñ public:
s; i = 0; *) pair* operator()() (* return (i«cs-»free)? amp;cs-»vec[i++] : 0; *) *);
Íàäî èíèöèàëèçèðîâàòü assoc_iterator äëÿ ìàññèâà assoc, ïîñëå ÷åãî îí áóäåò âîçâðàùàòü óêàç
main() // ñ÷èòàåò âõîæäåíèÿ êàæäîãî ñëîâà âî ââîäå (* const MAX = 256; // áîëüøå ñàìîãî áîë
( p = next() ) cout « p- name ": " «« p- val «« «\n ; *)
0 Èòåðàòîðíûé òèï âðîäå ýòîãî èìååò ïðåèìóùåñòâî ïåðåä íáîðîì ôóíêöèé, êîòîðûå âûïîëíÿþò òó
Êîíå÷íî, òàêîå ïðèìåíåíèå îáúåêòîâ äëÿ ïðåäñòàâëåíèÿ èòåðàòîðîâ íèêàê îñîáåííî ñ ïåðåãðóçêî

6.9 Êëàññ String


Âîò äîâîëüíî ðåàëèñòè÷íûé ïðèìåð êëàññà ñòðîê string.  íåì ïðîèçâîäèòñÿ ó÷åò ññûëîê íà ñòð
#include «stream.h» #include «string.h»
class string (* struct srep (* char* s; // óêàçàòåëü íà äàííûå int n; // ñ÷åò÷èê ññûëîê *);
public: string(char *); // string x = «abc» string(); // string x; string(string amp
;); // string x = string ... string amp; operator=(char *); string amp; operator
=(string amp;); ~string(); char amp; operator[](int i);
friend ostream amp; operator« (ostream amp;, string amp;); friend istream amp; opera
tor »(istream amp;, string amp;);

friend int operator==(string amp; x, char* s) (*return strcmp(x.p-»s, s) == 0; *)


friend int operator==(string amp; x, string amp; y) (*return strcmp(x.p-»s, y.p-»s)
== 0; *)
friend int operator!=(string amp; x, char* s) (*return strcmp(x.p-»s, s) != 0; *)
friend int operator!=(string amp; x, string amp; 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 amp; x) (* x.p-»n++; p = x.p; *)
string::~string() (* if ( p-»n == 0) (* delete p-»s; delete p; *) *)
Êàê îáû÷íî, îïåðàöèè ïðèñâàèâàíèÿ î÷åíü ïîõîæè íà êîíòðóêòîðû. Îíè äîëæíû îáðàáàòûâàòü î÷èñ
string amp; string::operator=(char* s) (* if (p-»n » 1) (* // ðàçúåäèíèòü ñåáÿ p-»n ; p = n
1) delete p-»s;
p-»s = new char[ strlen(s)+1 ]; strcpy(p-»s, s); p-»n = 1; return *this; *)
Áëàãîðàçóìíî îáåñïå÷èòü, ÷òîáû ïðèñâàèâàíèå îáúåêòà ñìîìó ñåáå ðàáîòàëî ïðàâèëüíî:

string amp; string::operator=(string amp; x) (* x.p-»n++; if ( p-»n == 0) (* delete p-»s


; delete p; *) p = x.p; return *this; *)
Îïåðàöèÿ âûâîäà çàäóìàíà òàê, ÷òîáû ïðîäåìîíñòðèðîâàòü ïðèìåíåíèå ó÷åòà ññûëîê. Îíà ïîâòîðÿ
ostream amp; operator« (ostream amp; s, string amp; x) (* return s x.p- s « « [ «« x.p
Îïåðàöèÿ ââîäà èñïîëüçóåò ñòàíäàðòíóþ ôóíêöèþ ââîäà ñèâîëüíîé ñòðîêè (#8.4.1).
istream amp; operator»»(istream amp; s, string amp; x) (* char buf[256]; s »» buf; x = b
uf; cout « "echo: " «« x «« «\n ; return s; *)
Äëÿ äîñòóïà ê îòäåëüíûì ñèìâîëàì ïðåäîñòàâëåíà îïåðàöèÿ èíäåêñèðîâàíèÿ. Îñóùåñòâëÿåòñÿ ïðîâ
void error(char* p) (* cerr « p «« «\n ; exit(1); *)
char amp; string::operator[](int i) (* if (i«0 !! strlen(p-»s)«i) error( èíäåêñ çà ãðàíèöàì
Ãîëîâíàÿ ïðîãðàììà ïðîñòî íåìíîãî îïðîáóåò äåéñòâèÿ íàä ñòðîêàìè. Îíà ÷èòàåò ñëîâà ñî ââîäà
main() (* string x[100]; int n;
cout « îòñþäà íà÷íåì\n ; for (n = 0; cin »x[n]; n++) (* string y; if (n==100) error(«ñëèø
t «« «îòñþäà ìû ïðîéäåì îáðàòíî\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 amp;); *);
Âíåøíå íå âèäíî íèêàêèõ ïðè÷èí äåëàòü f(X amp;) äðóãîì äïîëíèòåëüíî ê ÷ëåíó X::m() (èëè íàî
void g() (* 1.m(); // îøèáêà f(1); // f(x(1)); *)
Ïîýòîìó îïåðàöèÿ, èçìåíÿþùàÿ ñîñòîÿíèå îáúåêòà, äîëæíà áûòü ÷ëåíîì, à íå äðóãîì. Äëÿ îïðåäå
È íàîáîðîò, åñëè íóæíî èìåòü íåÿâíîå ïðåîáðàçîâàíèå äëÿ âñåõ îïåðàíäîâ îïåðàöèè, òî ðåàëèçó
Åñëè íèêàêèå ïðåîáðàçîâàíèÿ òèïà íå îïðåäåëåíû, òî îêçûâàåòñÿ, ÷òî íåò íèêàêèõ ñóùåñòâåííûõ
Ïðè ïðî÷èõ ðàâíûõ óñëîâèÿõ âûáèðàéòå, ÷òîáû ôóíêöèÿ áûëà ÷ëåíîì: íèêòî íå çíàåò, âäðóã êîãä
îáû÷íî êîðî÷å èìåí äðóçåé.

6.11 Ïðåäîñòåðåæåíèå
Êàê è áîëüøóþ ÷àñòü âîçìîæíîñòåé â ÿçûêàõ ïðîãðàììèðîâíèÿ, ïåðåãðóçêó îïåðàöèé ìîæíî èñïîëü
Èçëîæåííûé àïïàðàò äîëæåí óáåðå÷ü ïðîãðàììèñòà/÷èòàòåëÿ îò õóäøèõ êðàéíîñòåé ïðèìåíåíèÿ ïåð
Ìîæåò áûòü, ðàçóìíî ïðèìåíÿòü ïåðåãðóçêó îïåðàöèé ãëàâíûì îáðàçîì òàê, ÷òîáû ïîäðàæàòü îáùå

6.12 Óïðàæíåíèÿ
1. (*2) Îïðåäåëèòå èòåðàòîð äëÿ êëàññà string. Îïðåäåëèòå îïåðàöèþ êîíêàòåíàöèè + è îïåðàöè
2. (*1.5) Çàäàéòå ñ ïîìîùüþ ïåðåãðóçêè () îïåðàöèþ âûäåëíèÿ ïîäñòðîêè äëÿ êëàññà ñòðîê.
3. (*3) Ïîñòðîéòå êëàññ string òàê, ÷òîáû îïåðàöèÿ âûäåëíèÿ ïîäñòðîêè ìîãëà èñïîëüçîâàòüñÿ
4. (*2) Ïîñòðîéòå êëàññ string òàê, ÷òîáû äëÿ ïðèñâàèâàíèÿ, ïåðåäà÷è ïàðàìåòðîâ è ò.ï. îí è
5. (*3) Ìîäèôèöèðóéòå êëàññ string èç ïðåäûäóùåãî ïðèìåðà òàêèì îáðàçîì, ÷òîáû ñòðîêà êîïèð
6. (*4) Ðàçðàáîòàéòå êëàññ string ñ ñåìàíòèêîé ïî çíà÷åíèþ, êîïèðîâàíèåì ñ çàäåðæêîé è îïåð
7. (*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); y + y; 1
06 + y; *)
Îïðåäåëèòå X è Y òàê, ÷òîáû îíè îáà áûëè öåëûìè òèïàìè. Èçìåíèòå ïðîãðàììó òàê, ÷òîáû îíà ð
8. (*2) Îïðåäåëèòå êëàññ INT, êîòîðûé âåäåò ñåáÿ â òî÷íîñòè êàê int. Ïîäñêàçêà: îïðåäåëèòå
9. (*1) Îïðåäåëèòå êëàññ RINT, êîòîðûé âåäåò ñåáÿ â òî÷íîòè êàê int çà èñêëþ÷åíèåì òîãî, ÷ò
10. (*3) Îïðåäåëèòå êëàññ LINT, âåäóùèé ñåáÿ êàê RINT, çà èñêëþ÷åíèåì òîãî, ÷òî èìååò òî÷íî
11. (*4) Îïðåäåëèòå êëàññ, êîòîðûé ðåàëèçóåò àðèôìåòèêó ñ ïðîèçâîëüíîé òî÷íîñòüþ. Ïîäñêàçêà
12. (*2) Íàïèøèòå ïðîãðàììó, äîâåäåííóþ äî íå÷èòàåìîãî ñîòîÿíèÿ ñ ïîìîùüþ ìàêðîñîâ è ïåðåãð
13. (*3) Ïîìåíÿéòåñü ñî ñâîèì äðóãîì ïðîãðàììàìè, êîòîðûå ó âàñ ïîëó÷èëèñü â ïðåäûäóùåì óïð
14. (*2) Ïåðåïèøèòå ïðèìåðû ñ comlpex (#6.3.1), tiny (#6.3.2) è string (#6.9) íå èñïîëüçóÿ
15. (*2) Îïðåäåëèòå òèï vec4 êàê âåêòîð èõ ÷åòûðåõ float. Îïðåäåëèòå operator[] äëÿ vec4. Î
16. (*3) Îïðåäåëèòå êëàññ mat4 êàê âåêòîð èç ÷åòûðåõ vec4. Îïðåäåëèòå äëÿ mat4 operator[],
17. (*2) Îïðåäåëèòå êëàññ vector, àíàëîãè÷íûé vec4, íî ñ äëèíîé, êîòîðàÿ çàäàåòñÿ êàê ïàðàì
18. (*3) Îïðåäåëèòå êëàññ matrix, àíàëîãè÷íûé mat4, íî ñ ðàçìåðíîñòüþ, çàäàâàåìîé ïàðàìåòðà

Ãëàâà 7 Ïðîèçâîäíûå Êëàññû


Íå íàäî ðàçìíîæàòü îáúåêòû áåç íåîáõîäèìîñòè
    Ó. Îêêàì

 ýòîé ãëàâå îïèñûâàåòñÿ ïîíÿòèå ïðîèçâîäíîãî êëàññà â Ñ ++. Ïðîèçâîäíûå êëàññû äàþò ïðîñòî

7.1 Ââåäåíèå
Ïðåäñòàâèì ñåáå ïðîöåññ íàïèñàíèÿ íåêîòîðîãî óíèâåðñàëíîãî ñðåäñòâà (íàïðèìåð, òèï ñâÿçàííû
Ïðè÷èíà ýòîãî õàîñà ÷àñòè÷íî ñîñòîèò â òîì, ÷òî ïðåäñòâèòü òàêèå îáùèå ïîíÿòèÿ â ÿçûêå ïðîã
Íàïèñàíèå îáùåöåëåâûõ ñðåäñòâ çàäà÷à íåïðîñòàÿ, è ÷àòî îñíîâíîé àêöåíò â èõ ðàçðàáîòêå äð

7.2 Ïðîèçâîäíûå Êëàññû


×òîáû ðàçäåëèòü çàäà÷è ïîíèìàíèÿ àïïàðàòà ÿçûêà è ìåòäîâ åãî ïðèìåíåíèÿ, çíàêîìñòâî ñ ïîíÿò
ñàìè ñðåäñòâà ÿçûêà (çàïèñü è ñåìàíòèêà). Ïîñëå ýòîãî äåìîíòðèðóþòñÿ íåêîòîðûå íåî÷åâèäíûå

7.2.1 Ïîñòðîåíèå Ïðîèçâîäíîãî Êëàññà


Ðàññìîòðèì ïîñòðîåíèå ïðîãðàììû, êîòîðàÿ èìååò äåëî ñ ëþäüìè, ñëóæàùèìè â íåêîòîðîé ôèðìå.
struct employee (* // ñëóæàùèé char* name; // èìÿ short age; // âîçðàñò short department; /
Ñïèñîê àíàëîãè÷íûõ ñëóæàùèõ áóäåò ñâÿçûâàòüñÿ ÷åðåç ïîëå next. Òåïåðü äàâàéòå îïðåäåëèì ìåí
struct manager (* // ìåíåäæåð employee emp; // çàïèñü î ìåíåäæåðå êàê î ñëóæàùåì employee*
Ìåíåäæåð òàêæå ÿâëÿåòñÿ ñëóæàùèì; îòíîñÿùèåñÿ ê ñëóæàùìó employee äàííûå õðàíÿòñÿ â ÷ëåíå e
struct manager : employee (* employee* group; // ... *);
manager ÿâëÿåòñÿ ïðîèçâîäíûì îò employee è, îáðàòíî, employee åñòü áàçîâûé êëàññ äëÿ manage
Èìåÿ îïðåäåëåíèÿ employee è manager ìû ìîæåì òåïåðü ñîäàòü ñïèñîê ñëóæàùèõ, íåêîòîðûå èç êî
void f() (* manager m1, m2; employee e1, e2; employee* elist; elist = amp;m1; //
ïîìåñòèòü m1, e1, m2 è e2 â elist m1.next = amp;e1; e1.next = amp;m2; m2.next = amp;e2; e2
*)

Ïîñêîëüêó ìåíåäæåð ÿâëÿåòñÿ ñëóæàùèì, manager* ìîæåò èïîëüçîâàòüñÿ êàê employee*. Îäíàêî ñë
7.2.2 Ôóíêöèè ×ëåíû
Ïðîñòî ñòðóêòóðû äàííûõ âðîäå employee è manager íà ñìîì äåëå íå ñòîëü èíòåðåñíû è ÷àñòî íå
class employee (* char* name; // ... public: employee* next; void print(); // ..
. *);
class manager : public employee (* // ... public: void print(); // ... *);
Íàäî îòâåòèòü íà íåêîòîðûå âîïðîñû. Êàê ìîæåò ôóíêöèÿ ÷ëåí ïðîèçâîäíîãî êëàññà manager èñïî
Ðàññìîòðèì:
void manager::print() (* cout « " èìÿ " «« name «« «\n ; // ... *)
×ëåí ïðîèçâîäíîãî êëàññà ìîæåò èñïîëüçîâàòü îòêðûòîå èìÿ èç ñâîåãî áàçîâîãî êëàññà òàê æå,
Ýòî ìíîãèì ïîêàæåòñÿ óäèâèòåëüíûì, íî ïðåäñòàâüòå ñåáå äðóãîé âàðèàíò: ÷òî ôóíêöèÿ ÷ëåí ìîã

Ñ äðóãîé ñòîðîíû, ìîæíî âåäü èñïîëüçîâàòü ìåõàíèçì friend, ÷òîáû ïðåäîñòàâèòü òàêîé äîñòóï
class employee (* friend void manager::print(); // ... *);
ðåøèëî áû ïðîáëåìó ñ manager::print(), è
class employee (* friend class manager; // ... *);
ñäåëàëî áû äîñòóïíûì êàæäûé ÷ëåí employee äëÿ âñåõ ôóíöèé êëàññà manager.  ÷àñòíîñòè, ýòî
Äðóãîå, èíîãäà áîëåå ïðîçðà÷íîå ðåøåíèå äëÿ ïðîèçâîäíîãî êëàññà èñïîëüçîâàòü òîëüêî îòêðû
void manager::print() (* employee::print(); // ïå÷àòàåò èíôîðìàöèþ î ñëóæàùåì // ... // ïå÷
Çàìåòüòå, ÷òî íàäî èñïîëüçîâàòü ::, ïîòîìó ÷òî print() áûëà ïåðåîïðåäåëåíà â manager. Òàêîå
void manager::print() (* print(); // ïå÷àòàåò èíôîðìàöèþ î ñëóæàùåì // ... // ïå÷àòàåò èíôî
è îáíàðóæèòü, ÷òî ïðîãðàììà ïîñëå âûçîâà manager::print() íåîæèäàííî ïîïàäàåò â ïîñëåäîâàòå

7.2.3 Âèäèìîñòü
Êëàññ employee ñòàë îòêðûòûì (public) áàçîâûì êëàññîì êëàññà manager â ðåçóëüòàòå îïèñàíèÿ:
class manager : public employee (* // ... *);
Ýòî îçíà÷àåò, ÷òî îòêðûòûé ÷ëåí êëàññà employee ÿâëÿåòñÿ òàêæå è îòêðûòûì ÷ëåíîì êëàññà man
void clear(manager* p) (* p-»next = 0; *)
áóäåò êîìïèëèðîâàòüñÿ, òàê êàê next îòêðûòûé ÷ëåí è employee è manager'à. Àëüòåðíàòèâà

class manager : employee (* // ... *);


Ýòî îçíà÷àåò, ÷òî îòêðûòûé ÷ëåí êëàññà employee ÿâëÿåòñÿ çàêðûòûì ÷ëåíîì êëàññà manager. Òî
Ïîñêîëüêó, êàê îêàçûâàåòñÿ, îïèñàíèå îòêðûòûõ áàçîâûõ êëàññîâ âñòðå÷àåòñÿ ÷àùå îïèñàíèÿ çàê
Êîãäà îïèñûâàåòñÿ ïðîèçâîäíàÿ struct, åå áàçîâûé êëàññ ïî óìîë÷àíèþ ÿâëÿåòñÿ public áàçîâûì
struct D : B (* ...
îçíà÷àåò
class D : public B (* public: ...
Îòñþäà ñëåäóåò, ÷òî åñëè âû íå ñî÷ëè ïîëåçíûì òî ñîêðòèå äàííûõ, êîòîðîå äàþò class, public
Ìîæíî òàêæå îáúÿâèòü íåêîòîðûå, íî íå âñå, îòêðûòûå ÷ëíû áàçîâîãî êëàññà îòêðûòûìè ÷ëåíàìè
class manager : employee (* // ... public: // ... employee::name; employee::depa
rtment; *);
Çàïèñü
èìÿ_êëàññà :: èìÿ_÷ëåíà ;
íå ââîäèò íîâûé ÷ëåí, à ïðîñòî äåëàåò îòêðûòûé ÷ëåí áçîâîãî êëàññà îòêðûòûì äëÿ ïðîèçâîäíîã
Ïîäûòîæèâàÿ, ìîæíî ñêàçàòü, ÷òî âìåñòå ñ ïðåäîñòàâëåíèåì ñðåäñòâ äîïîëíèòåëüíî ê èìåþùèìñÿ

7.2.4 Óêàçàòåëè
Åñëè ïðîèçâîäíûé êëàññ derived èìååò îòêðûòûé áàçîâûé êëàññ base, òî óêàçàòåëü íà derived ì
class base (* /* ... */ *); class derived : public base (* /* ... */ *);
derived m; base* pb = amp;m; // íåÿâíîå ïðåîáðàçîâàíèå derived* pd = pb; // îøèáêà: base* í
Èíà÷å ãîâîðÿ, îáúåêò ïðîèçâîäíîãî êëàññà ïðè ðàáîòå ñ íèì ÷åðåç óêàçàòåëü è ìîæíî ðàññìàòðè
Áóäü base çàêðûòûì áàçîâûì êëàññîì êëàññà derived, íåÿíîå ïðåîáðàçîâàíèå derived* â base* í
class base (* int m1; public: int m2; // m2 îòêðûòûé ÷ëåí base *);
class derived : base (* // m2 ÍÅ îòêðûòûé ÷ëåí derived *);
derived d; d.m2 = 2; // îøèáêà: m2 èç çàêðûòîé ÷àñòè êëàññà base* pb = amp;d; // îøèáêà: (ç
Ïîìèìî âñåãî ïðî÷åãî, ýòîò ïðèìåð ïîêàçûâàåò, ÷òî èïîëüçóÿ ÿâíîå ïðèâåäåíèå ê òèïó ìîæíî ñë

7.2.5 Èåðàðõèÿ Òèïîâ


Ïðîèçâîäíûé êëàññ ñàì ìîæåò áûòü áàçîâûì êëàññîì. Íàïðèìåð:
class employee (* ... *); class secretary : employee (* ... *); class manager :
employee (* ... *); class temporary : employee (* ... *); class consultant : tem
porary (* ... *); class director : manager (* ... *); class vice_president : man
ager (* ... *); class president : vice_president (* ... *);
Òàêîå ìíîæåñòâî ðîäñòâåííûõ êëàññîâ ïðèíÿòî íàçûâàòü èðàðõèåé êëàññîâ. Ïîñêîëüêó ìîæíî âûâî
class temporary (* ... *); class employee { ... *); class secretary : employee (
* ... *);
// íå Ñ++: class temporary_secretary : temporary : secretary(* ... *); class consultan
t : temporary : employee (* ... *);
È ýòîò ôàêò âûçûâàåò ñîæàëåíèå, ïîòîìó ÷òî íàïðàâëåííûé àöèêëè÷åñêèé ãðàô ïðîèçâîäíûõ êëàññ
class temporary (* ... *); class employee (* ... *); class secretary : employee
(* ... *);
// Àëüòåðíàòèâà: class temporary_secretary : secretary (* temporary temp; ... *); class con
loyee (* temporary temp; ... *);
Ýòî âûãëÿäèò íåýëåãàíòíî è ñòðàäàåò êàê ðàç îò òåõ ïðîëåì, äëÿ ïðåîäîëåíèÿ êîòîðûõ áûëè èçî

7.2.6 Êîíñòðóêòîðû è Äåñòðóêòîðû


Äëÿ íåêîòîðûõ ïðîèçâîäíûõ êëàññîâ íóæíû êîíñòðóêòîðû. Åñëè ó áàçîâîãî êëàññà åñòü êîíñòðóêò
class base (* // ... public: base(char* n, short t); ~base(); *);
class derived : public base (* base m; public: derived(char* n); ~derived(); *);
Ïàðàìåòðû êîíñòðóêòîðà áàçîâîãî êëàññà ñïåöèôèöèðóþòñÿ â îïðåäåëåíèè êîíñòðóêòîðà ïðîèçâîäí
derived::derived(char* n) : (n,10), m(«member»,123) (* // ... *)

Îáúåêòû êëàññà êîíñòðóèðóþòñÿ ñíèçó ââåðõ: ñíà÷àëà áàçâûé, ïîòîì ÷ëåíû, à ïîòîì ñàì ïðîèçâî

7.2.7 Ïîëÿ Òèïà


×òîáû èñïîëüçîâàòü ïðîèçâîäíûå êëàññû íå ïðîñòî êàê óäîáíóþ ñîêðàùåííóþ çàïèñü â îïèñàíèÿõ,
1. Îáåñïå÷èòü, ÷òîáû âñåãäà óêàçûâàëèñü òîëüêî îáúåêòû îäíîãî òèïà (#7.3.3),
2. Ïîìåñòèòü â áàçîâûé êëàññ ïîëå òèïà, êîòîðîå ñìîãóò ïðîñìàòðèâàòü ôóíêöèè è
3. Èñïîëüçîâàòü âèðòóàëüíûå ôóíêöèè (#7.2.8).
Îáûêíîâåííî óêàçàòåëè íà áàçîâûå êëàññû èñïîëüçóþòñÿ ïðè ðàçðàáîòêå êîíòåéíåðíûõ (èëè âìåùà
Äàâàéòå ñíà÷àëà èññëåäóåì ïðîñòîå ðåøåíèå ñ ïîìîùüþ ïîëÿ òèïà, òî åñòü ðåøåíèå 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
nt \n ; // ... break; case M: cout « e- name «« «\t «« e- department «« «\n ; // ...
cout «« " óðîâåíü " «« p- level «« «\n ; // ... break;
*) *)
è âîñïîëüçîâàòüñÿ åþ äëÿ òîãî, ÷òîáû íàïå÷àòàòü ñïèñîê ñëóæàùèõ:
void f() (* for (; ll; ll=ll-»next) print_employee(ll); *)
Ýòî ïðåêðàñíî ðàáîòàåò,îñîáåííî â íåáîëüøîé ïðîãðàììå, íàïèñàííîé îäíèì ÷åëîâåêîì, íî èìååò
void print_employee(employee* e) (* cout « e- name \t e- department « «\n ; // ..
(* manager* p = (manager*)e; cout «« " óðîâåíü " «« p- level «« «\n ; // ... *) *)
Îòûñêàíèå âñåõ òàêèõ îïåðàòîðîâ if, ñêðûòûõ âíóòðè áîëøîé ôóíêöèè, êîòîðàÿ ðàáîòàåò ñ áîëüø

7.2.8 Âèðòóàëüíûå Ôóíêöèè


Âèðòóàëüíûå ôóíêöèè ïðåîäîëåâàþò ñëîæíîñòè ðåøåíèÿ ñ ïìîùüþ ïîëåé òèïà, ïîçâîëÿÿ ïðîãðàììèñ
struct employee (* employee* next; char* name; short department; // ... virtual
void print(); *);
Êëþ÷åâîå ñëîâî virtual óêàçûâàåò, ÷òî ìîãóò áûòü ðàçëèíûå âàðèàíòû ôóíêöèè 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; e.name = «Äæ.Áðàóí»; e.department = 1234; e.next = 0; manager m; m.na
tment = 1234; m.level = 2; m.next = amp;e; f( amp;m); *)
âûäàñò
Äæ.Ñìèò 1234 óðîâåíü 2 Äæ.Áðàóí 1234
Çàìåòüòå, ÷òî ýòî áóäåò ðàáîòàòü äàæå â òîì ñëó÷àå, åñëè f() áûëà íàïèñàíà è îòêîìïèëèðîâàí
âñåõ îáúåêòàõ ïðîèçâîäíûõ êëàññîâ. Âû ïëàòèòå ýòó ïîøëèíó òîëüêî çà òå êëàññû, äëÿ êîòîðûõ
Âûçîâ ôóíêöèè ñ ïîìîùüþ îïåðàöèè ðàçðåøåíèÿ îáëàñòè âäèìîñòè ::, êàê ýòî äåëàåòñÿ â manager
7.3 Àëüòåðíàòèâíûå Èíòåðôåéñû
Ïîñëå òîãî, êàê îïèñàíû ñðåäñòâà ÿçûêà, êîòîðûå îòíîñÿñÿ ê ïðîèçâîäíûì êëàññàì, îáñóæäåíèå

7.3.1 Èíòåðôåéñ
Ðàññìîòðèì òàêîå íàïèñàíèå êëàññà slist äëÿ îäíîêðàòíî ñâÿçàííîãî ñïèñêà, ñ ïîìîùüþ êîòîðîã
typedef void* ent;
Òî÷íàÿ ñóùíîñòü òèïà ent íåñóùåñòâåííà, íî íóæíî, ÷òîáû â íåì ìîã õðàíèòüñÿ óêàçàòåëü. Òîãä
class slink (* friend class slist; friend class slist_iterator; slink* next; ent
e; slink(ent a, slink* p) (* e=a; next=p;*) *);
 îäíîì çâåíå ìîæåò õðàíèòüñÿ îäèí ent, è ñ ïîìîùüþ íåãî ðåàëèçóåòñÿ êëàññ slist:
class slist (* friend class slist_iterator; slink* last; // last-»next ãîëîâà ñïèñêà publ
t a); // äîáàâèòü â ãîëîâó ñïèñêà int append(ent a); // äîáàâèòü â õâîñò ñïèñêà ent get();
slist() (* last=0; *) slist(ent a) (* last=new slink(a,0); last-»next=last; *) ~sl
ist() (* clear(); *)
*);
Õîòÿ ñïèñîê î÷åâèäíûì îáðàçîì ðåàëèçóåòñÿ êàê ñâÿçàííûé ñïèñîê, ðåàëèçàöèþ ìîæíî èçìåíèòü ò

7.3.2 Ðåàëèçàöèÿ
Ðåàëèçóþùèå slist ôóíêöèè â îñíîâíîì ïðîñòû. Åäèíñòâåíàÿ íàñòîÿùàÿ ñëîæíîñòü ÷òî äåëàòü â
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); e
lse (* last = new slink(a,0); last-»next = last; *) return 0; *)
ent slist::get() (* if (last == 0) slist_handler(«get fromempty list»); // âçÿòü èç ïóñòîãî
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»);
È 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 íå îáåñïå÷èâàåò ñïîñîáà çàãëÿíóòü â ñïèñîê, íî òîëüêî ñðåäñòâà äëÿ âñòàâëåíèÿ è
class slist_iterator (* slink* ce; slist* cs; public: slist_iterator(slist amp;
s) (* cs = amp;s; ce = cs-»last; *)
ent operator()() (* // äëÿ èíäèêàöèè êîíöà èòåðàöèè âîçâðàùàåò 0 // äëÿ âñåõ òèïîâ íå èäåàë

7.3.3 Êàê Ýòèì Ïîëüçîâàòüñÿ


Ôàêòè÷åñêè êëàññ slist â íàïèñàííîì âèäå áåñïîëåçåí.  êîíå÷íîì ñ÷åòå, çà÷åì ìîæíî èñïîëüçî
struct name (* char* string; // ... *);
 ñïèñîê áóäóò ïîìåùàòüñÿ óêàçàòåëè íà èìåíà, à íå ñàìè îáúåêòû èìåíà. Ýòî ïîçâîëÿåò èñïîëü
#include «slist.h» #include «name.h»
struct nlist : slist (* void insert(name* a) (* slist::insert(a); *) void append
(name* a) (* slist::append(a); *) name* get() (**) nlist(name* a) : (a) (**) *);
Ôóíêöèè íîâîãî êëàññà èëè íàñëåäóþòñÿ îò slist íåïîðåäñòâåííî, èëè íè÷åãî íå äåëàþò êðîìå ï

Ñïèñêè èìåí ìîæíî èñïîëüçîâàòü â êëàññå, êîòîðûé ïðåäòàâëÿåò îïðåäåëåíèå êëàññà:


struct classdef (* nlist friends; nlist constructors; nlist destructors; nlist m
embers; nlist operators; nlist virtuals; // ... void add_name(name*); classdef()
; ~classdef(); *);
è èìåíà ìîãóò äîáàâëÿòüñÿ ê ýòèì ñïèñêàì ïðèáëèçèòåëüíî òàê:
void classdef::add_name(name* n) (* if (n-»is_friend()) (* if (find( amp;friends,n
)) error(«friend redeclared»); // friend ïåðåîïèñàí else if (find( amp;members,n)) error(«f
d as member»); // friend ïåðåîïèñàí êàê member else friends.append(n); *) if (n-»is_operato
nd(n); // ... *)
ãäå is_operator() è 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. Áîëåå õ
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 ;
or print(*(slist*)ll); while ( p=(name*)print() ) cout «« p- string «« «\n ; *)

7.3.4 Îáðàáîòêà Îøèáîê


Åñòü ÷åòûðå ïîäõîäà ê ïðîáëåìå, ÷òî æå äåëàòü, êîãäà âî âðåìÿ âûïîëíåíèÿ óíèâåðñàëüíîå ñðåä
1. Âîçâðàùàòü íåäîïóñòèìîå çíà÷åíèå è ïîçâîëèòü ïîëüçâàòåëþ åãî ïðîâåðÿòü
2. Âîçâðàùàòü äîïîëíèòåëüíîå çíà÷åíèå ñîñòîÿíèÿ è ðàðåøèòü ïîëüçîâàòåëþ ïðîâåðÿòü åãî
3. Âûçûâàòü ôóíêöèþ îøèáîê, çàäàííóþ êàê ÷àñòü êëàññà slist èëè
4. Âûçûâàòü ôóíêöèþ îøèáîê, êîòîðóþ ïðåäïîëîæèòåëüíî ïðåäîñòàâëÿåò ïîëüçîâàòåëü.
Äëÿ íåáîëüøîé ïðîãðàììû, íàïèñàííîé åå åäèíñòâåííûì ïîëüçîâàòåëåì, íåò ôàêòè÷åñêè íèêàêèõ î
Ïåðâûé ïîäõîä, âîçâðàùàòü íåäîïóñòèìîå çíà÷åíèå, íåîñùåñòâèì. Íåò ñîâåðøåííî íèêàêîãî ñïîñî
Âòîðîé ïîäõîä, âîçâðàùàòü çíà÷åíèå ñîñòîÿíèÿ, ìîæíî èïîëüçîâàòü â íåêîòîðûõ êëàññàõ (îäèí è
Òðåòüåìó ïîäõîäó, ïðåäîñòàâëÿòü ôóíêöèþ îøèáîê, íåäîñòåò ãèáêîñòè. Òîò, êòî ðåàëèçóåò óíèâå
×åòâåðòûé ïîäõîä, ïîçâîëèòü ïîëüçîâàòåëþ çàäàâàòü ôóíöèþ îøèáîê, èìååò íåêîòîðóþ ïðèâëåêàòå
Ðåøåíèÿ 3 è 4 ìîæíî ñäåëàòü áîëåå ãèáêèìè (è ïî ñóòè ýâèâàëåíòíûìè), çàäàâ óêàçàòåëü íà ôóí
typedef void (*PFC)(char*); // óêàçàòåëü íà òèï ôóíêöèÿ extern PFC slist_handler; extern PF
Ôóíêöèÿ set_slist_hanlder() ïîçâîëÿåò ïîëüçîâàòåëþ çàìíèòü ñòàíäàðòíóþ ôóíêöèþ. Îáùåïðèíÿòà
#include «slist.h» #include «stream.h»
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 = h
andler; return rr; *)
Îáðàòèòå âíèìàíèå, êàê set_slist_hanlder() âîçâðàùàåò ïðåäûäóùèé slist_hanlder(). Ýòî äåëàå
(* PFC old = set_slist_handler(my_handler);
// êîä, â êîòîðîì â ñëó÷àå îøèáîê â slist // áóäåò èñïîëüçîâàòüñÿ ìîé îáðàáîò÷èê my_handler
set_slist_handler(old); // âîññòàíîâëåíèå *)
×òîáû ñäåëàòü óïðàâëåíèå áîëåå èçÿùíûì, slist_hanlder ìîã áû áûòü ñäåëàí ÷ëåíîì êëàññà slis

7.3.5 Îáîáùåííûå Êëàññû


Î÷åâèäíî, ìîæíî áûëî áû îïðåäåëèòü ñïèñêè äðóãèõ òèïîâ (classdef*, int, char* è ò.ä.) òî÷íî
Âîò ïðèìåð òîãî, êàê îáîáùåííûé (generic) êëàññ slist, íàçâàííûé gslist, ìîæåò áûòü çàäàí ê
#include «slist.h»
#ifndef GENERICH #include «generic.h» #endif
Îáðàòèòå âíèìàíèå íà èñïîëüçîâàíèå #ifndef äëÿ òîãî, ÷òîáû ãàðàíòèðîâàòü, ÷òî «generic.h» â
Ïîñëå ýòîãî ñ ïîìîùüþ name2(), ìàêðîñà èç «generic.h» äëÿ êîíêàòåíàöèè èìåí, îïðåäåëÿþòñÿ è
êëàññîâ:
#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_itera
tor(type)(gslist(type) amp; a) \ : ( (slist amp;)s ) (**) \ type operator()() \
(* return type( slist_iterator::operator()() ); *)\ *)
\ íà êîíöå ñòðîê óêàçûâàåò , ÷òî ñëåäóþùàÿ ñòðîêà ÿâëåòñÿ ÷àñòüþ îïðåäåëÿåìîãî ìàêðîñà.
Ñ ïîìîùüþ ýòîãî ìàêðîñà ñïèñîê óêàçàòåëåé íà èìÿ, àíàëãè÷íûé èñïîëüçîâàííîìó ðàíüøå êëàññó
#include «name.h»
typedef name* Pname; declare(gslist,Pname); // îïèñûâàåò êëàññ gslist(Pname)
gslist(Pname) nl; // îïèñûâàåò îäèí gslist(Pname)
Ìàêðîñ declare (îïèñàòü) îïðåäåëåí â «generic.h». Îí êîíêàòèíèðóåò ñâîè ïàðàìåòðû è âûçûâàå
Èñïîëüçîâàíèå âûâîäà êëàññà ãàðàíòèðóåò, ÷òî âñå ÷àñòíûå ñëó÷àè îáîáùåííîãî êëàññà ðàçäåëÿþ

7.3.6 Îãðàíè÷åííûå Èíòåðôåéñû


Êëàññ slist äîâîëüíî îáùåãî õàðàêòåðà. Èíîãäà ïîäîáíàÿ îáùíîñòü íå òðåáóåòñÿ èëè äàæå íåæ
#include «slist.h»
class iqueue : slist (* //ïðåäïîëàãàåòñÿ sizeof(int)«=sizeof(void*)
public: void put(int a) (* slist::append((void*)a); *) int det() (* return int(s
list::get()); *) 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 Äîáàâëåíèå ê Êëàññó


 ïðåäûäóùèõ ïðèìåðàõ ïðîèçâîäíûé êëàññ íè÷åãî íå äîáàëÿë ê áàçîâîìó êëàññó. Äëÿ ïðîèçâîäíî
Äëÿ ïðîèçâîäíîãî êëàññà ìîæíî îïðåäåëèòü äàííûå è ôóíöèè äîïîëíèòåëüíî ê òåì, êîòîðûå íàñëå
struct olink (* olink* next;
*);
Êëàññ olist î÷åíü íàïîìèíàåò êëàññ slist. Îòëè÷èå ñîñòèò â òîì, ÷òî ïîëüçîâàòåëü êëàññà oli
class olist (* olink* last; public: void insert(olink* p); void append(olink* p)
; olink* get(); // ... *);
Ìû ìîæåì âûâåñòè èç êëàññà olink êëàññ name:
class name : public olink (* // ... *);
Òåïåðü ëåãêî ñäåëàòü ñïèñîê, êîòîðûé ìîæíî èñïîëüçîâàòü áåç íàêëàäíûõ ðàñõîäîâ âðåìåíè íà ð
Îáúåêòû, ïîìåùàåìûå â olist, òåðÿþò ñâîé òèï. Ýòî îçí÷àåò, ÷òî êîìïèëÿòîð çíàåò òîëüêî òî,
void f() (* olist ll; name nn; ll.insert( amp;nn); // òèï amp;nn ïîòåðÿí name* pn = (name*)
// è âîññòàíîâëåí *)
Äðóãîé ñïîñîá: òèï ìîæíî âîññòàíîâèòü, âûâîäÿ åùå îäèí êëàññ èç olist äëÿ îáðàáîòêè ïðåîáðà
class onlist : public olist (* // ... name* get() (* return (name*)olist::get();
*) *);
Èìÿ name ìîæåò îäíîâðåìåííî íàõîäèòüñÿ òîëüêî â îäíîì olist. Äëÿ èìåí ýòî, ìîæåò áûòü, è íå

7.5 Íåîäíîðîäíûå Ñïèñêè


Ïðåäûäóùèå ñïèñêè áûëè îäíîðîäíûìè. Òî åñòü, â ñïèñîê ïîìåùàëèñü òîëüêî îáúåêòû îäíîãî òèïà
îñíîâàííûì èëè îáúåêòíî-îðèåíòèðîâàííûì. Îí îïèðàåòñÿ íà òî, ÷òî äåéñòâèÿ íàä îáúåêòàìè íå

7.6 Çàêîí÷åííàÿ Ïðîãðàììà


Ðàçáåðåì ïðîöåññ íàïèñàíèÿ ïðîãðàììû äëÿ ðèñîâàíèÿ íà ýêðàíå ãåîìåòðè÷åñêèõ ôèãóð. Îíà åñòå
1. Àäìèíèñòðàòîð ýêðàíà: ïîäïðîãðàììû íèçêîãî óðîâíÿ è ñòðóêòóðû äàííûõ, îïðåäåëÿþùèå ýêðàí
2. Áèáëèîòåêà ôèãóð: íàáîð îïðåäåëåíèé îñíîâíûõ ôèãóð âðîäå ïðÿìîóãîëüíèêà è êðóãà è ñòàíäà
3. Ïðèêëàäíàÿ ïðîãðàììà: ìíîæåñòâî îïðåäåëåíèé, ñïåöèàëçèðîâàííûõ äëÿ äàííîãî ïðèëîæåíèÿ, è
Ýòè òðè ÷àñòè ñêîðåå âñåãî áóäóò ïèñàòü ðàçíûå ëþäè (â ðàçíûõ îðãàíèçàöèÿõ è â ðàçíîå âðåìÿ

7.6.1 Àäìèíèñòðàòîð Ýêðàíà


Âíà÷àëå áûëî íàìåðåíèå íàïèñàòü àäìèíèñòðàòîð ýêðàíà íà C (à íå íà Ñ++), ÷òîáû ïîä÷åðêíóòü
Ýêðàí ïðåäñòàâëÿåòñÿ êàê äâóìåðíûé ìàññèâ ñèìâîëîâ, ðàáîòó ñ êîòîðûì îñóùåñòâëÿþò ôóíêöèè p
// ôàéë 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(p
oint p) (* put_point(p.x,p.y); *)
overload put_line; extern void put_line(int, int, int, int); inline void put_lin
e(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_clea
r();
#include «stream.h»
Ïåðåä ïåðâûì èñïîëüçîâàíèåì ôóíêöèè put ýêðàí íàäî èíöèàëèçèðîâàòü ñ ïîìîùüþ screen_init(),
#include «screen.h» #include «stream.h»
enum color (* black='*', white=' ' *);
char screen[XMAX][YNAX];
void screen_init() (* for (int y=0; y«YMAX; y++) for (int x=0; x«XMAX; x++) screen[x
][y] = white; *)
Òî÷êè ïå÷àòàþòñÿ, òîëüêî åñëè îíè åñòü íà ýêðàíå:
inline int on_screen(int a, int b) (* return 0«=a amp; amp; a«XMAX amp; amp; 0«=b amp;
amp; b«YMAX; *)
void put_point(int a, int b) (* if (on_screen(a,b)) screen[a][b] = black; *)
Äëÿ ðèñîâàíèÿ ëèíèé èñïîëüçóåòñÿ ôóíêöèÿ put_line():
void put_line(int x0, int y0, int x1, int y1) /* Ñòðîèò ëèíèþ îò (x0,y0) äî (x1,y1). Ñòðîèò
+ a(y-y0)). Ñì. Newman and Sproull: ``Principles of Interactive Computer Graphics''
McGraw-Hill, New York, 1979, pp 33-44. */ (* register dx = 1; int a = x1 x0; if
(a « 0) dx = -1, a = -a; register dy = 1; int b = y1 y0;
if (b « 0) dy = -1, b = -b; int two_a = 2*a; int two_b = 2*b; int xcrit = -b + two
_a; register eps = 0; for (;;) (* put_point(x0,y0); if(x0==x1 amp; amp; y0==y1)
break; if(eps = xcrit) x0 += dx, eps += two_b; if(eps =a !! a«=b) y0 += dy, eps -= tw
o_a; *) *)
Ïðåäîñòàâëÿþòñÿ ôóíêöèè äëÿ î÷èñòêè ýêðàíà è åãî îáíîëåíèÿ:
void screen_clear() (* screen_init(); *) // î÷èñòêà
void screen_refresh() // îáíîâëåíèå (* for (int y=YMAX-1; 0«=y; y ) (* // ñâåðõó âíèç for (
]); cout.put('\n'); *) *)
Ôóíêöèÿ ostream::put() ïðèìåíÿåòñÿ äëÿ ïå÷àòè ñèìâîëîâ êàê ñèìâîëîâ; ostream::operator««()

7.6.2 Áèáëèîòåêà Ôèãóð


Íàì íóæíî îïðåäåëèòü îáùåå ïîíÿòèå ôèãóðû (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()
urn point(0,0);*)//ñåâåðî-âîñòîê virtual point seast() (*return point(0,0);*) // þãî-âîñòîê
virtual void draw() (**); // íàðèñîâàòü virtual void move(int, int) (**); // ïåðåìåñòèòü *)
Èäåÿ ñîñòîèò â òîì, ÷òî ðàñïîëîæåíèå ôèãóðû çàäàåòñÿ ñ ïîìîùüþ move(), è ôèãóðà ïîìåùàåòñÿ
ñäåëàíû òàê:
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 south() (* return point((w.x+e.x)/2,e.y«w.y?e.y:w.y); *)
void move(int a, int b) (* w.x += a; w.y += b; e.x += a; e.x += b; *) void draw(
) (* put_line(w,e); *)
line(point a, point b) (* w = a; e = b; *) line(point a, int l) (* w = point(a.x
+l-1,a.y); e = a; *) *);
Àíàëîãè÷íî îïðåäåëÿåòñÿ ïðÿìîóãîëüíèê rectangle:
class rectangle : public shape (* /* nw n ne ! ! ! ! w c e ! ! ! ! sw s se */ po
int sw,ne; public: point north() (* return point((sw.x+ne.x)/2,ne.y); *) point s
outh() (* return point((sw.x+ne.x)/2,sw.y); *) point neast() (* return ne; *) po
int swest() (* return sw; *) void move (int a, int b) (* sw.x+=a; sw.y+=b; ne.x+
=a; ne.y+=b; *) void draw(); rectangle(point, point); *);
Ïðÿìîóãîëüíèê ñòðîèòñÿ ïî äâóì òî÷êàì. Êîä óñëîæíÿåòñÿ èç-çà íåîáõîäèìîñòè âûÿñíÿòü îòíîñèò

rectangle::rectangle(point a, point b); (* if (a.x «= b.x) (* (* sw = a; ne = b; *


) else (* sw = point(a.x,b.y); ne = point(b.x,a.y); *) *) else (* if (a.y «= b.y)
(* sw = point(b.x,a.y); ne = point(a.x,b.y); *) else (* sw = b; ne = a; *) *) *)
×òîáû ïîñòðîèòü ïðÿìîóãîëüíèê, ñòðîÿòñÿ ÷åòûðå åãî ñòðîíû:
void rectangle::draw(); (* point nw(sw.x,ne.y); point se(ne.x,sw.y); put_line(nw
,ne); put_line(ne,se); put_line(se,sw); put_line(sw,nw); *)
Ïîìèìî îïðåäåëåíèé ôèãóð â áèáëèîòåêå ôèãóð ñîäåðæàòñÿ ôóíêöèè äëÿ ðàáîòû ñ íèìè. Íàïðèìåð:
void shape_refresh(); // ðèñóåò âñå ôèãóðû void stack(shape* p, shape* q); // ñòàâèò p íà â
×òîáû ñïðàâèòüñÿ ñ íàøèì íàèâíûì ýêðàíîì, íóæíà îáíîâëþùàÿ ôóíêöèÿ. Îíà ïðîñòî ðèñóåò âñå ô
void shape_refresh() (* screen_clear(); sl_iterator next(shape_list); shape* p;
while ( p=next() ) p-»draw(); screen_refresh(); *)
È âîò, íàêîíåö, íàñòîÿùàÿ ñåðâèñíàÿ ôóíêöèÿ (óòèëèòà). Îíà êëàäåò îäíó ôèãóðó íà âåðõ äðóãî
void stack(shape* q, shape* p) // ñòàâèò p íà âåðõ q (* point n = p-»north(); point s = q-»
x-s.x,n.y-s.y+1);
*)
Òåïåðü ïðåäñòàâèì ñåáå, ÷òî ýòà áèáëèîòåêà ñ÷èòàåòñÿ ñîáñòâåííîñòüþ íåêîé êîìïàíèè, êîòîðàÿ

7.6.3 Ïðèêëàäíàÿ Ïðîãðàììà


Ïðèêëàäíàÿ ïðîãðàììà ÷ðåçâû÷àéíî ïðîñòà. Îïðåäåëÿåòñÿ íîâàÿ ôèãóðà myshape (íà ïå÷àòè îíà í
#include «shape.h»
class myshape : public rectangle (* line* l_eye; // ëåâûé ãëàç line* r_eye; // ïðàâûé ãëàç
pe(point, point); void draw(); void move(int, int); *);
Ãëàçà è ðîò îòäåëüíûå è íåçàâèñèìûå îáúåêòû, êîòîðûå ñîçäàåò êîíñòðóêòîð myshape:
myshape::myshape(point a, point b) : (a,b) (* int ll = neast().x-swest().x+1; in
t 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(), è â ïðèíöèïå ìîãóò îá
void myshape::draw() (* rectangle::draw(); put_point(point( (swest().x+neast().x
)/2,(swest().y+neast().y)/2)); *)
myshape ïåðåäâèãàåòñÿ ïîñðåäñòâîì ïåðåìåùåíèÿ áàçîâîãî ïðÿìîóãîëüíèêà rectangle è âòîðè÷íûõ
void myshape::move() (* rectangle::move(); 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 li
ne(point(0,15),17); shape* p3 = new myshape(point(15,10),point(27,18)); shape_re
fresh(); p3-»move(-10,-10); stack(p2,p3); stack(p1,p2); shape_refresh(); return 0;
*)
Åùå ðàç îáðàòèòå âíèìàíèå, êàê ôóíêöèè âðîäå shape_refresh() è stack() ìàíèïóëèðóþò îáúåêòà
*********** * * * * * * * * * * * * * * * * * * *********** ***************** **
*********** * * * ** ** * * * * * * * * * ********* * * * *************

7.7 Ñâîáîäíàÿ Ïàìÿòü


Åñëè âû ïîëüçîâàëèñü êëàññîì slist, âû ìîãëè îáíàðóæèòü, ÷òî âàøà ïðîãðàììà òðàòèò íà çàìåò
Åñëè ïðîèçâîäíûé êëàññ îñóùåñòâëÿåò ïðèñâàèâàíèå óêàçòåëþ this, òî êîíñòðóêòîð åãî áàçîâîãî

#include «stream.h»
struct base (* base(); *);
struct derived : base (* derived(); *)
base::base() (* cout « \tbase 1: this= int(this) «« «\n ; if (this == 0) this = (base
t «« «\tbase 2: this= «« int(this) «« «\n ; *)
derived::derived() (* cout « \tderived 1: this= int(this) «« «\n ; this = (this == 0)
ed*)43 : this; cout «« «\tderived 2: this= «« int(this) «« «\n ; *)
main() (* cout « base b;\n ; base b; cout new base b;\n ; new base; cout «« «derived
d d; cout «« «new derived d;\n ; new derived; cout «« «at the end\n ;
*)
ïîðîæäàåò âûâîä
base b; base 1: this=2147478307 base 2: this=2147478307 new base; base 1: this=0
base 2: this=27 derived d; derived 1: this=2147478306 base 1: this=2147478306 b
ase 2: this=2147478306 derived 1: this=2147478306 new derived; derived 1: this=0
base 1: this=43 base 2: this=43 derived 1: this=43 at the end
Åñëè äåñòðóêòîð ïðîèçâîäíîãî êëàññà îñóùåñòâëÿåò ïðèñâèâàíèå óêàçàòåëþ this, òî áóäåò ïðèñâ
 * Ê ñîæàëåíèþ, îá ýòîì ïðèñâàèâàíèè ëåãêî çàáûòü. Íàïðìåð, â ïåðâîì èçäàíèè ýòîé êíèãè (à

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


È ñëåäîâàòåëüíî, äëÿ d êîíñòðóêòîð áàçîâîãî êëàññà base::base() íå âûçûâàëñÿ. Ïðîãðàììà áûë

7.8 Óïðàæíåíèÿ
1. (*1) Îïðåäåëèòå
class base (* public: virtual void iam() (* cout « «base\n ; *) *);
Âûâåäèòå èç base äâà êëàññà è äëÿ êàæäîãî îïðåäåëèòå iam () («ÿ åñòü»), êîòîðàÿ âûâîäèò èìÿ
2. (*2) Ðåàëèçóéòå ïðèìèòèâû ýêðàíà (#7.6.1) ïîäõîäÿùèì äëÿ âàøåé ñèñòåìû îáðàçîì.
3. (*2) Îïðåäåëèòå êëàññ triangle (òðåóãîëüíèê) è êëàññ circle (êðóã).
4. (*2) Îïðåäåëèòå ôóíêöèþ, êîòîðàÿ ðèñóåò ëèíèþ, ñîåäèíÿùóþ äâå ôèãóðû, îòûñêèâàÿ äâå áëèæ
5. (*2) Ìîäèôèöèðóéòå ïðèìåð ñ ôèãóðàìè òàê, ÷òîáû line áëà rectangle è íàîáîðîò.
6. (*2) Ïðèäóìàéòå è ðåàëèçóéòå äâàæäû ñâÿçàííûé ñïèñîê, êîòîðûé ìîæíî èñïîëüçîâàòü áåç èòå
7. (*2) Ïðèäóìàéòå è ðåàëèçóéòå äâàæäû ñâÿçàííûé ñïèñîê, êîòîðûì ìîæíî ïîëüçîâàòüñÿ òîëüêî
8. (*2) Ïîñòðîéòå îáîáùåííûé âàðèàíò äâàæäû ñâÿçàííîãî ñïèñêà.
9. (*4) Ñäåëàéòå ñïèñîê, â êîòîðîì âñòàâëÿþòñÿ è óäàëÿþòñÿ ñàìè îáúåêòû (à íå ïðîñòî óêàçàò
10. (*5) Ïðèäóìàéòå è ðåàëèçóéòå áèáëèîòåêó äëÿ íàïèñàíèÿ ìîäåëåé, óïðàâëÿåìûõ ïðåðûâàíèÿìè
Ãëàâà 8 Ïîòîêè
``bad input char: .Ppm(*=P!..*@Z9A*)5!!!!!"syui!!!"!Mp#V6P?p8`;!4lf amp;
    ñîîáùåíèå îá îøèáêå (ñîêðàùåííîå)

ßçûê Ñ++ íå îáåñïå÷èâàåò ñðåäñòâ äëÿ ââîäà/âûâîäà. Åìó ýòî è íå íóæíî. Òàêèå ñðåäñòâà ëåãêî

8.1 Ââåäåíèå
Ðàçðàáîòêà è ðåàëèçàöèÿ ñòàíäàðòíûõ ñðåäñòâ ââîäà/âûâîäà äëÿ ÿçûêà ïðîãðàììèðîâàíèÿ çàðåêîì
Ñ++ ðàçðàáîòàí òàê, ÷òîáû ó ïîëüçîâàòåëÿ áûëà âîçìîíîñòü îïðåäåëÿòü íîâûå òèïû ñòîëü æå ýôô
Ñðåäñòâà ââîäà/âûâîäà «stream.h» ñâÿçàíû èñêëþ÷èòåëüíî ñ îáðàáîòêîé ïðåîáðàçîâàíèÿ òèïèçèðî
Îáðàáîòêà è âñòðîåííûõ è îïðåäåëÿåìûõ ïîëüçîâàòåëåì òïîâ îäíîðîäíûì îáðàçîì è ñ ãàðàíòèåé ò
put(cerr,"x = «); // cerr ïîòîê âûâîäà îøèáîê put(cerr,x); put(cerr,»\n");
Òèï ïàðàìåòðà îïðåäåëÿåò òî, êàêàÿ èç ôóíêöèé put áóäåò âûçûâàòüñÿ äëÿ êàæäîãî ïàðàìåòðà. Ý
çàïèñü è ïîçâîëÿåò ïðîãðàììèñòó âûâîäèòü ðÿä îáúåêòîâ îäíèì îïåðàòîðîì. Íàïðèìåð:
cerr « "x = " «« x «« «\n ;
ãäå cerr ñòàíäàðòíûé ïîòîê âûâîäà îøèáîê. Ïîýòîìó, åëè x ÿâëÿåòñÿ int ñî çíà÷åíèåì 123, ò
x = 123
è ñèìâîë íîâîé ñòðîêè. Àíàëîãè÷íî, åñëè X ïðèíàäëåæèò îïðåäåëåííîìó ïîëüçîâàòåëåì òèïó comp
x = (1,2.4)
Ýòîò ìåòîä ìîæíî ïðèìåíÿòü âñåãäà, êîãäà äëÿ x îïðåäåëíà îïåðàöèÿ ««, è ïîëüçîâàòåëü ìîæåò

8.2 Âûâîä
 ýòîì ðàçäåëå ñíà÷àëà îáñóæäàþòñÿ ñðåäñòâà ôîðìàòíîãî è áåñôîðìàòíîãî âûâîäà âñòðîåííûõ òè

8.2.1 Âûâîä Âñòðîåííûõ Òèïîâ


Êëàññ ostream îïðåäåëÿåòñÿ âìåñòå ñ îïåðàöèåé « («ïìåñòèòü â ) äëÿ îáðàáîòêè âûâîäà âñòðîå
class ostream (* // ... public: ostream amp; operator««(char*); ostream amp; operato
r««(int i) (* return *this««long(i); *) ostream amp; operator««(long); ostream amp; operato
ouble);
ostream amp; put(char); *);
Ôóíêöèÿ operator«« âîçâðàùàåò ññûëêó íà ostream, äëÿ êòîðîãî îíà áûëà âûçâàíà, ÷òîáû ê íåé
cerr «« "x = " «« x;
ãäå x ÿâëÿåòñÿ int, áóäåò èíòåðïðåòèðîâàòüñÿ êàê:
(cerr.operator««("x = ")).operator««(x);
 ÷àñòíîñòè, îòñþäà ñëåäóåò, ÷òî êîãäà îäèí îïåðàòîð ââîäà ïå÷àòàåò íåñêîëüêî ýëåìåíòîâ, îí

8.2.2 Âûâîä Îïðåäåëÿåìûõ Ïîëüçîâàòåëåì Òèïîâ


Ðàññìîòðèì îïðåäåëÿåìûé ïîëüçîâàòåëåì òèï:
class complex (* double re, im; public: complex(double r = 0, double i = 0) (* r
e=r; im=i; *)
friend double real(complex amp; a) (* returna.re; *) friend double real(complex
amp; a) (* returna.re; *)
friend complex operator+(complex, complex); friend complex operator-(complex, co
mplex); friend complex operator*(complex, complex); friend complex operator/(com
plex, complex); // ... *);
Îïåðàöèþ «« äëÿ íîâîãî òèïà complex ìîæíî îïðåäåëèòü òàê:
ostream amp; operator««(ostream amp;s, complex z) (* return s «« "(" «« real(z) «« "," «« i
; *)
è èñïîëüçîâàòü òî÷íî òàê æå, êàê äëÿ âñòðîåííîãî òèïà:
complex x(1,2); // ... cout « "x = " «« x «« «\n ;
ïîëó÷àÿ ïðè ýòîì
x = (1,2)
Îïðåäåëåíèå äåéñòâèÿ âûâîäà äëÿ îïðåäåëÿåìîãî ïîëüçîâòåëåì òèïà íå òðåáóåò íè ìîäèôèêàöèè î

8.2.3 Íåêîòîðûå Ïîäðîáíîñòè Ðàçðàáîòêè


Îïåðàöèÿ âûâîäà èñïîëüçóåòñÿ, ÷òîáû èçáåæàòü òîé ìíîãîëîâíîñòè, êîòîðóþ äàëî áû èñïîëüçîâàí
Âîçìîæíîñòè èçîáðåñòè íîâûé ëåêñè÷åñêèé ñèìâîë íåò (#6.2). Îïåðàöèÿ ïðèñâàèâàíèÿ áûëà êàíäè
Äåëàëèñü ïîïûòêè èñïîëüçîâàòü îïåðàöèè « è », íî çíà÷íèÿ «ìåíüøå» è «áîëüøå» íàñòîëüêî ïðî÷
cout « x , y , z;

Äëÿ òàêèõ îïåðàòîðîâ íåïðîñòî âûäàâàòü õîðîøèå ñîîáùåíèÿ îá îøèáêàõ.


Îïåðàöèè « è » ê òàêîãî ðîäà ïðîáëåìàì íå ïðèâîäÿò, îíè àñèììåòðè÷íû â òîì ñìûñëå, ÷òî èõ
cout « a*b+c= «« a*b+c «« «\n ;
Åñòåñòâåííî, ïðè íàïèñàíèè âûðàæåíèé, êîòîðûå ñîäåðæàò îïåðàöèè ñ áîëåå íèçêèìè ïðèîðèòåòàì
cout « a^b!c= «« (a^b!c) «« «\n ;
Îïåðàöèþ ëåâîãî ñäâèãà òîæå ìîæíî ïðèìåíÿòü â îïåðàòîðå âûâîäà:
cout « a««b= «« (a««b) «« «\n ;
 Ñ++ íåò âûðàæåíèé ñ ñèìâîëüíûìè çíà÷åíèÿìè, â ÷àñòíîòè, '\n' ÿâëÿåòñÿ öåëûì (ñî çíà÷åíèåì
cout «« "x = " «« x «« '\n';
íàïå÷àòàåò ÷èñëî 10, à íå îæèäàåìûé ñèìâîë íîâîé ñòðîêè. Ýòó è àíàëîãè÷íûå ïðîáëåìû ìîæíî ñ
#define sp « " " #define ht « «\t #define nl «« «\n
Òåïåðü ïðåäûäóùèé ïðèìåð çàïèøåòñÿ â âèäå:
cout «« "x = " «« x nl;
Äëÿ ïå÷àòè ñèìâîëîâ ïðåäîñòàâëÿþòñÿ ôóíêöèè ostream::put (char) è chr(int) (ñì. #8.2.4). Õî
Ðàññìîòðèì ïðèìåðû:
cout « x « " " «« y «« " " «« z «« «\n ; cout «« "x = " «« x «« ", y = " «« y «« «\n ;
Ëþäè íàõîäÿò èõ òðóäíî ÷èòàåìûìè èç-çà áîëüøîãî ÷èñëà êàâû÷åê è òîãî, ÷òî îïåðàöèÿ âûâîäà â
cout «« x sp «« y sp «« z nl; cout «« "x = " «« x «« ", y = " «« y nl;

8.2.4 Ôîðìàòèðîâàííûé Âûâîä


Ïîêà «« ïðèìåíÿëàñü òîëüêî äëÿ íåôîðìàòèðîâàííîãî âûâäà, è íà ñàìîì äåëå â ðåàëüíûõ ïðîãðàì
char* oct(long, int=0); // âîñüìåðè÷íîå ïðåäñòàâëåíèå char* dec(long, 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««form() ýêâèâàëåíòíî ïðèìåíåíèþ ñòàíäàðòíîé ôóíêöèè âûâîäà ÿçûêà C printf()*. form() â
 * Îáúÿñíåíèå òîãî, êàê ïðèìåíÿþòñÿ ñòðîêè ôîðìàòà,  ýòî ñëåãêà îòðåäàêòèðîâàííûé âàðèàíò
cout« form(«there were %d members present ,no_of_members);
Çäåñü %d óêàçûâàåò, ÷òî no_of_members äîëæíî ðàññìàòðâàòüñÿ êàê int è ïå÷àòàòüñÿ â âèäå ñîî
there were 127 members present
Ìíîæåñòâî ñïåöèôèêàöèé ïðåîáðàçîâàíèÿ äîâîëüíî âåëèêî è îáåñïå÷èâàåò âûñîêóþ ñòåïåíü ãèáêîñ
 íåîáÿçàòåëüíûé çíàê ìèíóñ, êîòîðûé çàäàåò âûðàâíèâàíèå ïðåîáðàçîâàííîãî çíà÷åíèÿ âëåâî â
d íåîáÿçàòåëüíàÿ ñòðîêà öèôð, çàäàþùàÿ øèðèíó ïîëÿ. Åñëè ïðåîáðàçîâàííîå çíà÷åíèå èìååò ìåí
. íåîáÿçàòåëüíàÿ òî÷êà, äëÿ îòäåëåíèÿ øèðèíû ïîëÿ îò
ñëåäóþùåé ñòðîêè öèôð;
d íåîáÿçàòåëüíàÿ ñòðîêà öèôð, ñïåöèôèöèðóþùàÿ òî÷íîñòü, êîòîðàÿ çàäàåò ÷èñëî öèôð ïîñëå äåñ
* â øèðèíå ïîëÿ èëè òî÷íîñòè âìåñòî ñòðîêè öèôð ìîæåò ñòÿòü *.  ýòîì ñëó÷àå øèðèíà ïîëÿ è
h íåîáÿçàòåëüíûé ñèìâîë h; óêàçûâàåò íà òî, ÷òî èäóùèå çà íèì d, o, x èëè y ñîîòâåòñòâóþò ï
l íåîáÿçàòåëüíûé ñèìâîë h; óêàçûâàåò íà òî, ÷òî èäóùèå çà íèì d, o, x èëè y ñîîòâåòñòâóþò ï
% óêàçûâàåò, ÷òî äîëæåí áûòü íàïå÷àòàí ñèìâîë %, íèêàêèå ïàðàìåòðû ïðè ýòîì íå çàòðàãèâàþòñ
c ñèìâîë, óêàçûâàþùèé, êàêîé òèï ïðåîáðàçîâàíèÿ äîëæåí ïðèìåíÿòüñÿ. Ñèìâîëû ïðåîáðàçîâàíèÿ
d öåëûé ïàðàìåòð ïðåîáðàçóåòñÿ â äåñÿòè÷íóþ çàïèñü;
o öåëûé ïàðàìåòð ïðåîáðàçóåòñÿ â âîñüìåðè÷íóþ çàïèñü;
x öåëûé ïàðàìåòð ïðåîáðàçóåòñÿ â øåñòíàäöàòèðè÷íóþ çàïèñü;
f ïàðàìåòð float èëè double ïðåîáðàçóåòñÿ â äåñÿòè÷íóþ çàïèñü âèäà [-]ddd.ddd, ãäå ÷èñëî, ç
e ïàðàìåòð float èëè double ïðåîáðàçóåòñÿ â äåñÿòè÷íóþ çàïèñü âèäà [-]d.ddde+dd, ãäå ïåðåä
g ïàðàìåòð float èëè double ïå÷àòàåòñÿ â òîì èç âèäîâ d, f èëè e, êîòîðûé îáåñïå÷èâàåò ïîëí
c ïå÷àòàåòñÿ ñèìâîëüíûé ïàðàìåòð, ïóñòûå ñèìâîëû èãíîððóþòñÿ;
s ïàðàìåòð âîñïðèíèìàåòñÿ êàê ñòðîêà (óêàçàòåëü íà ñèâîë), è ïå÷àòàþòñÿ ñèìâîëû èç ñòðîêè ä
u áåççíàêîâûé öåëûé ïàðàìåòð ïðåîáðàçóåòñÿ â äåñÿòè÷íóþ çàïèñü.
Íåñóùåñòâóþùàÿ èëè íåäîñòàòî÷íàÿ øèðèíà ïîëÿ íèêîãäà íå ïðèâîäèò ê îáðåçàíèþ ïîëÿ; äîïîëíåí
Âîò áîëåå ñëîæíûé ïðèìåð:
char* src_file_name;
int line; char* line_format = «\n#line %d \»%s\"\n"; //... cout « int a;\n ; cout «« form
_format,line,src_file_name); cout «« «int b;\n ;
êîòîðûé ïå÷àòàåò
int a;
#line 13 «Ñ++/main.c» int b;
Ïðèìåíåíèå form() íåáåçîïàñíî â ñìûñëå òîãî, ÷òî íå âïîëíÿåòñÿ ïðîâåðêà òèïà. Âîò, íàïðèìåð
char x; // ... cout« form(«bad input char: %s ,x);
Ïðàâäà, îíà äàåò áîëüøóþ ãèáêîñòü â òîì âèäå, êîòîðûé õîðîøî çíàêîì ïðîãðàììèñòàì íà C. Ïîò
 íàñòîÿùåå âðåìÿ íåò ïîëíîñòüþ óäîâëåòâîðèòåëüíûõ ñðåäñòâ, îáåñïå÷èâàþùèõ ôîðìàòèðîâàííûé
class complex (* float re,im; public: // ... char* string(char* format) (* retur
n form(format,re,im); *) *); // ... cout « z.string(«(%.3f,%.3f) );
Ïàìÿòü äëÿ õðàíåíèÿ ñòðîê, êîòîðûå âîçâðàùàþò form(), hex() è ò.ï., áåðåòñÿ èç îäíîãî ñòàòè

8.2.5 Âèðòóàëüíàÿ Ôóíêöèÿ Âûâîäà


Èíîãäà ôóíêöèÿ âûâîäà äîëæíà áûòü virtual. Ðàññìîòðèì ïðèìåð êëàññà shape, êîòîðûé äàåò ïîí
class shape (* // ... public: // ... virtual void draw(ostream amp; s); // ðèñóåò «this» íà

class circle : public shape (* int radius; public: // ... void draw(ostream amp;
); *);
Òî åñòü, êðóã èìååò âñå ïðèçíàêè ôèãóðû è ìîæåò îáðàáòûâàòüñÿ êàê ôèãóðà, íî èìååò òàêæå è
×òîáû ïîääåðæèâàòü äëÿ òàêèõ êëàññîâ ñòàíäàðòíóþ ïàðäèãìó âûâîäà, îïåðàöèÿ «« îïðåäåëÿåòñÿ
ostream amp; operator« (ostream amp; s, shape* p) (* p- draw(s); return s; *)
Åñëè next èòåðàòîð òèïà îïðåäåëåííîãî â #7.3.3, òî ñïèñîê ôèãóð ðàñïå÷àòûâàåòñÿ íàïðèìåð
while ( p = next() ) cout «« p;

8.3 Ôàéëû è Ïîòîêè


Ïîòîêè îáû÷íî ñâÿçàíû ñ ôàéëàìè. Áèáëèîòåêà ïîòîêîâ ñîäàåò ñòàíäàðòíûé ïîòîê ââîäà cin, ñòà

8.3.1 Èíèöèàëèçàöèÿ Ïîòîêîâ Âûâîäà


ostream èìååò êîíñòðóêòîðû:
class ostream (* // ... ostream(streambuf* s); // ñâÿçûâàåò ñ áóôåðîì ïîòîêà ostream(int fd
Ãëàâíàÿ ðàáîòà ýòèõ êîíñòðóêòîðîâ ñâÿçûâàòü ñ ïîòîêîì áóôåð. streambuf êëàññ, óïðàâëÿþù
Îïèñàíèå ñòàíäàðòíûõ ïîòîêîâ âûâîäà cout è cerr, êîòîðîå íàõîäèòñÿ â èñõîäíûõ êîäàõ áèáëèîò
// îïèñàòü ïîäõîäÿùåå ïðîñòðàíñòâî áóôåðà char cout_buf[BUFSIZE]
// ñäåëàòü «filebuf» äëÿ óïðàâëåíèÿ ýòèì ïðîñòðàíñòâîì //ñâÿçàòü åãî ñ UNIX'îâñêèì ïîòîêîì
// ñäåëàòü ostream, îáåñïå÷èâàÿ ïîëüçîâàòåëüñêèé èíòåðôåéñ ostream cout( amp;cout_file);
char cerr_buf[1];
// äëèíà 0, òî åñòü, íåáóôåðèçîâàííûé
// UNIX'îâñêèé ïîòîê âûâîäà 2 (óæå îòêðûòûé) filebuf cerr_file(2,cerr_buf,0);
ostream cerr( amp;cerr_file);
Ïðèìåðû äâóõ äðóãèõ êîíñòðóêòîðîâ ostream ìîæíî íàéòè â #8.3.3 è #8.5.

8.3.2 Çàêðûòèå Ïîòîêîâ Âûâîäà


Äåñòðóêòîð äëÿ ostream ñáðàñûâàåò áóôåð ñ ïîìîùüþ îòêðòîãî ÷ëåíà ôóíêöèè ostream::flush():
ostream::~ostream() (* flush(); // ñáðîñ *)
Ñáðîñèòü áóôåð ìîæíî òàêæå è ÿâíî. Íàïðèìåð:
cout.flush();

8.3.3 Îòêðûòèå Ôàéëîâ


Òî÷íûå äåòàëè òîãî, êàê îòêðûâàþòñÿ è çàêðûâàþòñÿ ôàéëû, ðàçëè÷àþòñÿ â ðàçíûõ îïåðàöèîííûõ
#include «stream.h»
void error(char* s, char* s2) (* cerr « s «« " " «« s2 «« «\n ; exit(1); *)
main(int argc, char* argv[]) (* if (argc != 3) error(«íåâåðíîå ÷èñëî ïàðàìåòðîâ»,"");
filebuf f1; if (f1.open(argv[1],input) == 0) error(«íå ìîãó îòêðûòü âõîäíîé ôàéë»,argv[1]);
filebuf f2; if (f2.open(argv[2],output) == 0) error(«íå ìîãó ñîçäàòü âûõîäíîé ôàéë»,argv[2]
char ch; while (from.get(ch)) to.put(ch);
if (!from.eof() !! to.bad()) error(«ñëó÷èëîñü íå÷òî ñòðàííîå»,""); *)
Ïîñëåäîâàòåëüíîñòü äåéñòâèé ïðè ñîçäàíèè ostream äëÿ èìåíîâàííîãî ôàéëà òà æå, ÷òî èñïîëüçó
ostream ñ filebuf â êà÷åñòâå ïàðàìåòðà. Ïîòîêè ââîäà îáðàáòûâàþòñÿ àíàëîãè÷íî.
Ôàéë ìîæåò îòêðûâàòüñÿ â îäíîé èç äâóõ ìîä:
enum open_mode (* input, output *);
Äåéñòâèå filebuf::open() âîçâðàùàåò 0, åñëè íå ìîæåò îêðûòü ôàéë â ñîîòâåòñòâèå ñ òðåáîâàíè
Ïåðåä çàâåðøåíèåì ïðîãðàììà ïðîâåðÿåò, íàõîäÿòñÿ ëè ïòîêè â ïðèåìëåìîì ñîñòîÿíèè (ñì. #8.4.
Ôàéë ìîæíî òàêæå îòêðûòü îäíîâðåìåííî äëÿ ÷òåíèÿ è çàïñè, íî â òåõ ñëó÷àÿõ, êîãäà ýòî îêàçû

8.3.4 Êîïèðîâàíèå Ïîòîêîâ


Åñòü âîçìîæíîñòü êîïèðîâàòü ïîòîêè. Íàïðèìåð:
cout = cerr;
 ðåçóëüòàòå ýòîãî ïîëó÷àþòñÿ äâå ïåðåìåííûå, ññûëàþùèñÿ íà îäèí è òîò æå ïîòîê. Ãàâíûì îáð
8.4 Ââîä
Ââîä àíàëîãè÷åí âûâîäó. Èìååòñÿ êëàññ istream, êîòîðûé ïðåäîñòàâëÿåò îïåðàöèþ »» («âçÿòü èç

8.4.1 Ââîä Âñòðîåííûõ Òèïîâ


Êëàññ istream îïðåäåëÿåòñÿ òàê:
class istream (* // ... public: istream amp; operator»»(char*); // ñòðîêà istream amp; oper
ar amp;); // ñèìâîë istream amp; operator»»(short amp;); istream amp; operator»»(int amp;);
amp; operator»»(long amp;); istream amp; operator»»(float amp;); istream amp; operator»»(do
ble amp;); // ... *);
Ôóíêöèè ââîäà îïðåäåëÿþòñÿ â òàêîì äóõå:
istream amp; istream::operator»»(char amp; c); (* // ïðîïóñêàåò ïðîïóñêè int a; // íåêèì îá

Ïðîïóñê îïðåäåëÿåòñÿ êàê ñòàíäàðòí÷é ïðîïóñê â C, ÷åðåç âûçîâ isspase() â òîì âèäå, êàê îíà
 êà÷åñòâå àëüòåðíàòèâû ìîæíî èñïîëüçîâàòü ôóíêöèè get():
class istream (* // ... istream amp; get(char amp; c); // char istream amp; get(
char* p, int n, int ='\n'); // ñòðîêà *);
Îíè îáðàáàòûâàþò ñèìâîëû ïðîïóñêà òàê æå, êàê îñòàëüíûå ñèìâîëû. Ôóíêöèÿ istream::get(char)
cin.get(buf,256,'\t');
áóäåò ÷èòàòü â buf íå áîëåå 256 ñèìâîëîâ, à åñëè âñòðòèòñÿ òàáóëÿöèÿ ('\t'), òî ýòî ïðèâåäå
Ñòàíäàðòíûé çàãîëîâî÷íûé ôàéë «ctype.h» îïðåäåëÿåò íåêîëüêî ôóíêöèé, êîòîðûå ìîãóò îêàçàòüñ
int isalpha(char) // 'a'..'z' 'A'..'Z' int isupper(char) // 'A'..'Z' int islower
(char) // 'a'..'z' int isdigit(char) // '0'..'9' int isxdigit(char) // '0'..'9'
'a'..'f' 'A'..'F' int isspase(char) // ' ' '\t' âîçâðàò íîâàÿ ñòðîêà // ïåðåâîä ôîðìàòà int
it() int isprint(char) // ïå÷àòàåìûé: ascii ' '..'-' int isgraph(char) // isalpha() ! isdig
punct() int isascii(char c) (* return 0«=c amp; amp; c«=127; *)
Âñå êðîìå isascii() ðåàëèçóþòñÿ âíåøíå îäèíàêîâî, ñ ïðìåíåíèåì ñèìâîëà â êà÷åñòâå èíäåêñà â
(('a'«=c amp; amp; c«='z') !! ('A'«=c amp; amp; c«='Z')) // àëôàâèòíûé
íå òîëüêî óòîìèòåëüíî ïèøóòñÿ è ÷ðåâàòû îøèáêàìè (íà ìøèíå ñ íàáîðîì ñèìâîëîâ EBCDIC îíî áó
isalpha(c)

8.4.2 Ñîñòîÿíèÿ Ïîòîêà


Êàæäûé ïîòîê (istream èëè ostream) èìååò àññîöèèðîâàííîå ñ íèì ñîñòîÿíèå, è îáðàáîòêà îøèáî
Ïîòîê ìîæåò íàõîäèòüñÿ â îäíîì èç ñëåäóþùèõ ñîñòîÿíèé:
enum stream_state (* _good, _eof, _fail, _bad *);
Åñëè ñîñòîÿíèå _good èëè _eof, çíà÷èò ïîñëåäíÿÿ îïåðàöèÿ ââîäà ïðîøëà óñïåøíî. Åñëè ñîñòîÿí
Ñîñòîÿíèå ïîòîêà ìîæíî ïðîâåðÿòü íàïðèìåð òàê:
switch (cin.rdstate()) (* case _good: // ïîñëåäíÿÿ îïåðàöèÿ íàä cin ïðîøëà óñïåøíî break; c
Äëÿ ëþáîé ïåðåìåííîé z òèïà, äëÿ êîòîðîãî îïðåäåëåíû îïåðàöèè « è », êîïèðóþùèé öèêë ìîæí
while (cin»»z) cout « z «« «\n ;
Íàïðèìåð, åñëè z âåêòîð ñèìâîëîâ, ýòîò öèêë áóäåò áðàòü ñòàíäàðòíûé ââîä è ïîìåùàòü åãî â
Êîãäà â êà÷åñòâå óñëîâèÿ èñïîëüçóåòñÿ ïîòîê, ïðîèñõîäèò ïðîâåðêà ñîñòîÿíèÿ ïîòîêà, è ýòà ïð
Äåëàòü ïðîâåðêó íà íàëè÷èå îøèáîê ïîñëå êàæäîãî ââîäà èëè âûâîäà äåéñòâèòåëüíî íå î÷åíü óäî

8.4.3 Ââîä Òèïîâ, Îïðåäåëÿåìûõ Ïîëüçîâàòåëåì


Ââîä äëÿ ïîëüçîâàòåëüñêîãî òèïà ìîæåò îïðåäåëÿòüñÿ òî÷íî òàê æå, êàê âûâîä, çà òåì èñêëþ÷åí
istream amp; operator»»(istream amp; s, complex amp; a) /* ôîðìàòû ââîäà äëÿ complex; "f" î
uble re = 0, im = 0; char c = 0;
s »» c; if (c == '(') (* s »» re »» c; if (c == ',') s »» im »» c; if (c != ')') s.clear(_b
lse (* s.putback(c); s »» re; *)
if (s) a = complex(re,im); return s; *)
Íåñìîòðÿ íà òî, ÷òî íå õâàòàåò êîäà îáðàáîòêè îøèáîê, áîëüøóþ ÷àñòü âèäîâ îøèáîê ýòî íà ñàì
Îïåðàöèÿ óñòàíîâêè ñîñòîÿíèÿ íàçâàíà 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 (íåîáÿçàòåëüíûé) çàäàå
cout.flush(); // ïèøåò áóôåð âûâîäà
Ñ ïîìîùüþ ôóíêöèè istream::tie() ìîæíî ïðèêðåïèòü (èëè îòêðåïèòü, ñ ïîìîùüþ tie(0)) ëþáîé o
int y_or_n(ostream amp; to, istream amp; from) /* «to», ïîëó÷àåò îòêëèê èç «from» */ (* ost
; for (;;) (* cout «« "íàáåðèòå Y èëè N: "; char ch = 0; if (!cin.get(ch)) return 0;
if (ch != '\n') (* // ïðîïóñêàåò îñòàòîê ñòðîêè char ch2 = 0; while (cin.get(ch2) amp; amp;
ase 'Y': case 'y': case '\n': from.tie(old); // âîññòàíàâëèâàåò ñòàðûé tie return 1; case '
âîññòàíàâëèâàåò ñòàðûé tie return 0; default: cout «« "èçâèíèòå, ïîïðîáóéòå åùå ðàç: "; *)
Êîãäà èñïîëüçóåòñÿ áóôåðèçîâàííûé ââîä (êàê ýòî ïðîèñõäèò ïî óìîë÷àíèþ), ïîëüçîâàòåëü íå ìî
Ñèìâîë ìîæíî âåðíóòü â ïîòîê ñ ïîìîùüþ ôóíêöèè istream:: putback(char). Ýòî ïîçâîëÿåò ïðîãð

8.5 Ðàáîòà ñî Ñòðîêàìè


Ìîæíî îñóùåñòâëÿòü äåéñòâèÿ, ïîäîáíûå ââîäó/âûâîäó, íàä ñèìâîëüíûì âåêòîðîì, ïðèêðåïëÿÿ ê í

void word_per_line(char v[], int sz) /* ïå÷àòåò "v" ðàçìåðà «sz» ïî îäíîìó ñëîâó íà ñòðîêå
Çàâåðøàþùèé íóëåâîé ñèìâîë â ýòîì ñëó÷àå èíòåðïðåòèðóåñÿ êàê ñèìâîë êîíöà ôàéëà.
 ïîìîùüþ ostream ìîæíî îòôîðìàòèðîâàòü ñîîáùåíèÿ, êîòðûå íå íóæíî ïå÷àòàòü òîò÷àñ æå:
char* p = new char[message_size]; ostream ost(message_size,p); do_something(argu
ments,ost); display(p);
Òàêàÿ îïåðàöèÿ, êàê do_something, ìîæåò ïèñàòü â ïîòîê ost, ïåðåäàâàòü ost ñâîèì ïîäîïåðàöè

8.6 Áóôåðèçàöèÿ
Ïðè çàäàíèè îïåðàöèé ââîäà/âûâîäà ìû íèêàê íå êàñàëèñü òèïîâ ôàéëîâ, íî âåäü íå âñå óñòðîéñ
struct streambuf (* // óïðàâëåíèå áóôåðîì ïîòîêà
char* base; // íà÷àëî áóôåðà char* pptr; // ñëåäóþùèé ñâîáîäíûé char char* qptr; // ñëåäóþù
// Îïóñòîøàåò áóôåð: // Âîçâðàùàåò EOF ïðè îøèáêå è 0 â ñëó÷àå óñïåõà virtual int overflow(
// Çàïîëíÿåò áóôåð
// Âîçâðàùåò EOF ïðè îøèáêå èëè êîíöå ââîäà, // èíà÷å ñëåäóþùèé char virtual int underflow(
int snextc() // áåðåò ñëåäóþùèé char (* return (++qptr==pptr) ? underflow() : *qptr amp;037
// ...
int allocate() //âûäåëÿåò íåêîòîðîå ïðîñòðàíñòâî áóôåðà
streambuf() (* /* ... */*) streambuf(char* p, int l) (* /* ... */*) ~streambuf()
(* /* ... */*) *);
Îáðàòèòå âíèìàíèå, ÷òî çäåñü îïðåäåëÿþòñÿ óêàçàòåëè, íîáõîäèìûå äëÿ ðàáîòû ñ áóôåðîì, ïîýòî
struct filebuf : public streambuf (*
int fd; // äåñêðèïòîð ôàéëà char opened; // ôàéë îòêðûò
int overflow(int c =EOF); int underflow();
// ...
// Îòêðûâàåò ôàéë: // åñëè íå ñðàáàòûâàåò, òî âîçâðàùåò 0, // â ñëó÷àå óñïåõà âîçâðàùàåò «t
filebuf() (* opened = 0; *) filebuf(int nfd) (* /* ... */ *) filebuf(int nfd, ch
ar* p, int l) : (p,l) (* /*...*/ *) ~filebuf() (* close(); *) *);
int filebuf::underflow() // çàïîëíÿåò áóôåð èç fd (* if (!opened !! allocate()==EOF) return
int count = read(fd, base, eptr-base); if (count « 1) return EOF;
qptr = base; pptr = base + count; return *qptr amp; 0377; *)

8.7 Ýôôåêòèâíîñòü
Ìîæíî áûëî áû îæèäàòü, ÷òî ðàç ââîä/âûâîä «stream.h» îïðåäåëåí ñ ïîìîùüþ îáùåäîñòóïíûõ ñðåä
Äëÿ ïðîñòûõ îáúåêòîâ (öåëîå, ñòðîêà è ò.ï.) òðåáóåòñÿ ïî îíîìó âûçîâó íà êàæäûé. Êàê âûÿñíÿ

8.8 Óïðàæíåíèÿ
1. (*1.5) Ñ÷èòàéòå ôàéë ÷èñåë ñ ïëàâàþùåé òî÷êîé, ñîñòàâüòå èç ïàð ñ÷èòàííûõ ÷èñåë êîìïëåêñ
2. (*1.5) Îïðåäåëèòå òèï name_and_address (èìÿ_è_àäðåñ). Îïðåäåëèòå äëÿ íåãî « è ». Ñêîïè
3. (*2) Ïîñòðîéòå íåñêîëüêî ôóíêöèé äëÿ çàïðîñà è ÷òåíèÿ ðàçëè÷íîãî âèäà èíôîðìàöèè. Ïðîñòå
4. (*1.5) Íàïèøèòå ïðîãðàììó, êîòîðàÿ ïå÷àòàåò (1) âñå áóâû â íèæíåì ðåãèñòðå, (2) âñå áóêâ
5. (*4) Ðåàëèçóéòå ñòàíäàðòíóþ áèáëèîòåêó ââîäà/âûâîäà C («stdio.h») ñ ïîìîùüþ ñòàíäàðòíîé
6. (*4) Ðåàëèçóéòå ñòàíäàðòíóþ áèáëèîòåêó ââîäà/âûâîäà Ñ++ («stream.h») ñ ïîìîùüþ ñòàíäàðòí
7. (*4) Ðåàëèçóéòå ñòàíäàðòíûå áèáëèîòåêè C è Ñ++ òàê, ÷òáû îíè ìîãëè èñïîëüçîâàòüñÿ îäíîâð
8. (*2) Ðåàëèçóéòå êëàññ, äëÿ êîòîðîãî [] ïåðåãðóæåíî äëÿ ðåàëèçàöèè ñëó÷àéíîãî ÷òåíèÿ ñèìâ
9. (*3) Êàê Óïðàæíåíèå 8, òîëüêî ñäåëàéòå, ÷òîáû [] ðàáîòëî è äëÿ ÷òåíèÿ, è äëÿ çàïèñè. Ïîä
10. (*2) Êàê Óïðàæíåíèå 9, òîëüêî ðàçðåøèòå [] èíäåêñèðîâàòü çàïèñè íåêîòîðîãî âèäà, à íå ñ
11. (*3) Ñäåëàéòå îáîáùåííûé âàðèàíò êëàññà, îïðåäåëåííîãî â Óïðàæíåíèè 10.
12. (*3.5) Ðàçðàáîòàéòå è ðåàëèçóéòå îïåðàöèþ ââîäà ïî ñïîñòàâëåíèþ ñ îáðàçöîì. Äëÿ ñïåöèôè
13. (*4) Ïðèäóìàéòå (è ðåàëèçóéòå) âèä îáðàçöîâ, êîòîðûå íàìíîãî ëó÷øå.

Ñïðàâî÷íîå Ðóêîâîäñòâî

1. Ââåäåíèå
ßçûê ïðîãðàììèðîâàíèÿ Ñ++ ýòî C*, ðàñøèðåííûé ââåäåíåì êëàññîâ, inline-ôóíêöèé, ïåðåãðóæå
 * «ßçûê ïðîãðàììèðîâàíèÿ Ñè» Áðàéýíà Â. Êåðíèãàíà è Äåíèñà Ì. Ðèò÷è. Ýòî ðóêîâîäñòâî áûëî

2. Äîãîâîðåííîñòè î Ëåêñèêå
Åñòü øåñòü êëàññîâ ëåêñåì: èäåíòèôèêàòîðû, êëþ÷åâûå ñëâà, êîíñòàíòû, ñòðîêè, îïåðàòîðû è ïð
Åñëè âõîäíîé ïîòîê ðàçîáðàí íà ëåêñåìû äî äàííîãî ñèìâëà, ïðèíèìàåòñÿ, ÷òî ñëåäóþùàÿ ëåêñåì

2.1 Êîììåíòàðèè
Ñèìâîëû /* çàäàþò íà÷àëî êîììåíòàðèÿ, çàêàí÷èâàþùåãîñÿ ñèìâîëàìè */. Êîììåíòàðèè íå ìîãóò á

2.2 Èäåíòèôèêàòîðû (Èìåíà)


Èäåíòèôèêàòîð ïîñëåäîâàòåëüíîñòü áóêâ è öèôð ïðîèâîëüíîé äëèíû. Ïåðâûé ñèìâîë îáÿçàí áûòü

2.3 Êëþ÷åâûå Ñëîâà


Ñëåäóþùèå èäåíòèôèêàòîðû çàðåçåðâèðîâàíû äëÿ èñïîëüçîâíèÿ â êà÷åñòâå êëþ÷åâûõ ñëîâ è íå ìîã
asm auto break case char class const continue default delete do double else enum
extern float for friend goto if inline int long new operator overload public re
gister return short sizeof static struct switch this typedef union unsigned virt
ual void while
Èäåíòèôèêàòîðû signed è volatile çàðåçåðâèðîâàíû äëÿ ïðèìåíåíèÿ â áóäóùåì.

2.4 Êîíñòàíòû
Êàê îïèñàíî íèæå, åñòü íåñêîëüêî âèäîâ êîíñòàíò. Â #2.6 ïðèâîäèòñÿ êðàòêàÿ ñâîäêà àïïàðàòíû

2.4.1 Öåëûå Êîíñòàíòû


Öåëàÿ êîíñòàíòà, ñîñòîÿùàÿ èç ïîñëåäîâàòåëüíîñòè öèôð, ñ÷èòàåòñÿ âîñüìèðè÷íîé, åñëè îíà íà÷

2.4.2 ßâíî Çàäàííûå Äëèííûå Êîíñòàíòû


Äåñÿòè÷íàÿ, âîñüìèðè÷íàÿ èëè øåñòíàäöàòèðè÷íàÿ êîíñòàòà, çà êîòîðîé íåïîñðåäñòâåííî ñòîèò l

2.4.3 Ñèìâîëüíûå Êîíñòàíòû


Ñèìâîëüíàÿ êîíñòàíòà ñîñòîèò èç ñèìâîëà, çàêëþ÷åííîãî â îäèíî÷íûå êàâû÷êè (àïîñòðîôû), êàê,
Íåêîòîðûå íåãðàôè÷åñêèå ñèìâîëû, îäèíî÷íàÿ êàâû÷êà ' è îáðàòíàÿ êîñàÿ \, ìîãóò áûòü ïðåäñòà
ñèìâîë íîâîé ñòðîêè NL(LF) \n ãîðèçîíòàëüíàÿ òàáóëÿöèÿ NT \t âåðòèêàëüíàÿ òàáóëÿöèÿ VT \v â
Escape-ïîñëåäîâàòåëüíîñòü \ddd ñîñòîèò èç îáðàòíîé êñîé, çà êîòîðîé ñëåäóþò 1, 2 èëè 3 âîñü
2.4.4 Êîíñòàíòû ñ Ïëàâàþùåé Òî÷êîé
Êîíñòàíòà ñ ïëàâàþùåé òî÷êîé ñîñòîèò èç öåëîé ÷àñòè, äåñÿòè÷íîé òî÷êè, ìàíòèññû, å èëè Å è

2.4.5 Ïåðå÷èñëèìûå Êîíñòàíòû


Èìåíà, îïèñàííûå êàê ïåðå÷èñëèòåëè, (ñì. #8.5) ÿâëÿþòñÿ êîíñòàíòàìè òèïà int.

2.4.6 Îïèñàííûå Êîíñòàíòû


Îáúåêò (#5) ëþáîãî òèïà ìîæåò áûòü îïðåäåëåí êàê èìåþùèé ïîñòîÿííîå çíà÷åíèå âî âñåé îáëàñò

2.5 Ñòðîêè
Ñòðîêà åñòü ïîñëåäîâàòåëüíîñòü ñèìâîëîâ, çàêëþ÷åííàÿ â äâîéíûå êàâû÷êè: «...». Ñòðîêà èìååò

2.6 Õàðêòåðèñòèêè Àïïàðàòíîãî Îáåñïå÷åíèÿ


 íèæåñëåäóþùåé òàáëèöå ñîáðàíû íåêîòîðûå õàðêòåðèñòèêè àïïàðàòíîãî îáåñïå÷åíèÿ, ðàçëè÷àþùè

3. Çàïèñü Ñèíòàêñèñà
Ïî èñïîëüçóåìûì â äàííîì ðóêîâîäñòâå ñèíòàêñè÷åñêèì ïðâèëàì çàïèñè ñèíòàêñè÷åñêèå êàòåãîðèè

(* âûðàæåíèå opt *)
óêàçûâàåò íà íåîáÿçàòåëüíîñòü âûðàæåíèÿ â ôèãóðíûõ ñêîêàõ. Ñèíòàêñèñ êðàòêî èçëîæåí â #14.

4. Èìåíà è Òèïû
Èìÿ îáîçíà÷àåò(äåíîòèðóåò) îáúåêò, ôóíêöèþ, òèï, çíà÷íèå èëè ìåòêó. Èìÿ ââîäèòñÿ â ïðîãðàìì

4.1 Îáëàñòü Âèäèìîñòè


Åñòü ÷åòûðå âèäà îáëàñòåé âèäèìîñòè: ëîêàëüíàÿ, ôàéë, ïðîãðàììà è êëàññ.
Ëîêàëüíàÿ: Èìÿ, îïèñàííîå â áëîêå (#9.2), ëîêàëüíî â ýòîì áëîêå è ìîæåò èñïîëüçîâàòüñÿ òîëü
Ôàéë: Èìÿ, îïèñàííîå âíå ëþáîãî áëîêà (#9.2) èëè êëàññà (#8.5), ìîæåò èñïîëüçîâàòüñÿ â ôàéë
Êëàññ: Èìÿ ÷ëåíà êëàññà ëîêàëüíî äëÿ åãî êëàññà è ìîæåò èñïîëüçîâàòüñÿ òîëüêî â ôóíêöèè ÷ëå
Èìÿ ìîæåò áûòü ñêðûòî ïîñðåäñòâîì ÿâíîãî îïèñàíèÿ òîãî æå èìåíè â áëîêå èëè êëàññå. Èìÿ â á
4.2 Îïðåäåëåíèÿ
Îïèñàíèå (#8) ÿâëÿåòñÿ îïðåäåëåíèåì, çà èñêëþ÷åíèåì òåõ ñëó÷àåâ, êîãäà îíî îïèñûâàåò ôóíêöè

4.3 Êîìïîíîâêà
Èìÿ â ôàéëîâîé îáëàñòè âèäèìîñòè, íå îïèñàííîå ÿâíî êàê static, ÿâëÿåòñÿ îáùèì äëÿ êàæäîãî
Òèïû, ñïåöèôèöèðîâàííûå âî âñåõ îïèñàíèÿõ âíåøíåãî èìåíè äîëæíû áûòü èäåíòè÷íû. Ìîæåò áûòü
Ðåàëèçàöèÿ ìîæåò ïîòðåáîâàòü, ÷òîáû ñîñòàâíîå const, èïîëüçîâàííîå òàì, ãäå íå âñðå÷åíî íèê

4.4 Êëàññû Ïàìÿòè


Åñòü äâà îïèñûâàåìûõ êëàññà ïàìÿòè: àâòîìàòè÷åñêèé è ñòàòè÷åñêèé.
Àâòîìàòè÷åñêèå îáúåêòû ëîêàëüíû äëÿ êàæäîãî âûçîâà áëîêà è ñáðàñûâàþòñÿ ïî âûõîäå èç íåãî.
Ñòàòè÷åñêèå îáúåêòû ñóùåñòâóþò è ñîõðàíÿþò ñâîå çíà÷åíèå â òå÷åíèå âûïîëíåíèÿ âñåé ïðîãðàìû
Íåêîòîðûå îáúåêòû íå ñâÿçàíû ñ èìåíàìè è èõ âðåìåíà æèíè ÿâíî óïðàâëÿþòñÿ îïåðàòîðàìè new è

4.5 Îñíîâíûå Òèïû


Îáúåêòû, îïèñàííûå êàê ñèìâîëû (char), äîñòàòî÷íû äëÿ õðàíåíèÿ ëþáîãî ýëåìåíòà ìàøèííîãî íà
 íàñòîÿùèé ìîìåíò èìåþòñÿ öåëûå òðåõ ðàçìåðîâ, îïèñûâåìûå êàê short int, int è long int. Á
Êàæäîå ïåðå÷èñëåíèå (#8.9) ÿâëÿåòñÿ íàáîðîì èìåíîâàííûõ êîíñòàíò. Ñâîéñòâà enum èäåíòè÷íû ñ
Öåëûå áåç çíàêà, îïèñûâàåìûå êàê unsigned, ïîä÷èíÿþòñÿ ïðàâèëàì àðèôìåòèêè ïî ìîäóëþ 2n, ãä
×èñëà ñ ïëàâàþùåé òî÷êîé îäèíàðíîé (float) è äâîéíîé (double) òî÷íîñòè â íåêîòîðûõ ìàøèííûõ
Ïîñêîëüêó îáúåêòû ïåðå÷èñëåííûõ âûøå òèïîâ âïîëíå ìîæíî èíòåðïðåòèðîâàòü êàê ÷èñëà, ìû áóäå
Òèï äàííûõ void (ïóñòîé) îïðåäåëÿåò ïóñòîå ìíîæåñòâî çíà÷åíèé. Çíà÷åíèå (íåñóùåñòâóþùåå) îá

4.4 Ïðîèçâîäíûå Òèïû


Êðîìå îñíîâíûõ àðèôìåòè÷åñêèõ òèïîâ êîíöåïòóàëüíî ñùåñòâóåò áåñêîíå÷íî ìíîãî ïðîèçâîäíûõ òè
ìàññèâû îáúåêòîâ äàííîãî òèïà;
ôóíêöèè, ïîëó÷àþùèå àðãóìåíòû äàííîãî òèïà è âîçâðàùàùèå îáúåêòû äàííîãî òèïà;
óêàçàòåëè íà îáúåêòû äàííîãî òèïà;
ññûëêè íà îáúåêòû äàííîãî òèïà;
êîíñòàíòû, ÿâëÿþùèåñÿ çíà÷åíèÿìè äàííîãî òèïà;
êëàññû, ñîäåðæàùèå ïîñëåäîâàòåëüíîñòü îáúåêòîâ ðàçëè÷íûõ òèïîâ, ìíîæåñòâî ôóíêöèé äëÿ ðàáîò
îáúåäèíåíèÿ, ÿâëÿþùèåñÿ ñòðóêòóðàìè, êîòîðûå ìîãóò â ðàçíîå âðåìÿ ñîäåðæàòü îáúåêòû ðàçíûõ
 öåëîì ýòè ñïîñîáû êîíñòðóèðîâàíèÿ îáúåêòîâ ìîãóò ïðìåíÿòüñÿ ðåêóðñèâíî.
Îáúåêò òèïà void* (óêàçàòåëü íà void) ìîæíî èñïîëüçîâàòü äëÿ óêàçàíèÿ íà îáúåêòû íåèçâåñòíî
5. Îáúåêòû è Lvalue (Àäðåñà)
Îáúåêò åñòü îáëàñòü ïàìÿòè. lvalue (àäðåñ) åñòü âûðàæíèå, ññûëàþùååñÿ íà îáúåêò. Î÷åâèäíûé
6. Ïðåîáðàçîâàíèÿ
Îïðåäåëåííûå îïåðàöèè ìîãóò â çàâèñèìîñòè îò èõ îïåðàäîâ âûçûâàòü ïðåîáðàçîâàíèå çíà÷åíèÿ î

6.1 Ñèìâîëû è Öåëûå


Ñèìâîë èëè êîðîòêîå öåëîå ìîãóò èñïîëüçîâàòüñÿ, åñëè ìîæåò èñïîëüçîâàòüñÿ öåëîå. Âî âñåõ ñë
 ìàøèíàõ, ãäå ñèìâîëû ðàññìàòðèâàþòñÿ êàê èìåþùèå çíàê (çíàêîâûå), ñèìâîëû ìíîæåñòâà êîäà
Êîãäà äëèííîå öåëîå ïðåîáðàçóåòñÿ â êîðîòêîå èëè â char, îíî óðåçàåòñÿ âëåâî; èçáûòî÷íûå áè

6.2 Float è Double


Äëÿ âûðàæåíèé float ìîãóò âûïîëíÿòüñÿ äåéñòâèÿ àðèôìåòêè ñ ïëàâàþùåé òî÷êîé îäèíàðíîé òî÷íî

6.3 Ïëàâàþùèå è Öåëûå


Ïðåîáðàçîâàíèÿ ïëàâàþùèõ çíà÷åíèé â öåëî÷èñëåííûé òèï èìååò ñêëîííîñòü áûòü ìàøèííî-çàâèñèì
Ïðåîáðàçîâàíèå öåëî÷èñëåííîãî çíà÷åíèÿ â ïëàâàþùèé òèï âûïîëíÿþòñÿ õîðîøî. Ïðè íåõâàòêå â à

6.4 Óêàçàòåëè è Öåëûå


Âûðàæåíèå öåëîãî òèïà ìîæíî ïðèáàâèòü ê óêàçàòåëþ èëè âû÷åñòü èç íåãî.  òàêîì ñëó÷àå ïåðâû
Ìîæíî ïðîèçâîäèòü âû÷èòàíèå íàä äâóìÿ óêàçàòåëÿìè íà îáúåêòû îäíîãî òèïà; â ýòîì ñëó÷àå ðåç

6.5 Unsigned
Âñåãäà ïðè ñî÷åòàíèè öåëîãî áåç çíàêà è îáû÷íîãî öåëîãî îáû÷íîå öåëîå ïðåîáðàçóåòñÿ ê òèïó
Ïðè ïðåîáðàçîâàíèè öåëîãî áåç çíàêà â äëèííîå çíà÷åíèå ðåçóëüòàòà ÷èñëåííî ñîâïàäàåò ñî çíà
6.6 Àðèôìåòè÷åñêèå Ïðåîáðàçîâàíèÿ
Áîëüøîå êîëè÷åñòâî îïåðàöèé âûçûâàþò ïðåîáðàçîâàíèÿ è äàþò òèï ðåçóëüòàòà îäèíàêîâûì îáðàçî
Âî-ïåðâûõ, ëþáûå îïåðàíäû òèïà char, unsigned char èëè short ïðåîáðàçóþòñÿ ê òèïó int.
Äàëåå, åñëè îäèí èç îïåðàíäîâ èìååò òèï double, òî äðãîé ïðåîáðàçóåòñÿ ê òèïó double è òîò
Èíà÷å, åñëè îäèí èç îïåðàíäîâ èìååò òèï unsigned long, òî äðóãîé ïðåîáðàçóåòñÿ ê òèïó unsig
Èíà÷å, åñëè îäèí èç îïåðàíäîâ èìååò òèï long, òî äðóãîé ïðåîáðàçóåòñÿ ê òèïó long è òàêîâ æ
Èíà÷å, åñëè îäèí èç îïåðàíäîâ èìååò òèï unsigned, òî äðóãîé ïðåîáðàçóåòñÿ ê òèïó unsigned è
Èíà÷å îáà îïåðàíäà äîëæíû èìåòü òèï int è òàêîâ æå òèï ðåçóëüòàòà.

6.7 Ïðåîáðàçîâàíèÿ Óêàçàòåëåé


Âåçäå, ãäå óêàçàòåëè ïðèñâàèâàþòñÿ, èíèöèàëèçèðóþòñÿ, ñðàâíèâàþòñÿ è ò.ä. ìîãóò âûïîëíÿòüñÿ
Êîíñòàíòà 0 ìîæåò ïðåîáðàçîâûâàòüñÿ â óêàçàòåëü, è ãðàíòèðóåòñÿ, ÷òî ýòî çíà÷åíèå ïîðîäèò ó
Óêàçàòåëü ëþáîãî òèïà ìîæåò ïðåîáðàçîâûâàòüñÿ â void*.
Óêàçàòåëü íà êëàññ ìîæåò ïðåîáðàçîâûâàòüñÿ â óêàçàòåëü íà îòêðûòûé áàçîâûé êëàññ ýòîãî êëàñ
Èìÿ âåêòîðà ìîæåò ïðåîáðàçîâûâàòüñÿ â óêàçàòåëü íà åãî ïåðâûé ýëåìåíò.
Èäåíòèôèêàòîð, îïèñàííûé êàê «ôóíêöèÿ, âîçâðàùàþùàÿ ...», âñåãäà, êîãäà îí íå èñïîëüçóåòñÿ

6.8 Ïðåîáðàçîâàíèÿ Ññûëîê


Âåçäå, ãäå èíèöèàëèçèðóþòñÿ ññûëêè, ìîæåò âûïîëíÿòüñÿ ñëåäóþùåå ïðåîáðàçîâàíèå.
Ññûëêà íà êëàññ ìîæåò ïðåîáðàçîâûâàòüñÿ â ññûëêó íà îòðûòûé áàçîâûé êëàññ ýòîãî êëàññà, ñì.

7. Âûðàæåíèÿ
Ïðèîðèòåò îïåðàöèé â âûðàæåíÿõ òàêîé æå, êàê è ïîðÿäîê ãëàâíûõ ïîäðàçäåëîâ â ýòîì ðàçäåëå,
 îñòàëüíûõ ñëó÷àÿõ ïîðÿäîê âû÷èñëåíèÿ âûðàæåíèÿ íåîïðäåëåí. Òî÷íåå, êîìïèëÿòîð âîëåí âû÷èñ
ïîðÿäêå, êîòîðûé îí ñ÷èòàåò áîëåå ýôôåêòèâíûì, äàæå åñëè ïîâûðàæåíèÿ âûçûâàþò ïîáî÷íûå ýôôå
Îáðàáîòêà ïåðåïîëíåíèÿ è êîíòðîëü äåëåíèÿ ïðè âû÷èñëåíèè âûðàæåíèÿ ìàøèííî çàâèñèìû.  áîëü
Êðîìå ñòàíäàðòíîãî çíà÷åíèÿ, îïèñàííîãî â #7.2-7.15, îïåðàöèè ìîãóò áûòü ïåðåãðóæåíû*, òî å
 * Ýòîò òåðìèí ïðèìåíÿåòñÿ äëÿ îïèñàíèÿ èñïîëüçîâàíèÿ â ÿçûêå îäíîé è òîé æå ëåêñåìû äëÿ î

7.1 Îñíîâíûå Âûðàæåíèÿ


Îñíîâíûå âûðàæåíèÿ, âêëþ÷àþùèå â ñåáÿ . , -» , èíäåêñðîâàíèå è âûçîâû ôóíêöèé, ãðóïïèðóþòñÿ
ñïèñîê_âûðàæåíèé: âûðàæåíèå ñïèñîê_âûðàæåíèé , âûðàæåíèå
id: èäåíòèôèêàòîð èìÿ_ôóíêöèè_îïåðàöèè typedef-èìÿ :: èäåíòèôèêàòîð typedef-èìÿ :: èìÿ_ôóíê
ïåðâè÷íîå_âûðàæåíèå: id :: èäåíòèôèêàòîð êîíñòàíòà ñòðîêà this ( âûðàæåíèå ) ïåðâè÷íîå_âûðà
Èäåíòèôèêàòîð åñòü ïåðâè÷íîå âûðàæåíèå, ïðè÷åì ñîîòâåòòâåííî îïèñàííîå (#8). Èìÿ_ôóíêöèè_îï
Îïåðàöèÿ ::, çà êîòîðîé ñëåäóåò èäåíòèôèêàòîð èç ôàéëîâîé îáëàñòè âèäèìîñòè, åñòü òî æå, ÷ò
Typedef-èìÿ (#8.8) , çà êîòîðûì ñëåäóåò ::, ïîñëå ÷åãî ñëåäóåò èäåíòèôèêàòîð, ÿâëÿåòñÿ ïåðâ
Êîíñòàíòà ÿâëÿåòñÿ ïåðâè÷íûì âûðàæåíèåì. Åå òèï äîëæåí áûòü int, long èëè double â çàâèñèìî
Ñòðîêà ÿâëÿåòñÿ ïåðâè÷íûì âûðàæåíèåì. Åå òèï «ìàññèâ ñèìâîëîâ». Îáû÷íî îí ñðàçó æå ïðåîáð
Êëþ÷åâîå ñëîâî this ÿâëÿåòñÿ ëîêàëüíîé ïåðåìåííîé â òåëå ôóíêöèè ÷ëåíà (ñì. #8.5) . Îíî ÿâë
Âûðàæåíèå, çàêëþ÷åííîå â êðóãëûå ñêîáêè, ÿâëÿåòñÿ ïåâè÷íûì âûðàæåíèåì, ÷åé òèï è çíà÷åíèå ò
Ïåðâè÷íîå âûðàæåíèå, çà êîòîðûì ñëåäóåò âûðàæåíèå â êâàäðàòíûõ ñêîáêàõ, ÿâëÿåòñÿ ïåðâè÷íûì
Âûçîâ ôóíêöèè ÿâëÿåòñÿ ïåðâè÷íûì âûðàæåíèåì, çà êîòîðûì ñëåäóþò ñêîáêè, ñîäåðæàùèå ñïèñîê (
Êàæäûé ôîðìàëüíûé ïàðàìåòð èíèöèàëèçèðóåòñÿ ôàêòè÷åñêèì ïàðàìåòðîì (#8.6). Âûïîëíÿþòñÿ ñòàí
Ôóíêöèÿ ìîæåò áûòü îïèñàíà êàê ïîëó÷àþùàÿ ìåíüøå èëè áîëüøå ïàðàìåòðîâ, ÷åì ñïåöèôèöèðîâàíî
Äîïóñòèìû ðåêóðñèâíûå âûçîâû ëþáûõ ôóíêöèé.
Ïåðâè÷íîå âûðàæåíèå, ïîñëå êîòîðîãî ñòîèò òî÷êà, çà êòîðîé ñëåäóåò èäåíòèôèêàòîð (èëè èäåíò
Ïåðâè÷íîå âûðàæåíèå, ïîñëå êîòîðîãî ñòîèò ñòðåëêà ( -»
), çà êîòîðîé ñëåäóåò èäåíòèôèêàòîð (èëè èäåíòèôèêàòîð, óòîíåííûé typedef-èìåíåì ñ ïîìîùüþ
Åñëè ïåðâè÷íîå âûðàæåíèå äàåò çíà÷åíèå òèïà «óêàçàòåëü íà ...» (ñì. #8.4 and #8.6.3), çíà÷å

7.2 Óíàðíûå Îïåðàöèè


Âûðàæåíèÿ ñ óíàðíûìè îïåðàöèÿìè ãðóïïèðóþò ñïðàâà íàëâî:
óíàðíîå_âûðàæåíèå: óíàðíàÿ_îïåðàöèÿ âûðàæåíèå âûðàæåíèå ++ âûðàæåíèå sizeof âûðàæåíèå siz
Óíàðíàÿ îïåðàöèÿ * îçíà÷àåò êîñâåííîå îáðàùåíèå: âûðàæåíèå äîëæíî áûòü óêàçàòåëåì è ðåçóëüò
Ðåçóëüòàòîì óíàðíîé îïåðàöèè amp; ÿâëÿåòñÿ óêàçàòåëü íà îáúåêò, íà êîòîðûé ññûëàåòñÿ îïåðàí
Ðåçóëüòàòîì óíàðíîé îïåðàöèè + ÿâëÿåòñÿ çíà÷åíèå åå îïðàíäà ïîñëå âûïîëíåíèÿ îáû÷íûõ àðèôìå
Ðåçóëüòàòîì óíàðíîé îïåðàöèè ÿâëÿåòñÿ îòðèöàòåëüíîå çíà÷åíèå åå îïåðàíäà. Îïåðàíä äîëæåí
Ðåçóëüòàòîì îïåðàöèè ëîãè÷åñêîãî îòðèöàíèÿ ! ÿâëÿåòñÿ 1, åñëè çíà÷åíèå îïåðàíäà 0, è 0, åñë
Îïåðàöèÿ ~ äàåò äîïîëíåíèå çíà÷åíèÿ îïåðàíäà äî åäèíèöû. Âûïîëíÿþòñÿ îáû÷íûå àðèôìåòè÷åñêèå
7.2.1 Óâåëè÷åíèå è Óìåíüøåíèå
Îïåðàíä ïðåôèêñíîãî ++ ïîëó÷àåò ïðèðàùåíèå. Îïåðàíä äîæåí áûòü àäðåñíûì . Çíà÷åíèåì ÿâëÿåòñ
Îïåðàíä ïðåôèêñíîãî óìåíüøàåòñÿ àíàëîãè÷íî äåéñòâèþ ïðåôèêñíîé îïåðàöèè ++.
Çíà÷åíèå, ïîëó÷àåìîå ïðè èñïîëüçîâàíèè ïîñòôèêñíîãî ++, åñòü çíà÷åíèå îïåðàíäà. Îïåðàíä äîë
Çíà÷åíèå, ïîëó÷àåìîå ïðè èñïîëüçîâàíèè ïîñòôèêñíîé , åñòü çíà÷åíèå îïåðàíäà. Îïåðàíä äîëæå

7.2.2 Sizeof
Îïåðàöèÿ sizeof äàåò ðàçìåð îïåðàíäà â áàéòàõ. (Áàéò íå îïðåäåëÿåòñÿ ÿçûêîì èíà÷å, ÷åì ÷åðå
Îïåðàöèþ sizeof ìîæíî òàêæå ïðèìåíÿòü ê çàêëþ÷åííîìó â ñêîáêè èìåíè òèïà.  ýòîì ñëó÷àå îíà

7.2.3 ßâíîå Ïðåîáðàçîâàíèå Òèïà


Ïðîñòîå_èìÿ_òèïà (#8.2), âîçìîæíî, çàêëþ÷åííîå â ñêîáêè, çà êîòîðûì èäåò çàêëþ÷åííîå â ñêîá
Óêàçàòåëü ìîæåò áûòü ÿâíî ïðåîáðàçîâàí ê ëþáîìó èç öåë÷èñëåííûõ òèïîâ, äîñòàòî÷íî ïî âåëè÷è
Îáúåêò öåëî÷èñëåííîãî òèïà ìîæåò áûòü ÿâíî ïðåîáðàçîâàí â óêàçàòåëü. Îòîáðàæàþùàÿ ôóíêöèÿ â
Óêàçàòåëü íà îäèí òèï ìîæåò áûòü ÿâíî ïðåîáðàçîâàí â óêàçàòåëü íà äðóãîé òèï. Èñïîëüçîâàíèå
Îáúåêò ìîæåò ïðåîáðàçîâûâàòüñÿ â îáúåêò êëàññà òîëüêî åñëè áûë îïèñàí ñîîòâåòñòâóþùèé êîíñò
Îáúåêò ìîæåò ÿâíî ïðåîáðàçîâûâàòüñÿ â ññûëî÷íûé òèï amp;X, åñëè óêàçàòåëü íà ýòîò îáúåêò ìî

7.2.4 Ñâîáîäíàÿ Ïàìÿòü


Îïåðàöèÿ new ñîçäàåò îáúåêò òèïà èìÿ_òèïà (ñì. #8.7), ê êîòîðîìó îí ïðèìåíåí. Âðåìÿ æèçíè î
void* operator new (long);
Ïàðàìåòð çàäàåò òðåáóåìîå ÷èñëî áàéòîâ. Ïàìÿòü áóäåò èíèöèàëèçèðîâàíà. Åñëè operator new()
Îïåðàöèÿ delete óíè÷òîæàåò îáúåêò, ñîçäàííûé îïåðàöèåé new. Åå ðåçóëüòàò ÿâëÿåòñÿ void. Îïå
×òîáû îñâîáîäèòü óêàçàííóþ ïàìÿòü, îïåðàöèÿ delete âûçâàåò ôóíêöèþ
void operator delete (void*);
 ôîðìå
delete [ âûðàæåíèå ] âûðàæåíèå
âòîðîé ïàðàìåòð óêàçûâàåò íà âåêòîð, à ïåðâîå âûðàæåíèå çàäàåò ÷èñëî ýëåìåíòîâ ýòîãî âåêòîð
7.3 Ìóëüòèïëèêàòèâíûå Îïåðàöèè
Ìóëüòèïëèêàòèâíûå îïåðàöèè *, / è % ãðóïïèðóþò ñëåâà íàïðàâî. Âûïîëíÿþòñÿ îáû÷íûå àðèôìåòè÷
ìóëüòèïëèêàòèâíîå_âûðàæåíèå: âûðàæåíèå * âûðàæåíèå âûðàæåíèå / âûðàæåíèå âûðàæåíèå % âûðàæå
Áèíàðíàÿ îïåðàöèÿ * îïðåäåëÿåò óìíîæåíèå. Îïåðàöèÿ * àññîöèàòèâíà è âûðàæåíèÿ ñ íåñêîëüêèìè
Áèíàðíàÿ îïåðàöèÿ % äàåò îñòàòîê îò äåëåíèÿ ïåðâîãî âðàæåíèÿ íà âòîðîå. Âûïîëíÿþòñÿ îáû÷íûå

7.4 Àääèòèâíûå Îïåðàöèè


Àääèòèâíûå îïåðàöèè + è ãðóïïèðóþò ñëåâà íàïðàâî. Âûïîëíÿþüñÿ îáû÷íûå àðèôìåòè÷åñêèå ïðåî
àääèòèâíîå_âûðàæåíèå: âûðàæåíèå + âûðàæåíèå âûðàæåíèå âûðàæåíèå
Ðåçóëüòàòîì îïåðàöèè + ÿâëÿåòñÿ ñóììà îïåðàíäîâ. Ìîæíî ñóììèðîâàòü óêàçàòåëü íà îáúåêò ìàññ
Íèêàêèå äðóãèå êîìáèíàöèè òèïîâ äëÿ óêàçàòåëåé íå äîïóòèìû.
Îïåðàöèÿ + àññîöèàòèâíà è âûðàæåíèå ñ íåñêîëüêèìè óìíæåíèÿìè íà îäíîì óðîâíå ìîæåò áûòü ðåî
Ðåçóëüòàòîì îïåðàöèè ÿâëÿåòñÿ ðàçíîñòü îïåðàíäîâ. Âûïîëíÿþüñÿ îáû÷íûå àðèôìåòè÷åñêèå ïðåî
Åñëè âû÷èòàþòñÿ óêàçàòåëè íà îáúåêòû îäíîãî òèïà, òî ðçóëüòàò ïðåîáðàçóåòñÿ (ïîñðåäñòâîì äå

7.5 Îïåðàöèè Ñäâèãà


Îïåðàöèè ñäâèãà « è » ãðóïïèðóþò ñëåâà íàïðàâî. Îáå âûïîëíÿþò îäíî îáû÷íîå àðèôìåòè÷åñêîå
åñëè ïðàâûé îïåðàíä îòðèöàòåëåí èëè áîëüøå èëè ðàâåí äëèíå îáúåêòà â áèòàõ.
ñäâèãîâîå_âûðàæåíèå: âûðàæåíèå « âûðàæåíèå âûðàæåíèå » âûðàæåíèå
Çíà÷åíèåì Å1 « Å2 ÿâëÿåòñÿ Å1 (ðàññìàòðèâàåìîå êàê áòîâîå ïðåäñòàâëåíèå), ñäâèíóòîå âëåâî

7.6 Îïåðàöèè Îòíîøåíèÿ


Îïåðàöèè îòíîøåíèÿ (ñðàâíåíèÿ) ãðóïïèðóþò ñëåâà íàïðàâî, íî ýòîò ôàêò íå î÷åíü-òî ïîëåçåí:
âûðàæåíèå_îòíîøåíèÿ: âûðàæåíèå « âûðàæåíèå âûðàæåíèå » âûðàæåíèå âûðàæåíèå «= âûðàæåíèå âûð
Îïåðàöèè « (ìåíüøå ÷åì), » (áîëüøå ÷åì), «= è »= âñå äþò 0, åñëè çàäàííîå ñîîòíîøåíèå ëîæíî

7.7 Îïåðàöèè Ðàâåíñòâà


âûðàæåíèå_ðàâåíñòâà: âûðàæåíèå == âûðàæåíèå âûðàæåíèå != âûðàæåíèå
Îïåðàöèè == è != â òî÷íîñòè àíàëîãè÷íû îïåðàöèÿì ñðàâííèÿ çà èñêëþ÷åíèåì èõ íèçêîãî ïðèîðèò
Óêàçàòåëü ìîæåò ñðàâíèâàòüñÿ ñ 0.
7.8 Îïåðàöèÿ Ïîáèòîâîå È
È-âûðàæåíèå: âûðàæåíèå amp; âûðàæåíèå
Îïåðàöèÿ amp; àññîöèàòèâíà, è âûðàæåíèÿ, ñîäåðæàùèå amp;, ìãóò ðåîðãàíèçîâûâàòüñÿ. Âûïîëíÿþ

7.9 Îïåðàöèÿ Ïîáèòîâîå Èñêëþ÷àþùåå ÈËÈ


èñêëþ÷àþùåå_ÈËÈ_âûðàæåíèå: âûðàæåíèå ^ âûðàæåíèå
Îïåðàöèÿ ^ àññîöèàòèâíà, è âûðàæåíèÿ, ñîäåðæàùèå ^, ìãóò ðåîðãàíèçîâûâàòüñÿ. Âûïîëíÿþòñÿ îá

7.10 Îïåðàöèÿ Ïîáèòîâîå Âêëþ÷àþùåå ÈËÈ


âêëþ÷àþùåå_ÈËÈ_âûðàæåíèå: âûðàæåíèå ! âûðàæåíèå
Îïåðàöèÿ ! àññîöèàòèâíà, è âûðàæåíèÿ, ñîäåðæàùèå !, ìãóò ðåîðãàíèçîâûâàòüñÿ. Âûïîëíÿþòñÿ îá

7.11 Îïåðàöèÿ Ëîãè÷åñêîå È


ëîãè÷åñêîå_È_âûðàæåíèå: âûðàæåíèå amp; amp; âûðàæåíèå
Îïåðàöèÿ amp; amp; ãðóïïèðóåò ñëåâà íàïðàâî. Îíà âîçâðàùàåò 1, åñëè îáà îïåðàíäà íåíóëåâûå,
Îïåðàíäû íå îáÿçàíû èìåòü îäèí è òîò æå òèï, íî êàæäûé èç íèõ äîëæåí èìåòü îäèí èç îñíîâíûõ

7.12 Îïåðàöèÿ Ëîãè÷åñêîå ÈËÈ


ëîãè÷åñêîå_ÈËÈ_âûðàæåíèå: âûðàæåíèå !! âûðàæåíèå
Îïåðàöèÿ !! ãðóïïèðóåò ñëåâà íàïðàâî. Îíà âîçâðàùàåò 1, åñëè õîòÿ áû îäèí èç åå îïåðàíäîâ í
Îïåðàíäû íå îáÿçàíû èìåòü îäèí è òîò æå òèï, íî êàæäûé èç íèõ äîëæåí èìåòü îäèí èç îñíîâíûõ

7.13 Óñëîâíàÿ Îïåðàöèÿ


óñëîâíîå_âûðàæåíèå: âûðàæåíèå ? âûðàæåíèå : âûðàæåíèå
Óñëîâíàÿ îïåðàöèÿ ãðóïïèðóåò ñëåâà íàïðàâî. Âû÷èñëÿåòñÿ ïåðâîå âûðàæåíèå, è åñëè îíî íå 0,

7.14 Îïåðàöèè Ïðèñâàèâàíèÿ


Åñòü ìíîãî îïåðàöèé ïðèñâàèâàíèÿ, âñå ãðóïïèðóþò ñëåâà íàïðàâî. Âñå â êà÷åñòâå ëåâîãî îïåðà
âûðàæåíèå_ïðèñâàèâàíèÿ:
âûðàæåíèå îïåðàöèÿ_ïðèñâàèâàíèÿ âûðàæåíèå
îïåðàöèÿ_ïðèñâàèâàíèÿ: îäíà èç
= += -= *= /= %= »»= ««= amp;= ~= !=
 ïðîñòîì ïðèñâàèâàíèè ñ = çíà÷åíèå âûðàæåíèÿ çàìåùàåò ñîáîé çíà÷åíèå îáúåêòà, íà êîòîðûé ñ
Ïðèñâàèâàíèå îáúåêòó òèïà «óêàçàòåëü íà ...» âûïîëíèò ïðèñâàèâàíèå îáúåêòó, äåíîòèðóåìîìó ñ
Âûïîëíåíèå âûðàæåíèÿ âèäà E1 op= E2 ìîæíî ïðåäñòàâèòü ñåáå êàê ýêâèâàëåíòíîå E1 = E1 op (E2

7.15 Îïåðàöèÿ Çàïÿòàÿ


çàïÿòàÿ_âûðàæåíèå: âûðàæåíèå , âûðàæåíèå
Ïàðà âûðàæåíèé, ðàçäåëåííûõ çàïÿòîé, âû÷èñëÿåòñÿ ñëåâà íàïðàâî, çíà÷åíèå ëåâîãî âûðàæåíèÿ ò
f (a,(t=3,t+2),c)
èìååò òðè ïàðàìåòðà, âòîðûì èç êîòîðûõ ÿâëÿåòñÿ çíà÷åíèå 5.

7.16 Ïåðåãðóæåííûå Îïåðàöèè


Áîëüøèíñòâî îïåðàöèé ìîæåò áûòü ïåðåãðóæåíî, òî åñòü, îïèñàíî òàê, ÷òîáû îíè ïîëó÷àëè â êà÷
Ýêâèâàëåíòíîñòü îïåðàöèé, ïðèìåíÿåìûõ ê îñíîâíûì òèïàì (íàïðèìåð, ++a ýêâèâàëåíòíî a+=1), í

7.16.1 Óíàðíûå Îïåðàöèè


Óíàðíàÿ îïåðàöèÿ, ïðåôèêñíàÿ èëè ïîñòôèêñíàÿ, ìîæåò áûòü îïðåäåëåíà èëè ñ ïîìîùüþ ôóíêöèè ÷

7.16.2 Áèíàðíûå Îïåðàöèè


Áèíàðíàÿ îïåðàöèÿ ìîæåò áûòü îïðåäåëåíà èëè ñ ïîìîùüþ ôóíêöèè ÷ëåíà (ñì. #8.5.4), ïîëó÷àþùå

7.16.3 Îñîáûå Îïåðàöèè


Âûçîâ ôóíêöèè ïåðâè÷íîå_âûðàæåíèå ( ñïèñîê_âûðàæåíèé opt )
è èíäåêñèðîâàíèå
ïåðâè÷íîå_âûðàæåíèå [ âûðàæåíèå ]
ñ÷èòàþòñÿ áèíàðíûìè îïåðàöèÿìè. Èìåíàìè îïðåäåëÿþùåé ôóíêöèè ÿâëÿþòñÿ ñîîòâåòñâåííî operato

8. Îïèñàíèÿ
Îïèñàíèÿ èñïîëüçóþòñÿ äëÿ îïðåäåëåíèÿ èíòåðïðåòàöèè, äâàåìîé êàæäîìó èäåíòèôèêàòîðó. Îíè íå
îïèñàíèå: ñïåöèôèêàòîðû_îïèñàíèÿ opt ñïèñîê_îïèñàòåëåé opt ; îïèñàíèå_èìåíè asm_îïèñàíèå
Îïèñàòåëè â ñïèñêå_îïèñàòåëåé ñîäåðæàò èäåíòèôèêàòîðû, ïîäëåæàùèå îïèñàíèþ. Ñïåöèôèêàòîðû_î
ñïåöèôèêàòîð_îïèñàíèÿ: ñïåöèôèêàòîð_êëàññà_ïàìÿòè ñïåöèôèêàòîð_òèïà ñïåöèôèêàòîð_ôóíêöèè fr
ñïåöèôèêàòîðû_îïèñàíèÿ: ñïåöèôèêàòîð_îïèñàíèÿ ñïåöèôèêàòîð_îïèñàíèÿ opt
Ñïèñîê äîëæåí áûòü âíóòðåííå íåïðîòèâîðå÷èâ â îïèñûâàìîì íèæå ñìûñëå.

8.1 Ñïåöèôèêàòîðû Êëàññà Ïàìÿòè


Ñïåöèôèêàòîðû ýòî:
ñïåöèôèêàòîð_êëàññà_ïàìÿòè: auto static extern register
Îïèñàíèÿ, èñïîëüçóþùèå ñïåöèôèêàòîðû auto, static è register òàêæå ñëóæàò îïðåäåëåíèÿìè òåì
Îïèñàíèå register ëó÷øå âñåãî ïðåäñòàâèòü êàê îïèñàíèå auto (àâòîìàòè÷åñêèé) ñ ïîäñêàçêîé ê
Ñïåöèôèêàòîðû auto èëè register ìîãóò ïðèìåíÿòüñÿ òîëüêî ê èìåíàì, îïèñàííûì â áëîêå, èëè ê
 îïèñàíèè ìîæåò áûòü çàäàí ìàêñèìóì îäèí sc_ñïåöèôèêòîð. Åñëè â îïèñàíèè îòñóòñâóåò ñïåöèô
Ñïåöèôèêàòîðû static è extern ìîãóò èñïîëüçîâàòüñÿ òîëêî äëÿ èìåí îáúåêòîâ è ôóíêöèé.
Íåêîòîðûå ñïåöèôèêàòîðû ìîãóò èñïîëüçîâàòüñÿ òîëüêî â îïèñàíèÿõ ôóíêöèé:
ñïåöèôèêàòîð_ôóíêöèè: overload inline virtual
Ñïåöèôèêàòîð ïåðåãðóçêè overload äåëàåò âîçìîæíûì èïîëüçîâàíèå îäíîãî èìåíè äëÿ îáîçíà÷åíèÿ
Ñïåöèôèêàòîð inline ÿâëÿåòñÿ òîëüêî ïîäñêàçêîé êîìïèëòîðó, íå âëèÿåò íà ñìûñë ïðîãðàììû è ì
Ñïåöèôèêàòîð virtual ìîæåò èñïîëüçîâàòüñÿ òîëüêî â îïñàíèÿõ ÷ëåíîâ êëàññà, ñì. #8.5.4.
Ñïåöèôèêàòîð friend èñïîëüçóåòñÿ äëÿ îòìåíû ïðàâèë ñîðûòèÿ èìåíè äëÿ ÷ëåíîâ êëàññà è ìîæåò
Ñ ïîìîùüþ ñïåöèôèêàòîðà typedef ââîäèòñÿ èìÿ äëÿ òèïà, ñì. #8.8.

8.2 Ñïåöèôèêàòîðû Òèïà


Ñïåöèôèêàòîðàìè òèïîâ (ñïåöèôèêàòîð_òèïà) ÿâëÿþòñÿ:
ñïåöèôèêàòîð_òèïà:
ïðîñòîå_èìÿ_òèïà ñïåöèôèêàòîð_êëàññà enum-ñïåöèôèêàòîð ñëîæíûé_ñïåöèôèêàòîð_òèïà const
Ñëîâî const ìîæíî äîáàâëÿòü ê ëþáîìó äîïóñòèìîìó ñïåöôèêàòîðó_òèïà.  îñòàëüíûõ ñëó÷àÿõ â î
ïðîñòîå_èìÿ_òèïà: char short int long unsigned float double const void
Ñëîâà long, short è unsigned ìîæíî ðàññìàòðèâàòü êàê ïðèëàãàòåëüíûå. Îíè ìîãóò ïðèìåíÿòüñÿ
Ñïåöèôèêàòîðû êëàññà è ïåðå÷èñëåíèÿ îáñóæäàþòñÿ â #8.5 è #8.10 ñîîòâåòñòâåííî.
ñëîæíûé_ñïåöèôèêàòîð_òèïà: êëþ÷ typedef-èìÿ êëþ÷ èäåíòèôèêàòîð
êëþ÷: class struct union enum
Ñëîæíûé ñïåöèôèêàòîð òèïà ìîæíî èñïîëüçîâàòü äëÿ ññûëêè íà èìÿ êëàññà èëè ïåðå÷èñëåíèÿ òàì,
class x (* ... *);
void f(int x) (* class x a; // ... *)
Åñëè èìÿ êëàññà èëè ïåðå÷èñëåíèÿ ðàíåå îïèñàíî íå áûëî, ñëîæíûé_ñïåöèôèêàòîð_òèïà ðàáîòàåò

8.3 Îïèñàòåëè
Ñïèñîê_îïèñàòåëåé, ïîÿâëÿþùèéñÿ â îïèñàíèè, åñòü ðàçäëåííàÿ çàïÿòûìè ïîñëåäîâàòåëüíîñòü îïè
ñïèñîê_îïèñàòåëåé: èíèö_îïèñàòåëü èíèö_îïèñàòåëü , ñïèñîê_îïèñàòåëåé
èíèö_îïèñàòåëü:
îïèñàòåëü èíèöèàëèçàòîð opt
Èíèöèàëèçàòîðû îáñóæäàþòñÿ â #8.6. Ñïåöèôèêàòîð â îïèñíèè óêàçûâàåò òèï è êëàññ ïàìÿòè îáúå
îïèñàòåëü: îï_èìÿ ( îïèñàòåëü ) * const opt îïèñàòåëü amp; const opt îïèñàòåëü îïèñàòåëü (
îï-èìÿ: ïðîñòîå_îï_èìÿ typedef-èìÿ :: ïðîñòîå_îï_èìÿ
ïðîñòîå_îï_èìÿ: èäåíòèôèêàòîð typedef-èìÿ ~ typedef-èìÿ èìÿ_ôóíêöèè_îïåðàöèè èìÿ_ôóíêöèè_ïð
Ãðóïïèðîâêà òà æå, ÷òî è â âûðàæåíèÿõ.

8.4 Ñìûñë îïèñàòåëåé


Êàæäûé îïèñàòåëü ñ÷èòàåòñÿ óòâåðæäåíèåì òîãî, ÷òî åñëè â âûðàæåíèè âîçíèêàåò êîíñòðóêöèÿ, è
Åñëè â êà÷åñòâå îïèñàòåëÿ âîçíèêàåò íè÷åì íå ñíàáæåííûé èäåíòèôèêàòîð, òî îí èìååò òèï, óêà
Îïèñàòåëü â ñêîáêàõ ýêâèâàëåíòåí îïèñàòåëþ áåç ñêîáîê, íî ñâÿçêó ñëîæíûõ îïèñàòåëåé ñêîáêè
Òåïåðü ïðåäñòàâèì ñåáå îïèñàíèå
T D1
ãäå T ñïåöèôèêàòîð òèïà (êàê int è ò.ä.), à D1 îïñàòåëü. Äîïóñòèì, ÷òî ýòî îïèñàíèå çàñ
*D
òî òèï ñîäåðæàùåãîñÿ èäåíòèôèêàòîðà åñòü «...óêàçàòåëü íà T.»
Åñëè D1 èìååò âèä
* const D
òî òèï ñîäåðæàùåãîñÿ èäåíòèôèêàòîðà åñòü «... êîíñòàííûé óêàçàòåëü íà T», òî åñòü, òîãî æå
Åñëè D1 èìååò âèä
amp;D
èëè
amp; const D
òî òèï ñîäåðæàùåãîñÿ èäåíòèôèêàòîðà åñòü «... ññûëêà íà T.» Ïîñêîëüêó ññûëêà ïî îïðåäåëåíèþ
Åñëè D1 èìååò âèä
D (ñïèñîê_îïèñàíèé_ïàðàìåòðîâ)
òî ñîäåðæàùèéñÿ èäåíòèôèêàòîð èìååò òèï «... ôóíêöèÿ, ïðèíèìàþùàÿ ïàðàìåòð òèïà ñïèñîê_îïèñ
ñïèñîê_îïèñàíèé_ïàðàìåòðîâ: ñïèñîê_îïèñàíèé_ïàðàì opt ... opt
ñïèñîê_îïèñàíèé_ïàðàì: ñïèñîê_îïèñàíèé_ïàðàì , îïèñàíèå_ïàðàìåòðà îïèñàíèå_ïàðàìåòðà
îïèñàíèå_ïàðàìåòðà: ñïåöèôèêàòîðû_îïèñàíèÿ îïèñàòåëü ñïåöèôèêàòîðû_îïèñàíèÿ îïèñàòåëü = âûð
Åñëè ñïèñîê_îïèñàíèé_ïàðàìåòðîâ çàêàí÷èâàåòñÿ ìíîãîòî÷åì, òî î ÷èñëå ïàðàìåòðîâ èçâåñòíî ëè
Ñïèñîê_îïèñàíèé_ïàðàìåòðîâ èñïîëüçóåòñÿ äëÿ ïðîâåðêè è ïðåîáðàçîâàíèÿ ôàêòè÷åñêèõ ïàðàìåòðî
Ïî æåëàíèþ ìîæíî çàäàòü èäåíòèôèêàòîð êàê èìÿ ïàðàìåòðà. Åñëè îí ïðèñóòñòâóåò â îïèñàíèè ôó
Åñëè D1 èìååò âèä
D[ êîíñòàíòíîå_âûðàæåíèå ]
èëè
D[]
òî òèï ñîäåðæàùåãîñÿ èäåíòèôèêàòîðà åñòü «... ìàññèâ îáúåêòîâ òèïà T».  ïåðâîì ñëó÷àå êîíñ
Ìàññèâ ìîæåò áûòü ïîñòðîåí èç îäíîãî èç îñíîâíûõ òèïîâ, èç óêàçàòåëåé, èç ñòðóêòóðû èëè îáú
Íå âñå âîçìîæíîñòè, êîòîðûå ïîçâîëÿåò ïðèâåäåííûé âûøå ñèíòàêñèñ, äîïóñòèìû. Îãðàíè÷åíèÿ ñë

8.4.1 Ïðèìåðû
Îïèñàíèå
int i; int *pi; int f (); int *fpi (); int (*pif) ();
îïèñûâàåò öåëîå i, óêàçàòåëü pi íà öåëîå, ôóíêöèþ f, âîçâðàùàþùóþ öåëîå, ôóíêöèþ fpi , âîçâ
Îïèñàíèå
const a = 10, *pc = amp;a, *const cpc = pc; int b, *const cp = amp;b;
îïèñûâàåò a: öåëóþ êîíñòàíòó, pc: óêàçàòåëü íà öåëóþ êîíñòàíòó, cpc: êîíñòàíòíûé óêàçàòåëü
a = 1; a++; *pc = 2; cp = amp;a; cpc++;
Ïðèìåðû äîïóñòèìûõ âûðàæåíèé:
b = a; *cp = a; pc++; pc = cpc; Îïèñàíèå
fseek (FILE*,long,int);
îïèñûâàåò ôóíêöèþ, ïîëó÷àþùóþ òðè ïàðàìåòðà óêàçàííûõ òèïîâ. Ïîñêîëüêó òèï âîçâðàùàåìîãî çí
point (int = 0,int = 0);
îïèñûâàåò ôóíêöèþ, êîòîðàÿ ìîæåò âûçûâàòüñÿ áåç ïàðàìåðîâ, ñ îäíèì èëè ñ äâóìÿ ïàðàìåòðàìè
point (1,2); point (1); point ();
Îïèñàíèå
printf (char* ... );
îïèñûâàåò ôóíêöèþ, êîòîðàÿ ìîæåò âûçûâàòüñÿ ñ ðàçëè÷íûìè ÷èñëîì è òèïàìè ïàðàìåòðîâ. Íàïðèì
printf («hello, world»); printf («a=%d b=%d»,a,b);
Îäíàêî, âñåãäà åå ïåðâûì ïàðàìåòðîì äîëæåí áûòü char*.
Îïèñàíèå
float fa[17], *afp[17];
îïèñûâàåò ìàññèâ ÷èñåë ñ ïëàâàþùåé òî÷êîé è ìàññèâ óêçàòåëåé íà ÷èñëà ñ ïëàâàþùåé òî÷êîé. È
static int x3d[3][5][7];
îïèñûâàåò ìàññèâ öåëûõ, ðàçìåðîì 3x6x7. Ñîâñåì ïîäðîáíî: x3d ÿâëÿåòñÿ ìàññèâîì èç òðåõ ýëåì

8.4.2 Ìàññèâû, Óêàçàòåëè è Èíäåêñèðîâàíèå


Âñÿêèé ðàç, êîãäà â âûðàæåíèè ïîÿâëÿåòñÿ èäåíòèôèêàòîð òèïà ìàññèâà, îí ïðåîáðàçóåòñÿ â óêà
Ýòî ïðàâèëî ñîîáðàçíûì îáðàçîì ïðèìåíÿåòñÿ â ñëó÷àå ìíãîìåðíîãî ìàññèâà. Åñëè E ÿâëÿåòñÿ n-
Ðàññìîòðèì, íàïðèìåð,
int x[3][5];
Çäåñü x ìàññèâ öåëûõ ðàçìåðîì 3*5. Êîãäà x âîçíèêàåò â âûðàæåíèè, îí ïðåîáðàçóåòñÿ â óêàç
Èìåííî èç âñåãî ýòîãî ïðîèñòåêàåò òî, ÷òî ìàññèâû â Ñ++ õðàíÿòñÿ ñòðîêîîáðàçíî (áûñòðåå âñå

8.5 Îïèñàíèÿ Êëàññîâ


Êëàññ åñòü òèï. Åãî èìÿ ñòàíîâèòñÿ typedef-èìÿ (ñì. #8.8), êîòîðîå ìîæåò áûòü èñïîëüçîâàíî
ñïåöèôèêàòîð_êëàññà: çàãîëîâîê_êëàññà (* ñïèñîê_÷ëåíîâ opt *) çàãîëîâîê_êëàññà (* ñïèñîê_÷ë
çàãîëîâîê_êëàññà: ñîñò èäåíòèôèêàòîð opt ñîñò èäåíòèôèêàòîð opt : public opt typedef-èìÿ
ñîñò: class struct union
Îáúåêòû êëàññîâ ìîãóò ïðèñâàèâàòüñÿ, ïåðåäàâàòüñÿ êàê ïàðàìåòðû è âîçâðàùàòüñÿ ôóíêöèÿìè (ç
Ñòðóêòóðà ÿâëÿåòñÿ êëàññîì, âñå ÷ëåíû êîòîðîãî îáùèå, ñì. #8.5.9. Îáúåäèíåíèå ÿâëÿåòñÿ ñòðó
ñïèñîê_÷ëåíîâ: îïèñàíèå_÷ëåíà ñïèñîê_÷ëåíîâ opt îïèñàíèå_÷ëåíà: ñïåöèôèêàòîðû_îïèñàíèÿ opt
×ëåíû, ÿâëÿþùèåñÿ êëàññîâûìè îáúåêòàìè, äîëæíû áûòü îáåêòàìè ïðåäâàðèòåëüíî îïèñàííûõ êëàññ
struct tnode (* char tword[20]; int count; tnode *left; tnode *right; *);
ñîäåðæàùåé ìàññèâ èç 20 ñèìâîëîâ, öåëîå è äâà óêàçàòåëÿ íà òàêèå æå ñòðóêòóðû. Åñëè áûëî äà
tnode s, *sp
îïèñûâàåò s êàê ñòðóêòóðó äàííîãî ñîðòà è sp êàê óêàçàòåëü íà ñòðóêòóðó äàííîãî ñîðòà. Ïðè
sp-»count
ññûëàåòñÿ íà ïîëå count ñòðóêòóðû, íà êîòîðóþ óêàçûâàåò sp;
s.left
ññûëàåòñÿ íà óêàçàòåëü ëåâîãî ïîääåðâà ñòðóêòóðû s; à
s.right-»tword[0]
ññûëàåòñÿ íà ïåðâûé ñèìâîë ÷ëåíà tword ïðàâîãî ïîääåðâà ñòðêòóðû s.

8.5.1 Ñòàòè÷åñêèå ×ëåíû


×ëåí äàííûå êëàññà ìîæåò áûòü static; ÷ëåíû ôóíêöèè íå ìîãóò. ×ëåíû íå ìîãóò áûòü auto, reg

8.5.2 Ôóíêöèè ×ëåíû


Ôóíêöèÿ, îïèñàííàÿ êàê ÷ëåí, (áåç ñïåöèôèêàòîðà friend (#8.5.10)) íàçûâàåòñÿ ôóíêöèåé ÷ëåíî
struct tnode (* char tword[20]; int count; tnode *left; tnode *right; void set (
char* w,tnode* l,tnode* r); *);
tnode n1, n2; n1.set («asdf», amp;n2,0); n2.set («ghjk»,0,0);
Îïðåäåëåíèå ôóíêöèè ÷ëåíà ðàññìàòðèâàåòñÿ êàê íàõîäÿùåñÿ â îáëàñòè âèäèìîñòè åå êëàññà. Ýòî
Íàïðèìåð:
void tnode.set (char* w,tnode* l,tnode* r) (* count = strlen (w); if (sizeof (tw
ord)«=count) error ( tnode string too long ); strcpy (tword,w); left = l; right = r; *
)
Çàïèñü tnode.set îïðåäåëÿåò òî, ÷òî ôóíêöèÿ set ÿâëÿåòñÿ ÷ëåíîì êëàññà tnode è ïðèíàäëåæèò
 ôóíêöèè ÷ëåíå êëþ÷åâîå ñëîâî this ÿâëÿåòñÿ óêàçàòåëåì íà îáúåêò, äëÿ êîòîðîãî âûçâàíà ôóí
Ôóíêöèÿ ÷ëåí ìîæåò áûòü îïðåäåëåíà (#10) â îïèñàíèè êëàññà, è â ýòîì ñëó÷àê îíà ÿâëÿåòñÿ in
int b; struct x (* int f () (* return b; *) int f () (* return b; *) int b; *);
îçíà÷àåò
int b; struct x (* int f (); int b; *); inline x::f () (* return b; *)
Ïðèìåíåíèå îïåðàöèè ïîëó÷åíèÿ àäðåñà ê ôóíêöèÿì ÷ëåíàì äîïóñòèìî. Îäíàêî, òèï ïàðàìåòðà ðåç

8.5.3 Ïðîèçâîäíûå Êëàññû


 êîíñòðóêöèè
ñîñò èäåíòèôèêàòîð : public opt typedef-èìÿ
typedef-èìÿ äîëæíî îçíà÷àòü ðàíåå îïèñàííûé êëàññ, íàçâàåìûé áàçîâûì êëàññîì äëÿ îïèñûâàåìî
áàçîâûé êëàññ (#6.7).
Äëÿ îáúåêòîâ êëàññà, ïðîèçâîäíîãî îò êëàññà, äëÿ êîòîðãî áûëà îïðåäåëåíà operator= (#8.5.11
Íàïðèìåð:
class base (* int a, b; *);
class derived : public base (* int b, c; *);
derived d;
d.a = 1; d.base::b = 2; d.b = 3; d.c = 4;
îñóùåñòâëÿåò ïðèñâàèâàíèå ÷åòûðåì ÷ëåíàì d.

8.5.4 Âèðòóàëüíûå Ôóíêöèè


Åñëè áàçîâûé êëàññ base ñîäåðæèò virtual (âèðòóàëüíóþ) (#8.1) ôóíêöèþ vf, à ïðîèçâîäíûé êëà
struct base (* virtual void vf (); void f (); *);
class derived : public base (* void vf (); void f (); *);
derived d; base* bp = amp;d; bp-»vf(); bp-»f();
Âûçîâû âûçûâàþò, ñîîòâåòñòâåííî, derived::vf è base::f äëÿ îáúåêòà êëàññà derived, èìåíîâàí
Âèðòóàëüíàÿ ôóíêöèÿ íå ìîæåò áûòü äðóãîì (friend) (#8.5. 10). Ôóíêöèÿ f â êëàññå, âûâåäåííî

8.5.5 Êîíñòðóêòîðû
Ôóíêöèÿ ÷ëåí ñ èìåíåì, ñîâïàäàþùèì ñ èìåíåì åå êëàññà, íàçûâàåòñÿ êîíñòðóêòîðîì. Åñëè êëàññ
Êîíñòðóêòîð íå ìîæåò áûòü virtual èëè friend.
Åñëè êëàññ èìååò áàçîâûé êëàññ èëè îáúåêòû ÷ëåíû ñ êîíòðóêòîðàìè, èõ êîíñòðóêòîðû âûçûâàþòñ
Îáúåêò êëàññà ñ êîíñòðóêòîðîì íå ìîæåò áûòü ÷ëåíîì îáåäèíåíèÿ.
Äëÿ êîíñòðóêòîðà íåëüçÿ çàäàòü âîçâðàùàåìîå çíà÷åíèå, êàê íåëüçÿ èñïîëüçîâàòü îïåðàòîð retu
Êîíñòðóêòîð ìîæåò ÿâíî ïðèìåíÿòüñÿ äëÿ ñîçäàíèÿ íîâûõ îáúåêòîâ åãî òèïà èñïîëüçóÿ ñèíòàêñèñ
typedef-èìÿ ( ñïèñîê_ïàðàìåòðîâ opt )
Íàïðèìåð,
complex zz = complex (1,2.3); cprint (complex (7.8,1.2));
Îáúåêòû, ñîçäàííûå òàêèì îáðàçîì, íå èìåþò èìåíè (åñëè òîëüêî êîíñòðóêòîð íå èñïîëüçîâàí êà

8.5.6 Ïðåîáðàçîâàíèÿ
Êîíñòðóêòîð, ïîëó÷àþùèé îäèí ïàðàìåòð, îïðåäåëÿåò ïðåîðàçîâàíèå èç òèïà ñâîåãî ïàðàìåòðà â
class X (* ... X (int); *); f (X arg) (* X a = 1; // a = X (1) a = 2; // a = X (
2) f (3); // f (X (3)) *)
Åñëè íè îäèí êîíñòðóêòîð äëÿ êëàññà X íå ïîëó÷àåò ïðèâàèâàåìûé òèï, òî íå äåëàåòñÿ íèêàêèõ
operator òèï
çàäàåò ïðåîáðàçîâàíèå èç X â òèï. Òèï íå ìîæåò ñîäåðæàòü îïèñàíèÿ [] «âåêòîð èç» èëè () «ôó
class X (* // ... operator int(); *);
X a; int i = int(a); i = (int)a; i = a;
Âî âñåõ òðåõ ñëó÷àÿõ çíà÷åíå áóäåò ïðåîáðàçîâûâàòüñÿ ôóíêöèåé X::operator int(). Ïðèìåíåíèå
X a, b; // ... int i = (a) ? 1+a : 0; int j = (a amp; amp;b) ? a+b : i;

8.5.7 Äåñòðóêòîðû
Ôóíêöèÿ ÷ëåí êëàññà cl ñ èìåíåì ~cl íàçûâàåòñÿ äåñòðóòîðîì. Äåñòðóêòîð íå âîçâðàùàåò íèêàêî
Äåñòðóêòîð äëÿ áàçîâîãî êëàññà âûïîëíÿåòñÿ ïîñëå äåñðóêòîðà ïðîèçâîäíîãî îò íåãî êëàññà. Äå
Îáúåêò êëàññà ñ äåñòðóêòîðîì íå ìîæåò áûòü ÷ëåíîì îáåäèíåíèÿ.

8.5.8 Ñâîáîäíàÿ Ïàìÿòü


Êîãäà ñ ïîìîùüþ îïåðàöèè new ñîçäàåòñÿ êëàññîâûé îáúåêò, òî äëÿ ïîëó÷åíèÿ íåîáõîäèìîé ïàìÿò
class cl (* int v[10]; cl () (* this = my_own_allocator (sizeof (cl)); *) ~cl ()
(* my_own_deallocator (this); this = 0; *) *) Íà âõîäå â êîíñòðóêòîð this ÿâëÿååòñÿ íå-íóë
êîíñòðóêòîð áàçîâîãî êëàññà îñóùåñòâëÿåò ïðèñâàèâàíèå this, òî íîâîå çíà÷åíèå òàêæå áóäåò è
Ïðè óíè÷òîæåíèè âåêòîðà îáúåêòîâ êëàññà ñ äåñòðóêòîðîì íåîáõîäèìî óêàçûâàòü ÷èñëî ýëåìåíòîâ
class X (* ... ~X(); *); X* p = new X [size]; delete[size] p;

8.5.9 Âèäèìîñòü Èìåí ×ëåíîâ


×ëåíû êëàññà, îïèñàííûå ñ êëþ÷åâûì ñëîâîì class, ÿâëÿþñÿ çàêðûòûìè, òî åñòü, èõ èìåíà ìîãóò
Åñëè ïðîèçâîäíûé êëàññ îïèñàí êàê struct èëè åñëè ïåðåä èìåíåì áàçîâîãî êëàññà â îïèñàíèè ï
typedef-èìÿ :: èäåíòèôèêàòîð ;
â êîòîðîì typedef-èìÿ îáîçíà÷àåò áàçîâûé êëàññ, à èäåòèôèêàòîð åñòü èìÿ ÷ëåíà áàçîâîãî êëàñ
class base (* int a; public: int b, c; int bf(); *);
class derived : base (* int d; public: base::c; int e; int df(); *);
int ef(derived amp;);
Âíåøíÿÿ ôóíêöèÿ ef ìîæåò èñïîëüçîâàòü òîëüêî èìåíà c, e è df. ßâëÿÿñü ÷ëåíîì ïðîèçâîäíîãî d

8.5.10 Äðóçüÿ
Äðóã êëàññà ýòî ôóíêöèÿ íå-÷ëåí, êîòîðàÿ ìîæåò èñïîëçîâàòü èìåíà çàêðûòûõ ÷ëåíîâ. Äðóã íå
class private (* int a; friend void friend_set(private*, int); public: void memb
er_set(int); *);
void friend_set (private* p, int i) (* p-»a = i; *)
void private::member_set (int i) (* a = i; *)
private obj; friend_set ( amp;obj,10); obj.member_set (10);
Åñëè îïèñàíèå friend îòíîñòèñÿ ê ïåðåãðóæåííîìó èìåíè èëè îïåðàöèè, òî äðóãîì ñòàíîâèòñÿ òî
class cl2 (* friend char* cl1::foo(int); // ... *);
Âñå ôóíêöèè êëàññà cl1 ìîãóò áûòü ñäåëàíû äðóçüÿìè êëàñà cl2 ñ ïîìîùüþ îäíîãî îïèñàíèÿ
class cl2 (* friend class cl1 ; // ... *);
Ôóíêöèÿ ÷ëåí, îïðåäåëåííàÿ (#10) â îïèñàíèè êëàññà, ÿëÿåòñÿ inline.

8.5.11 Ôóíêöèÿ Îïåðàöèÿ


Áîëüøèíñòâî îïåðàöèé ìîãóò áûòü ïåðåãðóæåíû ñ òåì, ÷òîáû îíè ìîãëè ïîëó÷àòü â êà÷åñòâå îïåð
èìÿ_ôóíêöèè_îïåðàöèè: operator îïåðàöèÿ
îïåðàöèÿ: îäíà èç new delete + * / % ^ amp; ! ~ ! = « » += -= *= /= %= ^= amp;= != « »
Ïîñëåäíèå äâå îïåðàöèè ýòî âûçîâ ôóíêöèè è èíäåêñèðâàíèå. Ôóíêöèÿ îïåðàöèÿ (çà èñêëþ÷åíèå
Ñòðóêòóðà åñòü êëàññ, âñå ÷ëåíû êîòîðîãî îáùèå. Ýòî çí÷èò, ÷òî
struct s (* ... *); ýêâèâàëåíòíî
class s (* public: ... *);
Ñòðóêòóðà ìîæåò èìåòü ôóíêöèè ÷ëåíû (âêëþ÷àÿ êîíñòðóêòðû è äåñòðóêòîðû). Áàçîâé êëàññ ïðîèç
struct s : d (* ... *);
ýêâèâîëåíòíî
class s : public b (* public: ... *);

8.5.13 Îáúåäèíåíèÿ
Îáúåäèíåíèå ìîæíî ñ÷èòàòü ñòðóêòóðîé, âñå îáúåêòû ÷ëåíû êîòîðîé íà÷èíàþòñÿ ñî ñìåùåíèÿ 0, è
Îáúåäèíåíèå âèäà
union (* ñïèñîê_÷ëåíîâ *);
íàçûâàåòñÿ áåçûìÿííûì îáúåäèíåíèåì; îíî îïðåäåëÿåò íåìåíîâàííûé îáúåêò. Èìåíà ÷ëåíîâ áåçûìÿ
union (* int a; char* p; *); a = 1; // ... p = «asdf»;
Çäåñü a è p èñïîëüçóþòñÿ êàê ïðîñòûå ïåðåìåííûå (íå-÷ëíû), íî òàê êàê îíè ÿâëÿþòñÿ ÷ëåíàìè

8.5.14 Ïîëÿ Áèò


Îïèñàòåëü_÷ëåíà âèäà
èäåíòèôèêàòîð opt : êîíñòàíòíîå_âûðàæåíèå
îïðåäåëÿåò ïîëå; åãî äëèíà îòäåëÿåòñÿ îò èìåíè ïîëÿ äâåòî÷èåì. Ïîëÿ óïàêîâûâàþòñÿ â ìàøèííû
Íåèìåíîâàííûå ïîëÿ ïîëåçíû ïðè çàïîëíåíèè äëÿ ñîãëàñîâíèÿ âíåøíå ïðåäïèñàííûõ ðàçìåùåíèé (ô
Ïîëÿ íå ìîãóò áûòü ÷ëåíàìè îáúåäèíåíèÿ.

8.5.15 Âëîæåííûå Êëàññû


Êëàññ ìîæåò áûòü îïèñàí âíóòðè äðóãîãî êëàññà. Ýòî, îíàêî, ëèøü ñîãëàøåíèå î çàïèñè, ïîñêîë
int x;
class enclose (* // îõâàòûâàþùèé int x; class inner (* // âíóòðåííèé int y; void f(int); *)
inner a; void inner::f(int i) (* x = i; *) // ïðèñâàèâàåò ::x int enclose::g(inner* p) (* r
) // îøèáêà
8.6 Èíèöèàëèçàöèÿ
Îïèñàòåëü ìîæåò çàäàâàòü íà÷àëüíîå çíà÷åíèå îïèñûâàåìîãî èäåíòèôèêàòîðà.
èíèöèàëèçàòîð: = âûðàæåíèå = (* ñïèñîê_èíèöèàëèçàòîðîâ , opt *) ( ñïèñîê_âûðàæåíèé ) ñïèñîê
Âñå âûðàæåíèÿ â èíèöèàëèçàòîðå ñòàòè÷åñêîé èëè âíåøíåé ïåðåìåííîé äîëæíû áûòü êîíñòàíòíûìè
Ãàðàíòèðóåòñÿ, ÷òî íåèíèöèàëèçèðîâàííûå ñòàòè÷åñêèå è âíåøíèå ïåðåìåííûå ïîëó÷àþò â êà÷åñòâ
 *  àíãëèéñêîì «garbage», îçíà÷àþùåå çàòåðòîå ìåñòî [ïàìÿòè], ò.å. åñëè ïåðåìåííàÿ öåëà
Êîãäà èíèöèàëèçàòîð ïðèìåíÿåòñÿ ê ñêàëÿðó (óêàçàòåëü èëè îáúåêò àðèôìåòè÷åñêîãî òèïà), îí ñ
Çàìåòüòå, ÷òî ïîñêîëüêó () íå ÿâëÿåòñÿ èíèöèàëèçàòîðîì, òî X a(); ÿâëÿåòñÿ íå îïèñàíèåì îáú

8.6.1 Ñïèñîê Èíèöèàëèçàòîðîâ


Êîãäà îïèñàííàÿ ïåðåìåííàÿ ÿâëÿåòñÿ ñîñòàâíîé (êëàññ èëè ìàññèâ), òî èíèöèàëèçàòîð ìîæåò ñî
Ôèãóðíûå ñêîáêè ìîãóò îïóñêàòüñÿ ñëåäóþùèì îáðàçîì. Åñëè èíèöèàëèçàòîð íà÷èíàåòñÿ ñ ëåâîé ô
Íàïðèìåð,
int x[] = (* 1, 3, 5 *);
îïèñûâàåò è èíèöèàëèçèðóåò x êàê îäíîìåðíûé ìàññèâ, èìþùèé òðè ýëåìåíòà, ïîñêîëüêó ðàçìåð í
float y[4][3] = (* (* 1, 3, 5 *), (* 2, 4, 6 *), (* 3, 5, 7 *) *);
ÿâëÿåòñÿ ïîëíîñòüþ ñíàáæåííîé êâàäðàòíûìè ñêîáêàìè èíöèàëèçàöèåé: 1,3 è 5 èíèöèàëèçèðóþò ïå
float y[4][3] = (* 1, 3, 5, 2, 4, 6, 3, 5, 7 *);
Èíèöèàëèçàòîð äëÿ y íà÷èíàåòñÿ ñ ëåâîé ôèãóðíîé ñêîáêè, íî íå íà÷èíàåòñÿ ñ íåå èíèöèàëèçàòî
float y[4][3] = (* (* 1 *), (* 2 *), (* 3 *), (* 4 *) *);
èíèöèàëèçèðóåò ïåðâûé ñòîëáåö y (ðàññìàòðèâàåìîãî êàê äâóìåðíûé ìàññèâ) è îñòàâëÿåò îñòàëüí

8.6.2 Îáúåêòû Êëàññîâ


Îáúåêò ñ çàêðûòûìè ÷ëåíàìè íå ìîæåò áûòü èíèöèàëèçîâàí ñïèñêîì èíèöèàëèçàòîðîâ; ýòî æå îòíî
float re; float im; complex (float r,float i = 0) (* re=r; im=i; *) *);
complex zz1(1,0); complex zz2(1); complex* zp1 = new complex (1,0); complex* zp1
= new complex (1);
Îáúåêòû êëàññà ìîãóò òàêæå èíèöèàëèçèðîâàòüñÿ ñ ïîìîùüþ ÿâíîãî èñïîëüçîâàíèÿ îïåðàöèè =. Íà
complex zz3 = complex (1,0); complex zz4 = complex (1); complex zz5 = 1; complex
zz6 = zz3;
Åñëè åñòü êîíñòðóêòîð, ïîëó÷àþùèé ññûëêó íà îáúåêò ñâîãî ñîáñòâåííîãî êëàññà, òî îí áóäåò â
Îáúåêò ìîæåò áûòü ÷ëåíîì ñîñòàâíîãî îáúåêòà òîëüêî (1) åñëè êëàññ îáúåêòà íå èìååò êîíñòðóê
Êîíñòðóêòîðû äëÿ íåëîêàëüíûõ ñòàòè÷åñêèõ îáúåêòîâ âûçâàþòñÿ â ïîðÿäêå èõ ïîÿâëåíèÿ â ôàéëå;

8.6.3 Ññûëêè
Êîãäà ïåðåìåííàÿ îïèñàíà êàê T amp;, òî åñòü «ññûëêà íà òèï T», îíà äîëæíà áûòü èíèöèàëèçèð
int i; int amp; r = i; r = 1; // çíà÷åíèå i ñòàíîâèòñÿ 1 int* p = amp;r; // p óêàçûâàåò íà
Çíà÷åíèå ññûëêè íå ìîæåò áûòü èçìåíåíî ïîñëå èíèöèàëèçöèè. Çàìåòüòå, ÷òî îáðàáîòêà èíèöèàëè
double amp; rr = 1;
äîïóñòèìî, è rr áóäåò óêàçûâàòü íà îáúåêò òèïà double, ñîäåðæàùèé çíà÷åíèå 1.0.
Çàìåòüòå, ÷òî ññûëêà íà êëàññ B ìîæåò áûòü èíèöèàëèçèðâàíà îáúåêòîì êëàññà D ïðè óñëîâèè, ÷
Ññûëêè îñîáåííî ïîëåçíû â êà÷åñòâå òèïîâ ïàðàìåòðîâ. Íàïðèìåð:
struct B (* ... *); struct D : B (* ... *); int f(B amp;); D a; f(a);

8.6.4 Ìàññèâû Ñèìâîëîâ


Ìàññèâ char ìîæíî èíèöèàëèçèðîâàòü ñòðîêîé. Ïîñëåäîâòåëüíûå ñèìâîëû ñòðîêè èíèöèàëèçèðóþò ÷
char msg[] = «Syntax error on line %d\n»;
äåìîíñòðèðóåò ìàññèâ ñèìâîëîâ, ÷ëåíû êîòîðîãî èíèöèàëçèðîâàíû ñòðîêîé. Îáðàòèòå âíèìàíèå, ÷

8.7 Èìåíà Òèïîâ


Èíîãäà (äëÿ íåÿâíîãî çàäàíèÿ ïðåîáðàçîâàíèÿ òèïîâ è â êà÷åñòâå ïàðàìåòðà sizeof èëè new) íó
èìÿ_òèïà: ñïåöèôèêàòîð_òèïà àáñòðàêòíûé_îïèñàòåëü
àáñòðàêòíûé_îïèñàòåëü: ïóñòîé * àáñòðàêòíûé_îïèñàòåëü àáñòðàêòíûé_îïèñàòåëü ( ñïèñîêî_ïèñàò
Âîçìîæíî åäèíñòâåííûì îáðàçîì èäåíòèôèöèðîâàòü ïîëîæåíèå â àáñòðàêòíîì_îïèñàòåëå, ãäå äîëæå
int int * int *[3] int (*)[3] int *() int (*)()
èìåíóþò, ñîîòâåòñâåííî, òèïû «öåëîå», «óêàçàòåëü íà öëîå», «ìàññèâ èç 3 óêàçàòåëåé íà öåëûå

8.8 Typedef Îïðåäåëåíèå Òèïà


Îïèñàíèÿ, ñîäåðæàùèå ñïåöèôèêàòîð_îïèñàíèÿ typedef, îïðåäåëÿþò èäåíòèôèêàòîðû, êîòîðû ïîçäí
typedef-èìÿ: èäåíòèôèêàòîð
Âíóòðè îáëàñòè âèäèìîñòè îïèñàíèÿ, ñîäåðæàùåãî typedef, êàæäûé èäåíòèôèêàòîð, âîçíèêàþùèé ê
typedef int MILES, *KLICKSP; struct complex (* double re, im; *);
êàæäàÿ èç êîíñòðóêöèé
MILES distance; extern KLICKSP metricp; complex z, *zp;
ÿâëÿåòñÿ äîïóñòèìûì îïèñàíèåì; distance èìååò òèï int, metricp èìååò òèï «óêàçàòåëü íà int»
typedef ââîäèò íå íîâûå òèïû, íî òîëüêî ñèíîíèìû äëÿ òïîâ, êîòîðûå ìîãëè áû áûòü îïðåäåëåíû
Íî îïèñàíèå êëàññà ââîäèò íîâûé òèï. Íàïðèìåð:
struct X (* int a; *); struct Y (* int a; *); X a1; Y a2; int a3;
îïèñûâàåò òðè ïåðåìåííûõ òðåõ ðàçëè÷íûõ òèïîâ.
Îïèñàíèå âèäà
îïèñàíèå_èìåíè: ñîñò èäåíòèôèêàòîð ; enum èäåíòèôèêàòîð ;
ñïåöèôèöèðóåò, ÷òî èäåíòèôèêàòîð ÿâëÿåòñÿ èìåíåì íåêîòðîãî (âîçìîæíî, åùå íå îïðåäåëåííîãî)
class vector;
class matrix (* // ... friend vector operator*(matrix amp;, vector amp;); *);
class vector (* // ... friend matrix operator*(matrix amp;, vector amp;); *);

8.9 Ïåðåãðóæåííûå Èìåíà Ôóíêöèé


 òåõ ñëó÷àÿõ, êîãäà äëÿ îäíîãî èìåíè îïðåäåëåíî íåêîëüêî (ðàçëè÷íûõ) îïèñàíèé ôóíêöèé, ýòî
Ïîèñê òîãî, êàêóþ ôóíêöèþ âûçâàòü, îñóùåñòâëÿåòñÿ â òðè îòäåëüíûõ øàãà:
Èñêàòü òî÷íî ñîîòâåòñòâóþùóþ è èñïîëüçîâàòü, åñëè íàéäíà.
Èñêàòü ñîîòâåòñòâóþùóþ ñ èñïîëüçîâàíèåì ñòàíäàðòíûõ ïðîáðàçîâàíèé (#6.6-8) è èñïîëüçîâàòü ë
Èñêàòü ñîîòâåòñòâóþùóþ ñ èñïîëüçîâàíèåì îïðåäåëåííûõ ïîëüçîâàòåëåì ïðåîáðàçîâàíèé (#6.5.6).
Íîëü, char èëè short ñ÷èòàþòñÿ òî÷íî ñîîòâåòñòâóþùèìè ôîðìàëüíîìó ïàðàìåòðó òèïà int. Float
Íàä ïàðàìåòðîì ïåðåãðóæåííîé ôóíêöèè âûïîëíÿþòñÿ òîëüêî ñëåäóþùå ïðåîáðàçîâàíèÿ: int â long
Äëÿ òîãî, ÷òîáû ïåðåãðóçèòü èìÿ ôóíêöèè íå ÷ëåíà è íå ôóíêöèè operator, ëþáîìó îïèñàíèþ ôóí
overload abs; double abs(double); int abs(int);
abs(1); // âûçûâàåòñÿ abs(int); abs(1.0); // âûçûâàåòñÿ abs(double);
Íàïðèìåð:
class X (* ... X (int); *); class Y (* ... Y (int); *);
class Z (* ... Z (char*); *);
overload int f (X), f (Y); overload int g (X), g (Z);
f (1); // íåäîïóñòèìî: f(X(1)) èëè f(Y(1)) g (1); // g(X(1)) g («asdf»); // g(Z(«asdf»))
Îïåðàöèÿ âçÿòèÿ àäðåñà amp; ìîæåò ïðèìåíÿòüñÿ ê ïåðåãðóæåíîìó èìåíè òîëüêî â ïðèñâàèâàíèè è
int operator=(matrix amp;, matrix amp;); int operator=(vector amp;, vector amp;)
; int (*pfm)(matrix amp;, matrix amp;) = amp;operator=; int (*pfv)(vector amp;,
vector amp;) = amp;operator=; int (*pfx)(...) = amp;operator=;

8.10 Îïèñàíèÿ Ïåðå÷èñëåíèé


Ïåðå÷èñëåíèÿ ÿâëÿþòñÿ òèïàìè int ñ èìåíîâàííûìè êîíñòàòàìè.
enum_ñïåöèôèêàòîð: enum èäåíòèôèêàòîð opt (* enum_ñïèñîê *)
enum_ñïèñîê: ïåðå÷èñëèòåëü enum_ñïèñîê , ïåðå÷èñëèòåëü
ïåðå÷èñëèòåëü: èäåíòèôèêàòîð èäåíòèôèêàòîð = êîíñòàíòíîå_âûðàæåíèå
Èäåíòèôèêàòîðû â enum-ñïèñêå îïèñàíû êàê êîíñòàíòû è ìãóò ïîÿâëÿòüñÿ âî âñåõ ìåñòàõ, ãäå òð
Èìåíà ïåðå÷èñëèòåëåé äîëæíû áûòü îòëè÷íûìè îò èìåí îáû÷íûõ ïåðåìåííûõ. Èìåíà ïåðå÷èñëèòåëåé
Ðîëü èäåíòèôèêàòîðà â ñïåöèôèêàòîðå ïåðå÷èñëåíèÿ enum_ñïåöèôèêàòîð ïîëíîñòüþ àíàëîãè÷íà ðîë
enum color (* red, yellow, green=20, blue *); color col = red;
color *cp = amp;col; if (*cp == blue) // ...
äåëàåò color èìåíåì òèïà, îïèñûâàþùåãî ðàçëè÷íûå öâåòà, è çàòåì îïèñûâàåò col êàê îáúåêò ýò

8.11 Îïèñàíèå Asm


Îïèñàíèå Asm èìååò âèä
asm ( ñòðîêà );
Ñìûñë îïèñàíèÿ asm íåîïðåäåëåí. Îáû÷íî îíî èñïîëüçóåòñÿ äëÿ ïåðåäà÷è èíôîðìàöèè àññåìáëåðó
9. Îïåðàòîðû
Îïåðàòîðû âûïîëíÿþòñÿ ïîñëåäîâàòåëüíî âî âñåõ ñëó÷àÿõ êðîìå îñîáî îãîâîðåííûõ.

9.1 Îïåðàòîð Âûðàæåíèå


Áîëüøèíñòâî îïåðàòîðîâ ÿâëÿåòñÿ îïåðàòîðàìè âûðàæåíèå, êîòîðûå èìåþò âèä
âûðàæåíèå ;
Îáû÷íî îïåðàòîðû âûðàæåíèå ÿâëÿþòñÿ ïðèñâàèâàíèÿìè è âçîâàìè ôóíêöèé.

9.2 Ñîñòàâíîé Îïåðàòîð, èëè Áëîê


Ñîñòàâíîé îïåðàòîð (íàçûâàåìûé òàêæå «áëîê», ÷òî ýêâèâëåíòíî) äàåò âîçìîæíîñòü èñïîëüçîâàòü
ñîñòàâíîé_îïåðàòîð: (* ñïèñîê_îïåðàòîðîâ opt *)
ñïèñîê_îïåðàòîðîâ: îïåðàòîð îïåðàòîð ñïèñîê_îïåðàòîðîâ
Îáðàòèòå âíèìàíèå, ÷òî îïèñàíèå ýòî âàðèàíò îïåðàòîðà (#9.14).

9.3 Óñëîâíûé Îïåðàòîð


Åñòü äâà âèäà óñëîâíûõ îïåðàòîðîâ
if ( âûðàæåíèå ) îïåðàòîð if ( âûðàæåíèå ) îïåðàòîð else îïåðàòîð

Âûðàæåíèå äîëæíî áûòü àðèôìåòè÷åñêîãî èëè óêàçàòåëüíîãî òèïà èëè êëàññîâîãî òèïà, äëÿ êîòîð

9.4 Îïåðàòîð While


Îïåðàòîð while èìååò âèä
while ( âûðàæåíèå ) îïåðàòîð
Âûïîëíåíèå ïîäîïåðàòîðà ïîâòîðÿåòñÿ, ïîêà çíà÷åíèå âûðæåíèÿ îñòàåòñÿ íåíóëåâûì. Ïðîâåðêà âû

9.5 Îïåðàòîð Do
Îïåðàòîð do èìååò âèä
do îïåðàòîð while ( âûðàæåíèå ) ;
Âûïîëíåíèå ïîäîïåðàòîðà ïîâòîðÿåòñÿ äî òåõ ïîð, ïîêà çíà÷åíèå îñòàåòñÿ íå íóëåì. Ïðîâåðêà â

9.6 Îïåðàòîð For


Îïåðàòîð for èìååò âèä
for (îïåðàòîð_1 âûðàæåíèå_1 opt; âûðàæåíèå_2 opt) îïåðàòîð_2
Ýòîò îïåðàòîð ýêâèâàëåíòåí ñëåäóþùåìó:
îïåðàòîð_1 while ( âûðàæåíèå_1 ) (* îïåðàòîð_2 âûðàæåíèå_2 ; *)
çà èñêëþ÷åíèåì òîãî, ÷òî continue â îïåðàòîðå_2 áóäåò âûïîëíÿòü âûðàæåíèå_2 ïåðåä âûïîëíåíè

Êàæäîå èëè îáà âûðàæåíèÿ ìîãóò áûòü îïóùåíû. Îòñóòñòâèå âûðàæåíèÿ_1 äåëàåò ïîäðàçóìåâàåìîå

9.7 Îïåðàòîð Switch


Îïåðàòîð switch âûçûâàåò ïåðåäà÷ó óïðàâëåíèÿ íà îäèí èç íåñêîëüêèõ îïåðàòîðîâ â çàâèñèìîñòè
switch ( âûðàæåíèå ) îïåðàòîð
Âûðàæåíèå äîëæíî áûòü àðèôìåòè÷ñêîãî èëè óêàçàòåëüíîãî òèïà. Ëþáîé îïåðàòîð âíóòðè îïåðàòîð
case êîíñòàíòíîå_âûðàæåíèå :
ãäå êîíñòàíòíîå âûðàæåíèå äîëæíî èìåòü òîò æå òèï ÷òî è âûðàæåíèå-ïåðåêëþ÷àòåëü; ïðîèçâîäÿò
Òàêæå ìîæåò áûòü íå áîëåå ÷åì îäíà ìåòêà âèäà
default :
Êîãäà âûïîëíåí îïåðàòîð switch, ïðîâåäåíî âû÷èñëåíèå åãî âûðàæåíèÿ è ñðàâíåíèå åãî ñ êàæäîé
Ìåòêè case è default ñàìè ïî ñåáå íå èçìåíÿþò ïîòîê óðàâëåíèÿ, êîòîðûé ïîñëå çàäåðêè èäåò ä
Îáû÷íî çàâèñÿùèé îò switch îïåðàòîð ÿâëÿåòñÿ ñîñòàâíûì.  ãîëîâå ýòîãî îïåðàòîðà ìîãóò ñòîÿ

9.8 Îïåðàòîð Break


Îïåðàòîð
break ;
âûçûâàåò çàâåðøåíèå âûïîëíåíèÿ íàèìåíüøåãî îõâàòûâàþùåãî îïåðàòîðà while, do, for èëè switc
îïåðàòîð, ñëåäóþùèé çà çàâåðøåííûì.

9.9 Îïåðàòîð Continue


Îïåðàòîð
continue ;
âûçûâàåò ïåðåäà÷ó óïðàâëåíèÿ íà óïðàâëÿþùóþ ïðîäîëæåíèåì öèêëà ÷àñòü íàèìåíüøåãî îõâàòûâàþù
while (...) (* do (* for (...) (* ... ... ... contin: ; contin: ; contin: ; *) *
) while (...); *)
continue ýêâèâàëåíòíî goto contin. (Çà contin: èäåò ïóòîé îïåðàòîð, #9.13.)

9.10 Îïåðàòîð Return


Âîçâðàò èç ôóíêöèè â âûçûâàþùåóþ ïðîãðàììó îñóùåñòâëÿåñÿ ñ ïîìîùüþ îïåðàòîðà return, èìåþùå
return ; return âûðàæåíèå ;
Ïåðâûé ìîæåò èñïîëüçîâàòüñÿ òîëüêî â ôóíêöèÿõ, íå âîçâðàùàþùèõ çíà÷åíèÿ, ò.å. â ôóíêöèÿõ ñ

9.11 Îïåðàòîð Goto


Ìîæíî îñóùåñòâëÿòü áåçóñëîâíóþ ïåðåäà÷ó óïðàëåíèÿ ñ ïìîùüþ îïåðàòîðà
goto èäåíòèôèêàòîð ;
Èäåíòèôèêàòîð äîëæåí áûòü ìåòêîé (#9.12), ðàñïîëîæåííîé â òåêóùåé ôóíêöèè. Íåâîçìîæíî ïåðåä

9.12 Ïîìå÷åííûå Îïåðàòîðû


Ïåðåä ëþáûì îïåðàòîðîì ìîæåò ñòîÿòü ìåòêà, èìåþùèé âèä

èäåíòèôèêàòîð :
êîòîðàÿ ñëóæèò äëÿ îïèñàíèÿ èäåíòèôèêàòîðà êàê ìåòêè. Ìåòêà èñïîëüçóåòñÿ òîëüêî êàê îáúåêò

9.13 Ïóñòîé Îïåðàòîð


Ïóñòîé îïåðàòîð èìååò âèä
;
Ïóñòîé îïåðàòîð èñïîëüçóåòñÿ äëÿ ïîìåùåíèÿ ìåòêè íåïîðåäñòâåííî ïåðåä *) ñîñòàâíîãî îïåðàòî

9.14 Îïåðàòîð Îïèñàíèå


Îïåðàòîð îïèñàíèå èñïîëüçóåòñÿ äëÿ ââåäåíèÿ íîâîãî èäåòèôèêàòîðà â áëîêå; îí èìååò âèä
Îïåðàòîð_îïèñàíèå: îïèñàíèå
Åñëè ââåäåííûé îïèñàíèåì èäåíòèôèêàòîð áûë îïèñàí ðàíåå âî âíåøíåì áëîêå, âíåøíåå îïèñàíèå
Êàæäàÿ èíèöèàëèçàöèÿ auto è register ïåðåìåííûõ ïðîèçâäèòñÿ êàæäûé ðàç, êîãäà âûïîëíÿåòñÿ è
Ïðîãðàììà ñîñòîèò èç ïîñëåäîâàòåëüíîñòè îïèñàíèé. Êîä (òåêñò ïðîãðàììû) ôóíêöèè ìîæåò áûòü
îïðåäåëåíèå_ôóíêöèè: ñïåöèôèêàòîðû_îïèñàíèÿ opt îïèñàòåëü_ôóíêöèè èíèöèàëèçàòîð_áàçîâîãî op
Ñïåöèôèêàòîðû_îïèñàíèÿ register, auto, typedef íå ìîãóò èñïîëüçîâàòüñÿ âíóòðè îïèñàíèÿ êëàñ
îïèñàòåëü_ôóíêöèè:
îïèñàòåëü ( ñïèñîê_îïèñàíèé_ïàðàìåòðîâ )
Åñëè ïàðàìåòð ñïåöèôèöèðîâàí êàê register, òî ñîîòâåòòâóþùèé ôàêòè÷åñêèé ïàðàìåòð áóäåò ïî
Òåëî ôóíêöèè èìååò âèä
òåëî_ôóíêöèè: ñîñòàâíîé_îïåðàòîð
Âîò ïðîñòîé ïðèìåð ïîëíîãî îïðåäåëåíèÿ ôóíêöèè:
int max(int a, int b, int c) (* int m = (a « b) ? a : b; return (m » c) ? m : c; *)
Çäåñü int ýòî ñïåöèôèêàòîð_òèïà; max(int a, int b, int c) ýòî îïèñàòåëü_ôóíêöèè; (* ...
Ïîñêîëüêó â êîíòåêñòå âûðàæåíèÿ èìÿ ìîññèâà (â îñîáåíîñòè, êàê ôàêòè÷åñêîãî ïàðàìåòðà) ïðèí
 îïðåäåëåíèè êîíñòðóêòîðà ìîãóò áûòü çàäàíû èíèöèàëèçòîðû äëÿ áàçîâîãî êëàññà è äëÿ ÷ëåíîâ
èíèöèàëèçàòîð_áàçîâîãî: : ñïèñîê_èíèöèàëèçàòîðîâ_÷ëåíîâ
ñïèñîê_èíèöèàëèçàòîðîâ_÷ëåíîâ: èíèöèàëèçàòîð_÷ëåíà èíèöèàëèçàòîð_÷ëåíà , ñïèñîê_èíèöèàëèçàò
èíèöèàëèçàòîð_÷ëåíà: èäåíòèôèêàòîð opt ( ñïèñîê_ïàðàìåòðîâ opt )
Åñëè â èíèöèàëèçàòîðå_÷ëåíà äàí èäåíòèôèêàòîð, òî ñïèñîê ïàðàìåòðîâ èñïîëüçóåòñÿ äëÿ èíèöèà
struct base (* base(int); ... *);
struct derived : base (* derived(int); base b; const c;
*);
derived::derived(int a) : (a+1), b(a+2), c(a+3) (* /* ... */ *)
derived d(10);
Ñíà÷àëà êîíñòðóêòîð áàçîâîãî êëàññà âûçûâàåòñÿ äëÿ îáåêòà d ñ ïàðàìåòðîì 11, çàòåì âûçûâàåò

11. Êîìàíäíûå Ñòðîêè Êîìïèëÿòîðà


Êîìïèëÿòîð ñîäåðæèò ïðåïðîöåññîð, ñïîñîáíûé âûïîëíÿòü ìàêðîïîäñòàíîâêè, óñëîâíóþ êîìïèëÿöèþ
Ó÷òèòå, ÷òî îïðåäåëåíèÿ const è inline äàþò àëüòåðíàòèâû äëÿ áîëüøèíñòâà èñïîëüçîâàíèé #def

11.1 Çàìåíà Ëåêñåì


Êîìàíäíàÿ ñòðîêà êîìïèëÿòîðà âèäà
#define èäåíòèôèêàòîð ñòðîêà_ëåêñåì âûçûâàåò çàìåíó ïðåïðîöåññîðîì ïîñëåäóþùèõ âõîæäåíèé èä
Ñòðîêà âèäà
#define èäåíòèôèêàòîð( èäåíòèôèêàòîð , ... , èäåíòèôèêàòîð) ñòðîêà_ëåêñåì
ãäå íåò ïðîáåëà ìåæäó ïåðâûì èäåíòèôèêàòîðîì è (, ÿâëåòñÿ ìàêðîîïðåäåëåíèåì ñ ïàðàìåòðàìè.
(ñ ïîìîùüþ define) èäåíòèôèêàòîðîâ.
 îáîèõ ñëó÷àÿõ ñòðîêà çàìåùåíèÿ åùå ðàç ñêàíèðóåòñÿ â ïîèñêàõ äðóãèõ îïðåäåëííûõ èäåíòèôèê
Êîìàíäíàÿ ñòðîêà âèäà
#undef èäåíòèôèêàòîð
âëå÷åò îòìåíó ïðåïðîöåññîðíîãî îïðåäåëåíèÿ èäåíòèôèêàòðà.
11.2 Âêëþ÷åíèå Ôàéëîâ
Êîìàíäíàÿ ñòðîêà êîìïèëÿòîðà âèäà
#include «èìÿ_ôàéëà»
âûçûâàåò çàìåíó ýòîé ñòðîêè ïîëíûì ñîäåðæèìûì ôàéëà èìÿ_ ôàéëà. Ñíà÷àëà èìåíîâàííûé ôàéë èù
#include «èìÿ_ôàéëà»
ïðîèçâîäèò ïîèñê òîëüêî â ñòàíäàðòíîì èëè çàäàííîì ìåòå, è íå èùåò â äèðåêòîðèè èñõîäíîãî ô

11.3 Óñëîâíàÿ Êîìïèëÿöèÿ


Êîìàíäíàÿ ñòðîêà êîìïèëÿòîðà âèäà
#if âûðàæåíèå
ïðîâåðÿåò, ÿâëÿåòñÿ ëè ðåçóëüòàòîì âû÷èñëåíèÿ âûðàæåíèÿ íå-íîëü. Âûðàæåíèå äîëæíî áûòü êîíñ
#ifdef èäåíòèôèêàòîð
ïðîâåðÿåò, îïðåäåëåí ëè èäåíòèôèêàòîð â ïðåïðîöåññîðå â äàííûé ìîìåíò; òî åñòü, áûë ëè îí î

#ifndef èäåíòèôèêàòîð
ïðîâåðÿåò, ÿâëÿåòñÿ ëè èäåíòèôèêàòîð íåîïðåäåëåííûì â ïðåïðîöåññîðå â äàííûé ìîìåíò.
Ïîñëå êàæäîãî èç òðåõ âèäîâ ìîæåò ñòîÿòü ïðîèçâîëüíîå êîëè÷åñòâî ñòðîê, âîçìîæíî, ñîäåðæàùè
#else
è äàëåå äî êîìàíäíîé ñòðîêè
#endif
Åñëè ïðîâåðåííîå óñëîâèå èñòèííî, òî âñå ñòðîêè ìåæäó #else è #endif èãíîðèðóþòñÿ. Åñëè ïðî
Ýòè êîíñòðóêöèè ìîãóò áûòü âëîæåííûìè.

11.4 Óïðàâëåíèå Ñòðîêîé


Äëÿ ïîìîùè äðóãèì ïðåïðîöåññîðàì, ãåíåðèðóþùèì ïðîãðàììû íà Ñ++, ñòðîêà âèäà
#line êîíñòàíòà «èìÿ_ôàéëà»
çàñòàâëÿåò êîìïèëÿòîð ñ÷èòàòü, íàïðèìåð, â öåëÿõ äèàíîñòèêè îøèáîê, ÷òî êîíñòàíòà çàäàåò íî

12. Êîíñòàíòíûå Âûðàæåíèÿ


 íåñêîëüêèõ ìåñòàõ Ñ++ òðåáóåò âûðàæåíèÿ, âû÷èñëåíèå êîòîðûõ äàåò êîíñòàíòó: â êà÷åñòâå ãð
+ * / % amp; ! ^ « » == != « » «= »= amp; amp; !!
èëè óíàðíûìè îïåðàöèÿìè
+ ~ !
èëè òåðíàðíîé îïåðàöèåé
?:

Ñêîáêè ìîãóò èñïîëüçîâàòüñÿ äëÿ ãðóïïèðîâàíèÿ, íî íå äëÿ âûçîâà ôóíêöèé.


Âî âñåõ îñòàëüíûõ ñëó÷àÿõ êîíñòàíòíîå âûðàæåíèå ìîæåò òàêæå ñîäåðæàòü óíàðíóþ îïåðàöèþ amp;
Ìåíüøàÿ øèðîòà äîïóñòèìà äëÿ êîíñòàíòíûõ âûðàæåíèé ïîñëå #if: íåäîïóñòèìû èìåíà, îïèñàííûå
13. Ñîîáðàæåíèÿ Ìîáèëüíîñòè
Îïðåäåëåííûå ÷àñòè Ñ++ ÿâëÿþòñÿ ìàøèííî çàâèñèìûìè ïî ñâîåé ñóòè. Ñëåäóþùèé íèæå ñïèñîê ìåñ
Êàê ïîêàçàëà ïðàêòèêà, õàðàêòåðèñòèêè àïïàðàòóðû â ÷èòîì âèäå, òàêèå, êàê ðàçìåð ñëîâà, ñâî
×èñëî ðåãèñòðîâûõ ïåðåìåííûõ, êîòîðûå ôàêòè÷åñêè ìîãóò áûòü ïîìåùåíû â ðåãèñòðû, ðàçëè÷àåòñ
 ÿçûêå íåîïðåäåëåí ïîðÿäîê âû÷èñëåíèÿ ïàðàìåòðîâ ôóíöèè. Íà íåêîòîðûõ ìàøèíàõ îí ñëåâà íàï
Ïîñêîëüêó ñèìâîëüíûå êîíñòàíòû â äåéñòâèòåëüíîñòè ÿâëþòñÿ îáúåêòàìè òèïà int, òî ìîãóò áûòü
14. Êðàòêîå Èçëîæåíèå Ñèíòàêñèñà
Ýòà êðàòêàÿ ñâîäêà ñèíòàêñèñà Ñ++ ïðåäíàçíà÷àåòñÿ, ÷òîáû ñïîñîáñòâîâàòü ïîíèìàíèþ. Îíà íå ÿ

14.1 Âûðàæåíèÿ
âûðàæåíèå: òåðì âûðàæåíèå áèíàðíàÿ_îïåðàöèÿ âûðàæåíèå âûðàæåíèå ? âûðàæåíèå : âûðàæåíèå ñïè
ñïèñîê_âûðàæåíèé: âûðàæåíèå ñïèñîê_âûðàæåíèé , âûðàæåíèå
òåðì: ïåðâè÷íîå_âûðàæåíèå óíàðíàÿ_îïåðàöèÿ òåðì òåðì ++ òåðì sizeof âûðàæåíèå sizeof ( èì
ïåðâè÷íîå_âûðàæåíèå: id :: èäåíòèôèêàòîð êîíñòàíòà ñòðîêà this ( âûðàæåíèå ) ïåðâè÷íîå_âûðà
id: èäåíòèôèêàòîð typedef-èìÿ :: èäåíòèôèêàòîð typedef-èìÿ :: èìÿ_ôóíêöèè_îïåðàöèè
îïåðàöèÿ: óíàðíàÿ_îïåðàöèÿ áèíàðíàÿ_îïåðàöèÿ ñïåöèàëüíàÿ_îïåðàöèÿ îïåðàöèÿ_ñâîáîäíîé_ïàìÿòè
Áèíàðíûå îïåðàöèè èìåþò ïðèîðèòåò, óáûâàþùèé â óêàçàííîì ïîðÿäêå:
áèíàðíàÿ_îïåðàöèÿ: îäíà èç * / % + « » « »
== != amp; ^ ! amp; amp; !! îïåðàöèÿ_ïðèñâàèâàíèÿ
îïåðàöèÿ_ïðèñâàèâàíèÿ: îäíà èç = += -= *= /= %= ^= amp;= != »»= ««=
óíàðíàÿ_îïåðàöèÿ: îäíà èç * amp; + ~ ! ++
ñïåöèàëüíàÿ_îïåðàöèÿ: îäíà èç () []
îïåðàöèÿ_ñâîáîäíîé_ïàìÿòè: îäíà èç new delete
èìÿ_òèïà: ñïåöèôèêàòîðû_îïèñàíèÿ àáñòðàêòíûé_îïèñàòåëü
àáñòðàêòíûé_îïèñàòåëü: ïóñòîé * àáñòðàêòíûé_îïèñàòåëü àáñòðàêòíûé_îïèñàòåëü ( ñïèñîê_îïèñàí
ïðîñòîå_èìÿ_òèïà: typedef-èìÿ char short int long unsigned float double void

typedef-èìÿ: èäåíòèôèêàòîð

14.2 Îïèñàíèÿ
îïèñàíèå: ñïåöèôèêàòîðû_îïèñàíèÿ opt ñïèñîê_îïèñàòåëåé opt ; îïèñàíèå_èìåíè asm-îïèñàíèå
îïèñàíèå_èìåíè: ñîñò èäåíòèôèêàòîð ; enum èäåíòèôèêàòîð ;
ñîñò:
class struct union
asm-îïèñàíèå: asm ( ñòðîêà ) ;
ñïåöèôèêàòîðû_îïèñàíèÿ: ñïåöèôèêàòîð_îïèñàíèÿ ñïåöèôèêàòîðû_îïèñàíèÿ opt
ñïåöèôèêàòîð_îïèñàíèÿ: ñïåöèôèêàòîð_êëàññà_ïàìÿòè ñïåöèôèêàòîð_òèïà ñïåöèôèêàòîð_ôóíêöèè ty
ñïåöèôèêàòîð_òèïà: ïðîñòîå_èìÿ_òèïà ñïåöèôèêàòîð_êëàññà ñïåöèôèêàòîð_enum óñëîæíåííûé_ñïåöè
ñïåöèôèêàòîð_êëàññà_ïàìÿòè: auto extern register static
ñïåöèôèêàòîð_ôóíêöèè: inline overload virtual
óñëîæíåííûé_ñïåöèôèêàòîð_òèïà: êëþ÷ typedef-èìÿ êëþ÷ èäåíòèôèêàòîð
êëþ÷: class struct union enum
ñïèñîê_îïèñàòåëåé: èíèö-îïèñàòåëü èíèö-îïèñàòåëü , ñïèñîê_îïèñàòåëåé
èíèö-îïèñàòåëü: îïèñàòåëü èíèöèàëèçàòîð opt
îïèñàòåëü: îï_èìÿ ( îïèñàòåëü ) * const opt îïèñàòåëü amp; const opt îïèñàòåëü
îïèñàòåëü ( ñïèñîê_îïèñàíèé_ïàðàìåòðîâ ) îïèñàòåëü [ êîíñòàíòíîå_âûðàæåíèå opt ]
îï_èìÿ: ïðîñòîå_îï_èìÿ typedef-èìÿ :: ïðîñòîå_îï_èìÿ
ïðîñòîå_îï_èìÿ: èäåíòèôèêàòîð typedef-èìÿ ~ typedef-èìÿ èìÿ_ôóíêöèè_îïåðàöèè èìÿ_ôóíêöèè_ïð
èìÿ_ôóíêöèè_îïåðàöèè: operator îïåðàöèÿ
èìÿ_ôóíêöèè_ïðåîáðàçîâàíèÿ operator òèï
ñïèñîê_îïèñàíèé_ïàðàìåòðîâ: ñïèñîê_îïèñàíèé_ïðì opt ... opt
ñïèñîê_îïèñàíèé_ïðì: ñïèñîê_îïèñàíèé_ïðì , îïèñàíèå_ïàðàìåòðà îïèñàíèå_ïàðàìåòðà
îïèñàíèå_ïàðàìåòðà: ñïåöèôèêàòîðû_îïèñàíèÿ îïèñàòåëü = âûðàæåíèå ñïåöèôèêàòîðû_îïèñàíèÿ îïè
ñïåöèôèêàòîð_êëàññà: çàãîëîâîê_êëàññà (* ñïèñîê_÷ëåíîâ opt *) çàãîëîâîê_êëàññà (* ñïèñîê_÷ë
çàãîëîâîê_êëàññà: ñîñò èäåíòèôèêàòîð opt ñîñò èäåíòèôèêàòîð opt : public opt typedef-èìÿ
ñïèñîê_÷ëåíîâ: îïèñàíèå_÷ëåíà ñïèñîê_÷ëåíîâ opt
îïèñàíèå_÷ëåíà: ñïåöèôèêàòîðû_îïèñàíèÿ opt îïèñàòåëü_÷ëåíà èíèöèàëèçàòîð opt ; îïðåäåëåíèå_
îïèñàòåëü_÷ëåíà: îïèñàòåëü èäåíòèôèêàòîð opt : êîíñòàíòíîå_âûðàæåíèå
èíèöèàëèçàòîð: = âûðàæåíèå = (* ñïèñîê_èíèöèàëèçàòîðîâ *) = (* ñïèñîê_èíèöèàëèçàòîðîâ , *)

ñïèñîê_èíèöèàëèçàòîðîâ: âûðàæåíèå ñïèñîê_èíèöèàëèçàòîðîâ , ñïèñîê_èíèöèàëèçàòîðîâ (* ñïèñîê


ñïåöèôèêàòîð_enum: enum èäåíòèôèêàòîð opt (* enum-ñïèñîê *)
enum-ñïèñîê: ïåðå÷èñëèòåëü enum-ñïèñîê , ïåðå÷èñëèòåëü
ïåðå÷èñëèòåëü: èäåíòèôèêàòîð èäåíòèôèêàòîð = êîíñòàíòíîå_âûðàæåíèå

14.3 Îïåðàòîðû
ñîñòàâíîé_îïåðàòîð: (* ñïèñîê_îïåðàòîðîâ opt *)
ñïèñîê_îïåðàòîðîâ: îïåðàòîð îïåðàòîð ñïèñîê_îïåðàòîðîâ
îïåðàòîð: îïèñàíèå ñîñòàâíîé_îïåðàòîð âûðàæåíèå opt ; if ( âûðàæåíèå ) îïåðàòîð if ( âûðàæå

14.4 Âíåøíèå îïðåäåëåíèÿ


ïðîãðàììà: âíåøíåå_îïðåäåëåíèå âíåøíåå_îïðåäåëåíèå ïðîãðàììà
âíåøíåå_îïðåäåëåíèå: îïðåäåëåíèå_ôóíêöèè îïèñàíèå
îïðåäåëåíèå_ôóíêöèè: ñïåöèôèêàòîðû_îïèñàíèÿ opt îïèñàòåëü_ôóíêöèè èíèöèàëèçàòîð_áàçîâîãî op

îïèñàòåëü_ôóíêöèè: îïèñàòåëü ( ñïèñîê_îïèñàíèé_ïàðàìåòðîâ )


òåëî_ôóíêöèè: ñîñòàâíîé_îïåðàòîð
èíèöèàëèçàòîð_áàçîâîãî: : ( ñïèñîê_èíèöèàëèçàòîðîâ_÷ëåíîâ opt )

14.5 Ïðåïðîöåññîð
#define èäåíòèôèêàòîð ñòðîêà_ëåêñåì
#define èäåíòèôèêàòîð( èäåíòèôèêàòîð,...,èäåíòèôèêàòîð ) ñòðîêà ëåêñåì #else #endif #if âûð

15. Îòëè÷èÿ îò C
15.1 Ðàñøèðåíèÿ
Òèïû ïàðàìåòðîâ ôóíêöèè ìîãóò áûòü çàäàíû (#8.4) è áóäóò ïðîâåðÿòüñÿ (#7.1). Ìîãóò âûïîëíÿò
Äëÿ âûðàæåíèé ñ ÷èñëàìè ñ ïëàâàþùåé òî÷êîé ìîæåò èñïîëçîâàòüñÿ ïëàâàþùàÿ àðèôìåòèêà îäèíàðí
Èìåíà ôóíêöèé ìîãóò áûòü ïåðåãðóæåíû; #8.9.
Îïåðàöèè ìîãóò áûòü ïåðåãðóæåíû; 7.16, #8.5.11.
Ôóíêöèè ìîãóò áûòü inline-ïîäñòàâëÿåìûìè; #8.1.
Îáúåêòû äàííûõ ìîãóò áûòü êîíñòàíòíûìè (const); #8.3.
Ìîãóò áûòü îïèñàíû îáúåêòû ññûëî÷íîãî òèïà; #8.4, #8.6.3
Îïåðàöèè new è delete îáåñïå÷èâàþò ñâîáîäíîå õðàíåíèå â ïàìÿòè, #7.2.
Êëàññû ìîãóò îáåñïå÷èâàòü ñîêðûòèå äàííûõ (#8.5.9), ãðàíòèðîâàííóþ èíèöèàëèçàöèþ (#8.6.2),
Èìÿ êëàññà èëè ïåðå÷èñëåíèÿ ÿâëÿåòñÿ èìåíåì òèïà; #8.5.

Ëþáîé óêàçàòåëü ìîæåò ïðèñâàèâàòüñÿ void* áåç ïðèìåíåèÿ ïðèâåäåíèÿ ê òèïó; #7.14.
Îïèñàíèå âíóòðè áëîêà ÿâëÿåòñÿ îïåðàòîðîì; #9.14.
Ìîæíî îïèñûâàòü áåçûìÿííûå îáúåäèíåíèÿ; #8.5.13.

15.2 Ñâîäêà Íåñîâìåñòèìîñòåé


Áîëüøèíñòâî êîíñòðóêöèé C äîïóñòèìû â Ñ++ áåç èçìåíåíèÿ èõ ñìûñëà. Èñêëþ÷åíèÿ èç ýòîãî ñëåä
Ïðîãðàììû, èñïîëüçóþùèå îäíî èç íîâûõ êëþ÷åâûõ ñëîâ
class const delete friend inline new operator overload public signed this virtua
l volatile
êàê èäåíòèôèêàòîðû, íåäîïóñòèìû.
Îïèñàíèå ôóíêöèè f(); îçíà÷àåò, ÷òî f íå ïîëó÷àåò ïàðìåòðîâ, â C æå ýòî çíà÷èò, ÷òî f ìîæåò
 C âíåøíåå èìÿ ìîæåò îïðåäåëÿòüñÿ íåñêîëüêî ðàç, à â Ñ+ + îíî äîëæíî áûòü îïðåäåëåíî ðîâíî
Èìåíà êëàññîâ â Ñ++ íàõîäÿòñÿ â òîì æå ïðîñòðàíñòâå, ÷òî è ïðî÷èå èìåíà, ïîýòîìó êîíñòðóêöè
int s; struct s (* /* ... */ *); f() (* s = 1; *)
èñïîëüçîâàòüñÿ íå ìîãóò. Îäíàêî, äëÿ ðàçðåøåíèÿ áîëøèíñòâà êîíôëèêòîâ ìîæåò ïðèìåíÿòüñÿ ÿâí
int s; struct s (* /* ... */ *); void f() (*int s; struct s a; *) void g() (* ::
s = 1; *)

15.3 Àíàõðîíèçìû
Èçëîæåííûå çäåñü ðàñøèðåíèÿ ìîãóò ïðåäîñòàâëÿòüñÿ äëÿ òîãî, ÷òîáû óïðîñòèòü èñïîëüçîâàíèå C
Ïðåæíåå íåîïðåäåëåííîå èìÿ ìîæåò èñïîëüçîâàòüñÿ êàê èìÿ ôóíêöèè â âûçîâå.  ýòîì ñëó÷àå èìÿ
ôóíêöèÿ, âîçâðàùàþùàÿ int ñ òèïîì ïàðàìåòðà (...).
Êëþ÷åâîå ñëîâî void ìîæåò èñïîëüçîâàòüñÿ äëÿ óêàçàíèÿ òîãî, ÷òî ôóíêöèÿ íå ïîëó÷àåò ïàðàìåò
Ìîãóò èñïîëüçîâàòüñÿ ïðîãðàììû, â êîòîðûõ èñïîëüçóåòñÿ ñèíòàêñèñ îïðåäåëåíèÿ ôóíêöèé â C
ñòàðîå_îïðåäåëåíèå_ôóíêöèè: ñïåöèôèêàòîðû_îïèñàíèÿ opt ñòàðûé_îïèñàòåëü_ôóíêöèè ñïèñîê_îïèñ
ñòàðûé_îïèñàòåëü_ôóíêöèè: îïèñàòåëü (* ñïèñîê_ïàðàìåòðîâ *)
ñïèñîê_ïàðàìåòðîâ: èäåíòèôèêàòîð èäåíòèôèêàòîð , èäåíòèôèêàòîð
íàïðèìåð,
max(a,b) (* return (a«b) ? b : a; *)
Åñëè ôóíêöèÿ, îïèñàííàÿ êàê ýòà, áûëà ðàíåå îïèñàíà, òèï åå ïàðàìåòðà áóäåò ïðèíÿò (...), ò
Âìåñòî :: ìîæåò èñïîëüçîâàòüñÿ òî÷êà äëÿ ñïåöèôèêàöèè èìåíè â îïðåäåëåíèè ôóíêöèè ÷ëåíà. Íà
int cl.fct() (* /* ... */ *)
Îäíî è òî æå èìÿ ìîæåò áûòü îïèñàíî îäíîâðåìåííî è äëÿ êëàññà èëè ïåðå÷èñëåíèÿ, è äëÿ îáúåê

Ñïàñèáî, ÷òî ñêà÷àëè êíèãó â áåñïëàòíîé ýëåêòðîííîé áèáëèîòåêå RoyalLib.ru


Íàïèñàòü ðåöåíçèþ ê êíèãå: http://royallib.ru/comment/hill_myurrey/C.html
Âñå êíèãè àâòîðà: http://royallib.ru/author/hill_myurrey.html
Ýòà æå êíèãà â äðóãèõ ôîðìàòàõ: http://royallib.ru/book/hill_myurrey/C.html

Вам также может понравиться