Начало Решаване на проблеми



страница1/19
Дата20.01.2017
Размер4.54 Mb.
  1   2   3   4   5   6   7   8   9   ...   19
СЪДЪРЖАНИЕ
Глава 0: Начало.........................................1

0.1 Решаване на проблеми..........................1

0.2 С++ програма..................................2

0.3 Пръвоначален поглед върху В/И.................6

0.4 Няколко думи за коментарите..................10

0.5 Директиви на предпроцесора...................13


Глава 1: Типове данни в С++............................15

1.1 Константни стойности.........................17

1.2 Променливи...................................19

1.3 Указателни типове............................26

1.4 Съотнасящи типове (reference types)..........35

1.5 Константни типове............................36

1.6 Изброими типове..............................40

1.7 Тип масив....................................41

1.8 Тип клас.....................................49

1.9 Имена на типове..............................60


Глава 2: Изрази и оператори............................63

2.1 Какво представлява изразът?..................63

2.2 Аритметични операции.........................64

2.3 Операции за равенство и отношение,

логически операции...........................65

2.4 Оператор за присвояване......................67

2.5 Оператори за увеличаване и намаляване с 1....69

2.6 Операторът sizeof............................72

2.7 Аритметичен оператор if......................73

2.8 Оператори за работа с битове.................74

2.9 Приоритет....................................79

2.10 Преобразуване на типове.....................80

2.11 Оператори...................................85

2.12 Оператори за управление.....................86

2.13 Операторът if...............................87

2.14 Операторът switch...........................92

2.15 Операторът while............................97

2.16 Операторът for..............................98

2.17 Операторът do..............................100

2.18 Операторът break...........................101

2.19 Операторът continue........................101

2.10 Операторът goto............................102


Глава 3: Функции и обхват.............................103

3.1 Рекурсия....................................105

3.2 Функции inline..............................107

3.3 Строга проверка на типовете.................108

3.4 Връщане на стойност.........................109

3.5 Списък от аргументи на функция..............112

3.6 Изпращане на аргументи......................117

3.7 Аргумент - псевдоним (reference)............119

3.8 Аргумент - масив............................122

3.9 Програмен обхват............................124

3.10 Локален обхват.............................130
Глава 4: Свободна памет и презаредими имена...........135

4.1 Разпределение на свободната памет...........135

4.2 Един пример за свързан списък...............141

4.3 Презаредими имена на функции................151

4.4 Указатели към функции.......................164

4.5 Свързване, безопасно относно типовете.......171


Глава 5: Класът в С++.................................177

5.1 Дефиниция на клас...........................178

5.2 Класови обекти..............................183

5.3 Член функции на клас........................185

5.4 Неявен указател this........................194

5.5 Приятели на клас............................200

5.6 Статични членове на класа...................206

5.7 Указател към член на клас...................210

5.8 Обхват на клас..............................217

5.9 Обединение: Клас, който пести памет.........224

5.10 Разредно поле: член, който пести памет.....227

5.11 Аргумент клас и многоточие.................229


Глава 6: Член функции на клас.........................231

6.1 Инициализация на клас.......................231

6.2 Почленова инициализация.....................247

6.3 Презареждане на оператор....................253

6.4 Пример за клас BitVector....................272

6.5 Конвертори, дефинирани от потребителя.......282


Глава 7: Извличане на класове.........................295

7.1 Обектно-ориентирано програмиране...........297

7.3 Представяне Zoo Animal.....................305

7.4 Определяне (спецификация на извличанията)...307

7.5. Скриване на информацията при извличане.....314

7.6. Public и Private базови класове............317

7.7. Стандартни преобразувания при извличане....319

7.8 Обхват на клас при извличане................323

7.9 Извличане, инициализация и присвояване......326
Глава 8: Обектно-ориентирано програмиране.............331

8.1 Презаредими функции с аргумент клас........331

8.2 Виртуални функции...........................337

8.3 Виртуални базови класове....................360

C++ PRIMER
Stanley B. Lippman
AT&T Bell Laboratories

To Beth,


who makes this,

and all things,

possible.
ЇЇЇЇЇЇЇЇЇЇЇЇ

I.
Езикът за програмиране С++ беше разработен от AT&T

Bell Laboratories в началото на 80-те години от Bjarne

Stroustrup. Той педставлява развитие на програмния език С,

което разширява С в три важни направления:
1. създаване и използуване на абстрактни типове

данни,
2. обектно - ориентирано проектиране и програмиране,


3. различни подобрения на съществуващи С-конструкции,
като се запазва простотата на изразяване и скоростта на

изпълнение, характерна за С.

С++ вече е широко достъпен и често се използува за

реални приложения и разработване на системи. През шестте

месеца от представянето му от AT&T в края на 1985г. се появиха

търговски реализации на С++ за над 24 системи, обхващащи от

персоналните компютри до големи машини. От тогава бяха

направени множество приложения и сега С++ е директно достъпен

за няколко компютърни групи. В допълнение, през 1985г. беше

създаден първия оригинален компилатор за РС и работни станции

за пазара. На различни конференции и в технически публикаци се

появиха статии, описващи потребителския опит от използуването

на С++.

Може би поради стремителното си навлизане, за С++ не



се появиха множество обучаващи и образователни материали.

Тази книга прави една голяма стъпка в запълването на тази

празнина. Основно справочно пособие се явява книгата "The C++

Programming Language" от Stroustrup, която дефинира и описва

езика при появяването му. От този момент, С++ беше развит,

като бяха добавени нови характеристики в отговор на

потребителския опит. Тази книга предлага обширно въвеждане в

езика С++, съответствуващо на по-късна негова реализация -

версия 2.0. Освен това, тя предлага един консултативно -

обучаващ подход при описване на езика. Познаването на езка С

не е наложително, но е задължително владеенето на някой

съвременен блоково структуриран език; тя не е замислена като

първа книга по програмиране!

Голяма част от мощността на С++ се дължи на факта, че

той поддържа нов начин за програмиране и нов начин за мислене

върху програмните проблеми. За да се научите да използувате

С++ ефективно, следователно, е необходимо нещо повече от

простото запознаване с един нов набор от синтактични и

семантични правила. За да бъде улеснено такова изучаване на

езика, книгата е организирана на групи от обширни примери.

Тези примери се използуват както за поясняване на различните

езикови характеристики, така и мотивирането им. Чрез

изучаването на езиковите характеристики в контекста на

ЇЇЇЇЇЇЇЇЇЇЇЇ

II.
примерите става ясно защо тези характеристики са полезни, като

се придобива усет кога и как да бъдат използувани при решаване

на проблеми от реалния свят. В добавка, целта на примерите,

която трябва да бъде постигната, е да се позволи ранното

запознаване с концепции, които ще бъдат по-пълно разяснени,

когато базовите знанията на читателя се доизграждат. Примерите

в началото могат и наистина съдържат просто използуване на

фундаменталните езикови концепции, давайки усет за същността

на програмирането на С++ без изискване за пълно разбиране

на детаилите по проектирането и реализацията.

Структура на този блок
Фундаментални за С++ са различните улеснения, които

позволяват на потребителя да разширяват езика като такъв чрез

дефиниране на нови типове данни, които да бъдат използувани с

гъвкавостта и простотата на вградените типове данни. Първа

стъпка към придобиване на майсторство е да се разбере самия

базов език. Глави от 0 до 4 разглеждат езика на това ниво,

докато глави от 5 до 8 разширяват дискусията върху

улесненията, които поддържат създаването на типове, дефинирани

от потребителя.

Глава 0 описва основните елементи на една С++ програма

и подробности за въвеждането и изпълнението й. Данновите

типове, изразите и операторите са обект на разглеждане от

глави 1 и 2. Глава 1 включва дискусия и пример за въведане на

С++ клас, като тази фундаментална идея ще бъде обогатявана и

допълвана в течение на цялата книга. Глава 3 въвежда някои

функции, докато глава 4 разширява обсъждането върху обхвта

на презаредимите имена и функции за управление на свободната

памет. Професионалният програмист и, особено, програмистът на

С може да бъде изкушен да прескочи тези глави. Не го правете.

В тези глави са включени някои нови концепции и дори много

опитният програмист на С може да извлече полза от прочитането

и работата с примерите в текста, както и с упражненията. Глави

5 и 6 разясняват класовия механизъм и как се поддържа

проектирането и реализацията на абстрактните типове данни.

Чрез създаването на нови типове за описание на проблемната

област, С++ позволява на програмиста да пише приложения като

по-малко засяга разни изчислителни аспекти, правещи

програмирането досадно. Реализацията на типовете,

фундаментални за приложението може да бъде направена веднъж и

използувана многократно, което позволява на програмиста да се

концентрира по-скоро върху проблема, отколкото върху детаилите

на реализацията. В добавка, улесненията по групирането на

данните може съществено да упрости следващата поддръжка и

промени.


Обектно-ориентираното програмиране и улесненията,

които С++ поддържа, са предмет на обсъждане в глави 7 и 8.

Глава 7 пояснява наследствеността. Използувайки наследяването,

програмистът може да обхване връзките между типовете, които

са взаимно зависими. Класическият пример е за форми. Всички

форми имат подходящи атрибути: положение върху плоскост,

логика на завъртане, чертане на форма и т.н. Наследствеността

ЇЇЇЇЇЇЇЇЇЇЇЇ

III.
позволява тези общи атрибути да бъдат разделени от приложна

гледна точка, докато реализацията на всяка конкретна форма не

се грижи за допълнително дефиниране на тези атрибути, които

всъщност са различни за различните форми. Фундаментална за

обектно-ориентираното програмиране е възможността да се избира

по време на изпълнение коя точно функция да бъде извикана.

Например, по време на изпълнение ние трябва да можем да

поискаме завъртане на формата и да знаем, че ще бъде избран

подходящ за окръжност или квадрат алгоритъм /логика/, който да

бъде извикан в зависимост от фактическият тип на формата,

която ще бъде въртяна. В С++ това се осъществява чрез

виртуалния механизъм за работа с функции, който се обсъжда в

глава 8. Глава 8 разгрежда по-пълно наследствената йерархия,

като се използуват виртуалните базови класове.

Както своя предшественик С, и тук целият вход и изход

се обработва чрез стандартна библиотека. За версия 2.0 тази

библиотека е значително разширена. Приложение А предлага едно

учебно въведение.

Както беше отбелязано по-горе, С++ се е раазвивал

след първоначалното му пускане за продажба. Новите черти,

включени към версия 2.0 включват:
- многократно наследяване и виртуални базови класове.
- рекурсивна инициализация и присвояване на членство.
- запазваща типовете връзка с други езици.
- презареждане на оператори като new, delete, ->, and,

(comma).


- функции със статично и константно членство.
Приложение D пояснява как тези езикови разширения

въздействуват на по-ранните версии на С++. Както и при всеки

програмен език, степента на овладяване на С++ се показва

от изпалзуването му. Приложенние B предлага две

характеристики, които е добре да бъдат добавени към езика.

Доколкото С++ е основан на С очевидно има доста

характеристики в С++, които не са представени в С. Съответно,

има малко характеристики, общи за двата езика, но с малки

разлики в конкретната реализация. Това е предмет на обсъждане

за Приложение С.


Бележки по реализацията
Програмите, приложени в тази книга, са дадени директно

от изходните текстове, компилирани на DEC VAX 8550 като е

използувана ОС UNIX V версия 2. Всички програми и програмни

фрагменти са компилирани, като е използувана версия 2.0 на

С++, разработена от Bell Laboratories.

Част от тази книга беше използувана за обучение и беше

представена от автора на професионална конференция. Чернова на

ЇЇЇЇЇЇЇЇЇЇЇЇ

IV.
ръкописа беше предложена като обучаващ и справочен материал за

вътрешно ползуване в AT&T Bell Laboratories, подпомагащ

начинаещите в С++. Много от програмите и програмните фрагменти

в тази книга бяха използувани като примери за проверка при

разработването на версия 2.0.

Езикът С++, описан в тази книга, се основа на

описанието от май 1989г., дадено в справочния наръчник,

създаден от Stroustrup. Този наръчник е включен към

документацията на Езиковата система С++, версия 2.0 на AT&T.

С++ може да бъде доставен чрез AT&T, Software and

Marketing, P.O. Box 25000, Greensboro, NC 27420, USA (tel.

800-823-UNIX) или чрез местните търговски организации за

системата UNIX.
Благодарности
Тази книга е резултат на дискретната помощ, оказана на

автора в подкрепа на начинанието му. Най-сърдечна благодарност

отправям към Barbara Moo. Нейното насърчаване, съвети и

внимателния прочит на последователните чернови на ръкописа

бяха неоценими. Първите две части на това въведение са нейно

дело. Специални благодарности отправям също към Bjarne

Stroustrup за помощта му, както и за чудесния език, коойто ни

е предоставил. Благодарност изразявам и на Stephen Dewhurst,

който ми оказа помощ при първоначалното запознаване с езика.

Martin Carroll, William Hopkins, Brian Kernighan,

Andrew Koenig и Alexis Layton направиха много подробни и

съществени забележки. Прегледана от тях, книгата беше

значително подобрена. Phil Brown, James Coplein, Elizabeth

Flanagan, David Jordan, Don Kretsch, Craig Rubin и Judy Warad

прегледаха различни чернови на ръкописа направиха много

полезни забележки. David Jordan изясни множество ANSI C

въпроси. Jerry Schwarz, който е написал пакета за вход-изход,

предложи оригиналната документация, върху която е основано

приложение A. Неговият подробен и пълен преглед на това

приложение е много ценен.

Следват прегледите на ръкописа от представители на

Addison-Wesiey: Steven Bellovin, Victor Milenkovic, Norman

Kerth, Justin Smith, Jon Forrest, Darrell Long и Maurice

Herlihy.


Аз съм дълбоко впечатлен от Brian Kernighan и Andrew

Koenig, които ми предоставиха набор от средста за печат.


Справочник
[1] Carlo Ghezzi and Mehdi Jazayeri: Programming

Language Concepts, John Wiley & Sons, NY, 1992.


ЇЇЇЇЇЇЇЇЇЇЇЇ

V.
[2] Adele Goldberg and David Robson: SMALLTALK-80: The

Language and Its Implementation, Addison-Wesiey, Reading, MA,

1983.
[3] Samuel P. Harbison and Guy L. Steele, Jr.: C: A

Reference Manual, 2nd edition, Prentice-Hall, Englewood

Cliffs, NJ, 1987.
[4] Ralph Johnson and Brian Foote: Designing

Reusable Classes, Journal of OOPrograming, June/July 1988,

pp.22-35.
[5] Brian W. Kernigan and Dennis M. Ritchie: The C

Programming Language, 2nd edition, Prentice-Hall, Englewood

Cliffs, NJ, 1988.
[6] Andrew Koenig: C Traps and PitFalls, Addison-

Wesley, Reading, MA, 1989.


[7] Andrew Koenig: What is the C++, Anyway?, Journal

of OOProgramming, April/May 1988, pp.48-52.


[8] Andrew Koenig: An Example of Dynamic Binding in

C++, Journal of OOProgramming, August/Sep. 1988, pp.60-62.


[9] Stanley Lippman and Barbara Moo: C++: From

Research to Practice, Proc. of the USENIX C++ Conference,

Denver, CO, October 17-21, 1988, pp. 123-136.
[10] Stanley Lippman and Bjarne Stroustrup: Pointers

to Class Members in C++, Proc. of the USENIX C++ Conference,

Denver, CO, October 17-21, 1988, pp. 305-326.
[11] Stanley Lippman: What is this? The C++ Report,

March 1989, pp. 6-7.


[12] Barbara Liskov and John Guttag: Abstraktion and

Specification in Programming Development, McGraw-Hill, NY,

1986.
[13] Ravi Sethi: Programming Language Concepts and

Constructs, Addison-Wesely, Reading, MA, 1989. (Two Chaptrs on

C++).
[14] Bjarne Stroustrup: The C++ Programming Language,

Addison-Wesley, Reading, MA, 1986.


[15] Bjarne Stroustrup: Multiple Inheritance for C++,

Proc. EUUG Spring'87 Conference, Helsinki, May, 1987.


[16] Bjarne Stroustrup:: What is OOProgramming?, Proc.

of the USENIX C++ Workshop, Santa Fe, NM, Nov. 9-10, 1987,

pp.159-180.
[17] Bjarne Stroustrup: The Evolution of C++ 1985 to

1987, Proc. of the USENIX C++ Workshop, Santa Fe, NM, Nov.

9-10, 1987, pp. 1-21.

ЇЇЇЇЇЇЇЇЇЇЇЇ

VI.
[18] Bjarne Stroustrup: Possible Directions for C++,

Proc. of the USENIX C++ Workshop, Santa Fe, NM, Nov. 9-10,

1987, pp. 399-416.
[19] Bjarne Stroustrup: Type-safe Linkage for C++,

Proc. of the USENIX C++ Conference, Denver, CO, Oct. 17-21,

1988, pp. 193-211.
[20] Bjarne Stroustrup: Parameterized Types for C++,

Proc. of the USENIX C++ Conference, Denver, CO, Oct. 17-21,

1988, pp. 1-18.
Бележки по отпечатването
David Beckdorff, Dag Bruck, John Eldridge, Jim

Humelsine, Dave Jordan, Ami Klienman, Andy Koenig, Danny

Lippman, Clovis Tondo и Steve Vinoski откриха множество грешки

в предишното издание на тази книга. Благодаря за всичко това.


Глава 0: Начало

При самостоятелно запознаване с езика С++ естествено

възникват два въпроса:


1. Какво представлява една С++ програма? Как се пише?
2. Веднъж написана, как може да бъде изпълнена?
Тази глава описва основните знания и действия,

необходими за получаването на изпълнима програма от изходен

код на С++.

0.1. Решаване на проблеми


Програмите най-често се пишат в отговор на проблеми

или задачи, които трябва да бъдат решени. Нека да разгледаме

един пример. Магазин за книги въвежда във файл заглавието и

издателя на всяка книга, която продава. Информацията се

въвежда по реда на продаваните книги. Всеки две седмици

собственикът на ръка изчислява броя на екземплярите на всички

продадени книги, както и бройките, отнасящи се до различните

издатели. Списъкът се подрежда в азбучен ред и се използува за

реорганизация. Вие сте помолени да предложите програма за тази

работа.


Един от методите за решаване на голям проблем е

раздробяването му на няколко малки проблема. За щастие, тези

малки проблеми са по-лесни за решаване. Проблемът на

книжарницата се разделя на четири подпроблема или задачи:


1. Четене от файла за продажби.
2. Преброяване на продажбите по заглавие и издател.
3. Продреждане по заглавие и издател.
4. Записване на изходните резултати.
Точки 1, 3 и 4 представят проблеми, които знаем как да

решим; те не се нуждаят от допълнително разпадане. Точка 2,

обаче, представя проблем, който не може да бъде решен

директно. Затова прилагаме своя метод към нея:


2а. Подреждаме продадените книги по издатели.
2б. За всеки издател подреждаме продажбите по

заглавие.


2в. Сравняват се съседните заглавия във всяка

издателска група. За всяка съответствуваща двойка, се

увеличава броят на появите на първият елемент на двойката и се

изтрива вторият.

ЇЇЇЇЇЇЇЇЇЇЇЇ
ЇЇЇЇЇЇЇЇЇЇЇЇ

2.

Точки 2а, 2б и 2в също вече представят проблеми, които знаем как да решим. Тъй като вече сме в състояние да решим всички подпроблеми, които бяхме формулирали, то фактически сме решили и по-големия проблем. Последователността от действия ще бъ



де:
1. Четене от файла продажби.
2. Подреждане на файла продажби - първо по издател, а после в групите на издателите.
3. Сгъстяване на повтарящите се заглавия.
4. Записване на резултатите в нов файл.
Описаната последователност от действия може да бъде на-речена алгоритъм. Следващата стъпка е описване на алгоритъма в термините на някой програмен език - в този случай на С++.

0.2. С++ програма


В С++ всяко действие се представя чрез израз. Израз, ограничен с ";" представлява оператор. Най-малката независи-ма единица в езика е оператора. В естествените езици анало-гичната конструкция е изречение. Следващите изрази, напри-мер, са оп

ератори на С++.


int value;

value = 7 + 1;

cout << value;
Първият оператор е един декларативен оператор. Той де-финира област от паметта на компютъра, свързана с името value, където могат да се записват цели числа. Вторият опе-ратор е оператор за присвояване. Той помества в паметта на компютъра, свъ

рзана с името value, резултата от събирането на 7 и 1. Третият оператор е оператор за изход. Сout описва изход, насочен към потребителския терминал. << е оператор за изход. Операторът записва в cout, т.е. на потребителския терминал, стойността, съхра

нена в областта от компютърната памет, свързана с името value.

Операторите логически се групират в единици, наречени функции. Например, всички оператори, необходими за четене от файла продажби,са организирани във функция, наречена readIn(). Съответно, създаваме и функциите sort(), compact() и print().

В С++ всяка програма трябва да съдържа функция, нарече-на main(), написана от програмиста, преди да може да бъде изпълнена. Следва пример за дефиниране на main() за гореопи-сания алгоритъм.
ЇЇЇЇЇЇЇЇЇЇЇЇ
ЇЇЇЇЇЇЇЇЇЇЇЇ

3.
int main()

{

readIn();



sort();

compact();

print();

return 0;

}
Програмата на С++ започва да се изпълнява от първия оператор на main(). В този случай, програмата започва с изпълнението на функцията readIn(). Изпълнението й продължава чрез последователното изпълнение на операторите в main(). Тя приключва

нормално с изпълнението на последния оператор на main().

Всяка функция се състои от четири части: тип на

резултата, име на функцията, списък от аргументи и тяло.

Първите три елемента заедно образуват прототипа на функцията.

Списъкът от аргументи, затворен в скоби, съдържа списък от

нула или повече аргументи, отделени със запетая. Тялото на

функцията е затворено в скоби от вида "{ }". То съдържа

последователност от програмни оператори.

В този пример, в тялото на main() се извикват за

изпълнение функциите readIn(), sort(), compact() и print().

Когато тези функци приключат работа, се изпълнява операторът

return 0. Това е един предварително дефиниран оператор на С++,

предоставящ метод за прекратяване на изпълнението на функция.

Когато операторът е съпътствуван от стойност, 0 например, тази

стойност става стойност, която функцията връща. В този случай,

връщаната стойност 0 показва успешното приключване на

изпълнението на main().

Нека сега да подготвим програмата за изпълнение. Първо

трябва да предложим дефиниции за readIn(), sort(), compact() и

print(). В този момент следните фиктивни примери са достатъчно

добри.
void readIn() { cout << "readIn()\n"; }

void sort() { cout << "sort()\n"; }

void compact() { cout << "compact()\n"; }

void print() { cout << "print()\n"; }
viod се използува за да укаже, че функцията не връща

стойност. Както е дефинирано, всяка функция просто ще съобщи

за своето съществуване чрез написване на съответния текст

върху терминала на потребителя, когато бъде извикана от

main(). По-късно бихме могли да заменим фиктивния пример със

самото тяло, когато то бъде реализирано. Този метод на

последователно увеличаване на кода на програмата е полезен

за контролиране на програмните грешки, които неминуемо

допускаме. Да се опитваме да направим работеща програма

отведнъж е просто много сложно и объркващо.

Всеки файл, съдържащ текст на програма се състои от

две части - име на файл и разширение. Разширението често

определя съдържанието на файла. Това разширение ще се променя

ЇЇЇЇЇЇЇЇЇЇЇЇ


ЇЇЇЇЇЇЇЇЇЇЇЇ

4.
при различните реализации на С++. При операционната система

UNIX, името на С++ файла може да бъде завършено както със

".с", така и със ".С". Употребата на малка буква ".с" показва

съществуващата връзка между програмните езици С++ и С. (Всички

файлове, съдържащи програми на С трябва да завършват със

".с"). За да бъде различаван С++ програмен файл, използувайте

разширение ".С". (ў)

Въведете следната пълна програма в един С++ кодов

файл.
#include


void read() { cout << "read()\n"; }

void sort() { cout << "sort()\n"; }

void compact() { cout << "compact()\n"; }

viod write() { cout << "write()\n"; }


int main()

{

read();



sort();

compact();

write();

return 0;

}
Stream.h е един от т.н. заглавни файлове. Той съдържа

информация за cout, която е необходима за написаната програма.

#include е една предпроцесорна директива. Тя указва добавянето

на съдържанието на stream.h към нашия текстов файл. Част 0.5

(стр. 13) разглежда предпроцесорните директиви.

След като вече програмата е записана във файл може да

бъде компилирана. Това се прави така ($ е системния

показалец):


$ СС prog1.C
Името на командата, използувано за извикване на

компилатора на С++ ще бъде различно за различните реализации.

СС е името на командата, използувано от AT&T C++ Language

System, Release 2.0. Направете справка в своя наръчник или

попитайте вашия системен администратор за името на С++

компилатора във вашата система.

Част от работата на вашия компютър е да анализира

текста на програмата за коректност. Компютърът не може да

установи дали логиката на вашата програма е правилна, но може

да открие грешки във формата на програмата. Най-общо

програмните грешки, които компилаторът открива са:
ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ

(ў) За операционната система MS-DOS, обаче, разширението ".c"

не е допустимо - MS-DOS не прави разлика между малки и големи

букви. Реализацията на С++ под управлението на MS-DOS

поддържа следните разширения на файлове:
- cxx (x е + завъртян на 90 градуса).
- cpp (p съответствува на "плюс"-а).

ЇЇЇЇЇЇЇЇЇЇЇЇ


ЇЇЇЇЇЇЇЇЇЇЇЇ

5.
1. Синтактични грешки. Програмистът е направил

"граматическа грешка" според езика С++. Например:
int main(

{ // error: missing ')'

readIn: // error: illegal character ':'

sort();


compact();

print();


return 0 // error: missihg ';'

}
2. Грешки за типове. Данните в С++ се свързват с

типове. Стойността 10, например, е цяла. Думата "hello",

заградена от двойни кавички е символен низ. Ако на дадена

функция очакваща аргумент от цял тип се подаде аргумент тип

низ, компилаторът ще сигнализира за грешка при типовете.


Всяко съобщение за грешка съдържа номер на ред и

кратко описание на причината, поради която се счита, че вие

сте сгрешили. Препоръчва се грешките да се коригират в

последователността, в която се появяват. Често единична

грешка може да предизвика лавинообразен ефкет и компилаторът

да съобщи за повече гришки, отколкото фактически съществуват.

След като коригирате текста на програмата си, можете да я

компилирате отново.

Втората част от работата на компилатора е да преведе

формално коректния програмен текст. Този превод, наречен

генерация на код, фактчески генерира обектов или асемблерен

текст, разбираем за компютъра на който програмата ще бъде

изпълнявана.

Резултатът от успешна компилация е изпълним файл. По

подразбиране, при системата на автора този файл се нарича

a.out. Той може да бъде изпълнен както следва:


$ a.out
Изходът на програмата изглежда така:
readIn()

sort()


compact()

print()
Командната опция "-о име" позволява на програмиста да

даде име на програмния файл, различно от a.out. Например,

командният ред


$ CC prog1 prog1.C
ще създаде изпълним файл prog1. За да се изпълни тази програма

трябва да се напише:


$ prog1

ЇЇЇЇЇЇЇЇЇЇЇЇ


ЇЇЇЇЇЇЇЇЇЇЇЇ

6.
Освен езиковия компилатор реализацията на С++ предлага

и набор от стандартни библиотеки. Библиотеките са съвкупност

от предварително дефинирани функци. В С++, например, входът

и изходът се поддържат от стандартна С++ библиотека.

Програмистите могат да използуват библиотечните функции в

програмите си по същия начин, по който използуват функциите,

които са написали.

Най-голямото предимство на програмните библиотеки е

това, че позволяват на добри програмисти да комплектоват

своите знания за използуване от множество други програмисти.

Малко от нас, например, знаят как работи електричеството, но

повечето знаят как да включат осветлението. Добрата

библиотека може да бъде използувана така лесно, както и

ключа за осветление. В следващата част се прави един кратък

преглед на входно-изходната библиотека.

0.3. Пръвоначален поглед върху вход-изхода


Входът и изходът не са част от езика С++, но се

поддържат от библиотека, написана на С++ и позната като

iostream ( вх/изх. поток ). Приложение А разглежда подробно

тази библиотека(ў). В този дял е дадена достатъчна информация

за начинаещия читател.

Входът, постъпващ от потребителският терминал, наречен

стандартен вход, е свързан с предварително дефинирания във

вх/изх. поток вход cin (произнася се "see-in"). Изходът,

насочен към потребителския терминал, се нарича стандартен

изход и се свързва с предварително дефинирания във вх/изх.

поток изход cout (произнася се "see-out").

Операторът за изход ("<<") се използува за изпращане

на стойност към стандартния изход. Например:
cout << "The sum of 7 + 3 = ";

cout << 7 + 3;

cout << "\n";
Последователността от символи \n представя символа нов

ред. При писане той предизвиква насочване на печата на

следващия ред. Последователност от входно-изходни оператори

може да бъде обединена в един оператор. Например,


cout << "The sum of 7 + 3 = " << 7 + 3 << "\n";
Всеки следващ изходен оператор може да бъде добавен на

свой ред към cout. За четимост обеднените изходни оператори

могат да се разположат на няколко реда. На следващите три

реда е записан един изходен оператор.

ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ

(ў) Читателят, разполагащ с реализация на С++, която не се

основава на версия 2.0, има по-ранната версия на библиотеката,

наречена stream. Примерите в тази книга използуват

подмножество, общо за двете версии.

ЇЇЇЇЇЇЇЇЇЇЇЇ


ЇЇЇЇЇЇЇЇЇЇЇЇ

7.
cout << "The sum of ";

<< v1 << " + ";

<< v2 << " = " << v1 + v2 << "\n";
Съответно операторът за вход (" >> ") се използува за

четене на стойност от стандартния вход. Например, следната

програма реализира прост алгоритъм за четене на две стойности,

определяне на по-голямата от тях и отпечатването й.


#include
void read2 ( int1&, int2& );

int max( int, int );

void writeMax( int );
main()

{

int val1, val2;


read2( val1, val2 );

int maxVal = max( val1, val2 );

writeMax( maxVal );

return 0;

}
void read2(int& v1, int& v2);

{

cout << "\nPlease enter two numeric values: ";



cin >> v1 >> v2;

}
int max( int v1, int v2);

{

if ( v1 > v2 )



return v1;

else


return v2;

}
viod writeMax( int val )

{

cout << val << " is the largest value.\n";



}
По тази програма могат да бъдат направени няколко

забележки. Описани са три имена на функции преди да бъде

дефинирана функцията main(). Първоначалният списък се нарича

предварителна декларация, съобщаваща на програмата, че тези

функции съществуват и описанията им могат да бъдат намерени

някъде в текста на програмата, представена от този файл или в

ЇЇЇЇЇЇЇЇЇЇЇЇ

ЇЇЇЇЇЇЇЇЇЇЇЇ

8.
отделен файл. Всяка функция трябва да бъде деклакирана преди

да може да бъде викана. Предварителната декларация е един от

начините да се направи това.

val1 и val2 се наричат променливи. Операторът


int val1, val2;
дефинира тези променливи за програмата. И променливите трябва

да бъдат обявени преди да могат да бъдат използувани.

Продробен преглед на променливите е направен в глава 1.

v1 и v2, наричани формални параметри, изграждат

списъка от аргументи на функциите read2() и max(). val е

единствения формален параметър на writeMax(). Същността на

дефиницията им е разгледана в дял 3.6 (стр. 117), където се

обсъжда как се описват параметрите на функции.

Читателят сигурно е забелязал, че main() e описана

малко по-различно този път. Не е описан явно типа на връщания

резултат. Това е разрешено в С++: функция, за която не е

зададен тип за връщане, връща тип цяло число по подразбиране.

Когато програмата бъде компилирана и изпълнена се

получава следния изход (потребителят е въвел стойностите 17 и

124):
Please enter two numeric values: 17 124

124 is the largest value.


Двете стойности, 17 и 124, са разделени с интервал.

Интервалите, табулациите и новите редове са празно

пространство (white space) за С++. Операторът
cin >> v1 >> v2;
правилно чете двете стойности, защото операторът за изход

(">>") пропуска цялото празно пространство, което е въведено.

Предварителната дефиниция на cin и cout се съдържа в

stream.h. Ако програмистът забрави да включи този файл, всички

обръщения към cin и cout ще бъдат отбелязани от компилатора

като грешки. Включването на предварителните декларации показва

първичната употреба на заглавния файл. ( Част 4.5 (стр. 173)

разглежда заглавните файлове в подробности).

Съществува и един трети вх/изх. поток, cerr (произнася

се "see-err"), наречен стандартна грешка, който също се

свързва с потребителския терминал. cerr се използува за да

уведомява потребителя относно някои особени състояния на

програмата по време на изпълнение. Например, следната част от

програма предпазва програмиста от деление на нула:

ЇЇЇЇЇЇЇЇЇЇЇЇ

ЇЇЇЇЇЇЇЇЇЇЇЇ

9.
if (v2 == 0 )

{ cerr << "\nerror: attempt to divide by zero";

return;

}

v3 = v1/v2;


Следващата програма чете по един символ от стандартния

вход докато не срещне end-of-file. Тя брои прочетените редове

и символи. Изходът й има следния вид:
lineCount characterCount
Описанието й има вида:
#include
main()

{ char ch;

int lineCnt=0, charCnt=0;
while ( cin.get(ch) )

{ switch ( ch )

{ case '\t':

case ' ' : break;

case '\n': ++lineCnt;

break;


default : ++charCnt;

break;


}

}

cout << lineCnt << " " << "\n";



return 0;

}
get() е функция, принадлежаща на вх/изх. поток, която

чете символ и го записва като свой аргумент - в този случай,

ch. Последователността от два символа \n представя символа

tab.

Операторът switch сигурява условен преход според



стойността на селектора си. Ако стойността му съвпада с

някой от описаните след думата case стойности, се изпълнява

оператора, съответствуващ на тази стойност. Ако съответствие

не може да бъде намерено, се изпълняват операторите, записани

след default. За всеки прочетен символ за нов ред се увелчава

стойността на lineCnt с 1. charCnt се увеличава с 1 всеки път,

когато е прочетен символ, който не е табулатор, интервал или

нов ред.


Операторът while, наричан оператор за цикъл, осигурява

ЇЇЇЇЇЇЇЇЇЇЇЇ


ЇЇЇЇЇЇЇЇЇЇЇЇ

10.
многократно изпълнение на група от оператори докато някакво

условие има стойност истина. В този случай, операторът switch

се изпълнява докато get() чете символ от стандартния вход.

(Операторите while и switch са описани в глава 5).


Упражнение 0-1. Въведете програмата във файл prog2.c и я

компилирайте в изпълним файл, наречен prog2.


Упражнение 0-2. Изпълнете програмата с текста на предишното

упражнение. Изпълнете я отново с текст, съдържащ само празни

интервали. Изпълнете я за текст, съдържащ само знака

end-of-file.


Упражнение 0-3. Преработете програмата така, че да брои

табулаторите (tabCnt) и интервалите (blankCnt). Нека изходът

да изглежда така.
Total Characters: xx
Lines: x

Chars: x


Tabs: x

Blanks: x

0.4. Няколко думи за коментарите
Коментарите се пишат за да подпомагат четенето на

програмите. Те могат да поясняват алгоритъма на функцията, да

описват употребата на променливите или да поясняват други

аспекти по текста на програмата. Коментарите не увеличават

размера на изпълнимата програма. Те се отстраняват от

компилатора преди генерацията на кода.

В С++ са дефинирани два типа коментари. Двойката ("/*

*/") описва коментарите в езика С. Началото на коментара се

определя чрез "/*". Всичко, което следва тези символи ще бъде

трерирано от компилатора като коментар до срещането на

символите "*/". Коментар може да бъде поставян там, където

могат да се поставят тавулатори, интервали или символи за нов

ред и той може да заема няколко реда от програмата. Например,

ЇЇЇЇЇЇЇЇЇЇЇЇ


ЇЇЇЇЇЇЇЇЇЇЇЇ

11.

/*

* This is a first look at a C++ class definition.



* Classes are used both in data abstraction and

* object-oriented programming. An implementation

* of the Screen class is presented in Chapter 5.

*/
class Screen

{

/* This is referred to as the class body */



public:

void home(); /* move cursor to 0,0 */

void refresh(); /* redraw Screen */

private:


/* Classes support ``information hiding''. */

/* Information hiding restricts a program's */

/* access to the internal representation of */

/* a class (its data). This is done through */

/* use of the ``private:'' label */
char *cursor; /* current Screen position */
};
Многото коментари, раположени хаотично в пограмния

код, могат да напрвят текста неясен. Например, обградената с

коментари дефиниция на cursor почти я скрива. Изобщо, за

предпочитане е коментарът да се помества в цялостен блок над

текста, който пояснява.

Коментарите не могат да бъдат влагани. Т.е., коментар

не може да се поставя във вътрешността на друг коментар.

Въведете програмата, написана по-нататък в текста. Тя ще

предизвика генерирането на серия от грешки. Как бихте могли да

се справите с това?


#include
/*

* comment pairs /* */ do not nest.

* "do not nest" is considerd sourse code,

* as are both these lines and the next.

*/
main()

{

cout << "hello, world\n";



}
Вторият тип коментари се означава чрез двойката

символи //, ограничаващи коментар от един ред. Текстът,

записан от дясно на този ограничител, се третира като коментар

и се игнорира от компилатора. Например,

ЇЇЇЇЇЇЇЇЇЇЇЇ

ЇЇЇЇЇЇЇЇЇЇЇЇ

12.
#include

#include "myIO.h"

int isOdd( int );
main()

{

int v1, v2; // hold values from user


read2( v1, v2 ); // declared in myIO.h
if ( isOdd( v1 ) == 1 )

cout << v1



<< " is odd\n";
if ( isOdd( v2 ) == 1 )

cout << v2



<< " is odd\n";
return 0;

}
isOdd( int val )

{

/* return 1 if val is odd; otherwise, return 0



* % is the modulus operator; 3 % 2 yields 1. */
return( val % 2 != 0 );

}
Тази програма определя дали стойностите са четни или

нечетни. Тя използува функцията read2(), дефинирана в

предходния подраздел. Прототипът на тази функция е зададен в

заглавния файл myIO.h. Когато програмата бъде компилирана и

изпълнена, ще бъде изведено следното (стойностите 497 и -25 са

въведени от потребителя):
Please enter two numeric values: 497 -25

497 is odd

-25 is odd
Двойката символи, ограничаваща коментарите, не може да

бъдат разделяни с интервал. Следните два реда, например, няма

да бъдат разглеждани като коментари, а по-скоро като част от

програмния текст:


/ * not a comment: white space not allowed */

/ / also not a comment: must be //


Обикновено програмите съдържат както единия тип

коментари, така и другия. Обширните разяснения най-често се

организират в коментар като се използува двойката коментарни

ограничители. За бележки, разположени на половин или един ред

се използуват символите //.

ЇЇЇЇЇЇЇЇЇЇЇЇ


ЇЇЇЇЇЇЇЇЇЇЇЇ

13.
0.5. Директиви на предпроцесора
Редом със стандартните библиотеки се предлага набор от

стандартни заглавни файлове, такива като stream.h. Тези

заглавни файлове съдържат цялата информация, необходма на

потребителя, за да използува лесно библиотеките. За да имаме

достъп до променливите и функциите, дефинирани в тези

библиотеки, ние трябва да включим съответния заглавен файл в

нашата програма.

Заглавните файлове стават част от нашата програма като

се използува директивата include. Директивите се определят

като се постави знака # в първата колона от реда в нашата

програма. Директивите се обработват преди извикването на

езиковия компилатор. Програмата, която обработва директивите

се нарича предпроцесор.

Директивата #include чете от съдържанието на именован

файл. Тя има един от следните два формата:
#include

#include "myIO.h"


Ако името на файла е затворено в ъглови скоби ("<>")

се подразбира, че файлът е преаварително дефиниран, или

стандартен, заглавен файл. Търсенето за откриването му ще бъде

проведено в предварително дефинирано множество от

местоположения, което може да бъде променяно чрез опцията -I

на командата СС.(ў) Например, командата


$ CC -I incl -I/usr/local/include prog1.c
указва на предпроцесора да потърси първо в директория incl, а

после в /usr/local/include, преди да преглежда предварително

дефинираното множество от местоположения. При първият открит

екземпляр на файла се преустановява търсенето.

Ако името на файла е затворено в двойни кавички се

подразбира, че това е заглавен файл, създаден от потребителя.

Търсенето му започва от текущата директория. Ако не бъде

намерен там се преглежда множеството на предварително

дефинираните местоположения. Опцията -I също работи със

заглавни файлове, дефинирани от потребителя.

Всеки включен файл може също да съдържа директива

#include. Поради това е възможно даден заглавен файл да бъде

включен неколкократно в изходен файл. Могат да бъдат

използувани условни директиви за да се предотврати

многократната обработка на даден заглавен файл. Например,
#ifndef STRING_H

#define STRING_H

/* String.h contents go here */

#endif
Условната директива #ifndef приема стойност истина, когато

ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ

(ў) Тези, които използуват друга реализация на С++, трябва да

направят справка за съответната командна опция.

ЇЇЇЇЇЇЇЇЇЇЇЇ


ЇЇЇЇЇЇЇЇЇЇЇЇ

14.
името, което следва не е дефинирано все още. Когато условната

директива приеме стойност true съвкупността от редове до

#endif се считат включени. Ако условната директива приеме

стойност false, тези редове ще бъдат игнорирани.

Директивата #define дефинира името, което я следва. В

този случай тя дефинира STRING_H. Ако заглавият файл String.h

се включва отново директивата #ifndef ще приеме стойност false

и съдържанието на Stream.h нъма да бъде включено повторно.

Директивата #ifdef приема стойност true, когато името,

записано след нея, е дефинирано. Например,


#ifdef u3b2

/* system specific code

* for AT&T 3B ocmputers goes here */

#endif
#ifdef sun

/* system spesific code

* for Sun computers goes here */

#endif
С++ предварително дефинира името __cplusplus (две подчертаващи

тиренца). Потребител, който желае да смесва програми, написани

на С и С++, трябва да запише следното:
#ifdef __cplusplus

extern min( int, int );

int *pi = new int;

#else


extern min();

int *pi;


#endif
Операторите между директивите #else и #endif ще бъдат

включени ако директивата #ifdef приеме стойност true.

Педпроцесорът е тясно свързан с езика С (често се

нарича cpp, С - придпроцесор). Много реализации просто

използуват предпроцесора на С и следователно не разпознават

коментара на С++, ограничаван от //. Ако желаете да включите

коментар в директива #define по-безопасно е да използувате

обичайния за С коментар.


#ifdef u3b2

#define SYSV /* UNIX System V */

#endif

ЇЇЇЇЇЇЇЇЇЇЇЇ



ЇЇЇЇЇЇЇЇЇЇЇЇ

15.

  1   2   3   4   5   6   7   8   9   ...   19


База данных защищена авторским правом ©obuch.info 2016
отнасят до администрацията

    Начална страница