Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Программирование основы языка С++. Учебное пособие
.pdf
Это интересно! Джон Маккарти (4 сентября 1927,
Бостон – 24 октября 2011, Стэнфорд) – американский
информатик, автор термина «искусственный интеллект» (1955), изобретатель языка Лисп (1958), основоположник функционального программирования, лауреат премии Тьюринга (1971) за огромный вклад в область исследований искусственного интеллекта. Член
Национальной академии наук США (1989). У Маккарти
рано проявились склонности к математике, в юности он самостоятельно изучал
ее по университетским учебникам, которые использовались в расположенном неподалеку Калифорнийском технологическом институте. В результате, поступив
в университет, он смог сразу пропустить два первых года по математике. В 1948
году получил степень бакалавра математики в Калифорнийском технологическом
институте и степень Ph.D. по математике в Принстоне в 1951 году. После кратковременных должностей в Принстонском и Стэнфордском университетах,
Дартмутском колледже и Массачусетском технологическом институте, он стал
профессором в Стэнфорде в 1962 году, где он и оставался до своего ухода на пенсию
в конце 2000-го. Маккарти отстаивал использование математической логики для
искусственного интеллекта. В 1958 году он предложил систему «принятия советов», которая позже вдохновила работы по ответам на запросы и логическому
программированию. В том же году он изобрел язык программирования Лисп и опубликовал его описание в журнале Communications of the ACM в апреле 1960 г. В 1961
году Джон Маккарти публично предположил, что компьютерная технология разделения времени может привести к будущему, в котором компьютерная мощь и
даже определенные приложения могут продаваться с использованием бизнес-модели сферы услуг (подобно воде или электричеству). Эта идея компьютерных или
информационных услуг была очень популярна в конце 1960 годов, но вышла из моды
к середине 1970 годов, так как стало ясно, что аппаратные, программные и коммуникационные технологии того времени были просто еще не готовы к этому. Тем
не менее, начиная с 2000 года, эта идея вновь объявилась, всплыв на поверхность в
новых формах.
Особенности. Основной особенностью функционального программирования, определяющей как преимущества, так и недостатки данной
парадигмы, является то, что в ней реализуется модель вычислений без
состояний. Если императивная программа на любом этапе исполнения
имеет состояние, то есть совокупность значений всех переменных, и
производит побочные эффекты, то чисто функциональная программа ни
целиком, ни частями состояния не имеет и побочных эффектов не про-
21

изводит. То, что в императивных языках делается путем присваивания
значений переменным, в функциональных достигается путем передачи
выражений в параметры функций. Непосредственным следствием становится то, что чисто функциональная программа не может изменять
уже имеющиеся у нее данные, а может лишь порождать новые путем
копирования и/или расширения старых. Следствием того же является
отказ от циклов в пользу рекурсии.
Достоинства функциональной парадигмы программирования
1. Повышение надежности кода – повышение надежности кода за
счет четкой структуризации и отсутствия необходимости отслеживания
побочных эффектов. Любая функция работает только с локальными данными и работает с ними всегда одинаково, независимо от того, где, как
и при каких обстоятельствах она вызывается. Невозможность мутации
данных при пользовании ими в разных местах программы исключает появление трудно обнаруживаемых ошибок (таких, например, как
случайное присваивание неверного значения глобальной переменной
в императивной программе).
2. Удобство организации модульного тестирования – поскольку
функция в функциональном программировании не может порождать
побочные эффекты, менять объекты нельзя как внутри области видимости, так и снаружи (в отличие от императивных программ, где одна
функция может установить какую-нибудь внешнюю переменную, считываемую второй функцией). Единственным эффектом от вычисления
функции является возвращаемый ей результат, и единственный фактор,
оказывающий влияние на результат – это значения аргументов. Таким
образом, имеется возможность протестировать каждую функцию в программе, просто вычислив ее от различных наборов значений аргументов.
При этом можно не беспокоиться ни о вызове функций в правильном
порядке, ни о правильном формировании внешнего состояния. Если
любая функция в программе проходит модульные тесты, то можно быть
уверенным в качестве всей программы. В императивных программах
проверка возвращаемого значения функции недостаточна: функция
может модифицировать внешнее состояние, которое тоже нужно проверять, чего не нужно делать в функциональных программах.
3. Возможности оптимизации при компиляции – позволяет описывать программу в так называемом «декларативном» виде, когда жесткая
последовательность выполнения многих операций, необходимых для
вычисления результата, в явном виде не задается, а формируется авто-
22

матически в процессе вычисления функций. Это обстоятельство, а также
отсутствие состояний дает возможность применять к функциональным
программам достаточно сложные методы автоматической оптимизации.
4. Возможности параллелизма – программы на функциональном
языке предоставляют широчайшие возможности для автоматического распараллеливания вычислений. Поскольку отсутствие побочных
эффектов гарантировано, в любом вызове функции всегда допустимо
параллельное вычисление двух различных параметров – порядок их
вычисления не может оказать влияния на результат вызова.
Недостатки функциональной парадигмы программирования
Недостатки функционального программирования вытекают из тех
же самых его особенностей. Отсутствие присваиваний и замена их на
порождение новых данных приводят к необходимости постоянного выделения и автоматического освобождения памяти, поэтому в системе
исполнения функциональной программы обязательным компонентом
становится высокоэффективный сборщик мусора. Нестрогая модель вычислений приводит к непредсказуемому порядку вызова функций, что
создает проблемы при вводе-выводе, где порядок выполнения операций
важен. Кроме того, очевидно, функции ввода в своем естественном виде
(например, getchar из стандартной библиотеки языка C) не являются чистыми, поскольку способны возвращать различные значения для одних
и тех же аргументов, и для устранения этого требуются определенные
ухищрения. Для преодоления недостатков функциональных программ
уже первые языки функционального программирования включали не
только чисто функциональные средства, но и механизмы императивного
программирования (присваивание, цикл, «неявный PROGN» были уже
в Лиспе). Использование таких средств позволяет решить некоторые
практические проблемы, но означает отход от идей (и преимуществ)
функционального программирования и написание императивных программ на функциональных языках. В чистых функциональных языках
эти проблемы решаются другими средствами, например, в языке Haskell
ввод-вывод реализован при помощи монад – нетривиальной концепции, позаимствованной из теории категорий.
23

РАЗДЕЛ 2
ИСТОРИЯ ПОЯВЛЕНИЯ ЯЗЫКА ПРОГРАММИРОВАНИЯ С++
C++ – компилируемый, статически типизированный язык программирования общего назначения. Поддерживает такие парадигмы
программирования как процедурное программирование, объектноориентированное программирование, обобщенное программирование,
обеспечивает модульность, раздельную компиляцию, обработку исключений, абстракцию данных, объявление типов (классов) объектов,
виртуальные функции. Стандартная библиотека включает, в том числе,
общеупотребительные контейнеры и алгоритмы. C++ сочетает свойства
как высокоуровневых, так и низкоуровневых языков. В сравнении с его
предшественником – языком C, – наибольшее внимание уделено поддержке объектно-ориентированного и обобщенного программирования.
C++ широко используется для разработки программного обеспечения, являясь одним из самых популярных языков программирования.
Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов устройств, приложений
для встраиваемых систем, высокопроизводительных серверов, а также
развлекательных приложений. Существует множество реализаций языка
C++, как бесплатных, так и коммерческих и для различных платформ.
Язык программирования С++ был создан в начале 1980-х годов,
его создатель сотрудник фирмы Bell Laboratories – Бьерн Страуструп.
Он придумал ряд усовершенствований к языку программирования C,
для собственных нужд. Т. е. изначально не планировалось создания
языка программирования С++. Ранние версии языка С++, известные
под именем «Cи с классами», начали появляться с 1980 года. Язык C,
будучи базовым языком системы UNIX, на которой работали компьютеры фирмы Bell, является быстрым, многофункциональным и переносимым. Страуструп добавил к нему возможность работы с классами
и объектами, тем самым зародил предпосылки нового, основанного на
синтаксисе С, языка программирования. Синтаксис C++ был основан
на синтаксисе C, так как Бьерн Страуструп стремился сохранить совместимость с языком C.
Развитие. Первое издание «Языка программирования C++» вышло
в 1985 году. Обеспечивает первое описание этого языка, что было важно
24

из-за отсутствия официального стандарта. В 1989 году вышла версия 2.0
языка C++. Его новые возможности включали множественное наследование, абстрактные классы, статические функции-члены, функции-константы и защищенные члены. В 1990 году вышло «Комментированное
справочное руководство по C++», положенное впоследствии в основу
стандарта. Последние обновления включали шаблоны, исключения,
пространства имен, новые способы приведения типов и логический
тип. В 1998 году был опубликован стандарт языка ISO/IEC 14882:1998
(известный как C++98), разработанный комитетом по стандартизации
C++ (ISO/IEC JTC1/SC22/WG21 working group). Стандарт состоит из
двух частей – основы языка (core language) и стандартной библиотеки
языка, которая включает Standard Template Library (STL) и модифицированный вариант стандартной библиотеки языка C. В 2003 году был
опубликован стандарт языка ISO/IEC 14882:2003, где были исправлены
выявленные ошибки и недочеты предыдущей версии стандарта. В 2005
году был выпущен отчет Library Technical Report 1. Отчет описывает
расширения стандартной библиотеки, которые, должны быть включены в следующую версию языка C++. С 2009 года велась работа по
обновлению предыдущего стандарта, предварительной версией нового
стандарта сперва был C++09, а спустя год C++0x, сегодня – C++11, куда
были включены дополнения в ядро языка и расширение стандартной
библиотеки.
Название. Название C++ придумал Рик Масситти. Название указывает на эволюционную природу перехода к нему от C. "++" – это
операция приращения в C. Чуть более короткое имя C+ является синтаксической ошибкой; кроме того, оно уже было использовано как имя
совсем другого языка. Знатоки семантики C находят, что C++ хуже, чем
++C. Названия D язык не получил, поскольку он является расширением
C и в нем не делается попыток исцеляться от проблем путем выбрасывания различных особенностей.
Объектно-ориентированные особенности. C++ добавляет к C объектно-ориентированные возможности. Он вводит классы, которые
обеспечивают три самых важных свойства ООП: инкапсуляцию, наследование и полиморфизм. Методы класса – это функции, которые
смогут применяться к экземплярам класса, то есть метод – это функция
объявленная внутри класса и предназначенная для работы с его объектами. Методы объявляются в теле класса. Описываться могут там же, но
могут и за пределами класса (внутри класса в таком случае достаточно
25

представить прототип метода, а за пределами класса определять метод
поставив перед его именем – имя класса и оператор ::). Методы и поля
входящие в состав класса называются членами класса. При этом методы
часто называют функциями-членами класса.
Наследование. В C++ при наследовании одного класса от другого
наследуется реализация класса, плюс класс-наследник может добавлять
свои поля и функции или переопределять функции базового класса.
Множественное наследование разрешено. Конструктор наследника
вызывает конструкторы базовых классов, а затем конструкторы нестатических членов-данных, являющихся экземплярами классов. Деструктор
работает в обратном порядке. Наследование бывает публичным, защищенным и закрытым.
Полиморфизм. Целью полиморфизма, применительно к объектно-ориентированному программированию, является использование
одного имени для задания общих для класса действий. Выполнение
каждого конкретного действия будет определяться типом данных.
Преимуществом полиморфизма является то, что он помогает снижать
сложность программ, разрешая использование того же интерфейса для
задания единого класса действий. Выбор же конкретного действия, в
зависимости от ситуации, возлагается на компилятор. Полиморфизм
может применяться также и к операторам.
Инкапсуляция. Основным способом организации информации в
C++ являются классы. В отличие от структуры (struct) языка C, которая может состоять только из полей и вложенных типов, класс (class)
C++ может состоять из полей, вложенных типов и функций-членов.
Инкапсуляция в С++ реализуется через указание уровня доступа к членам класса: они бывают публичными (public), защищенными (protected)
и закрытыми (private). В C++ структуры отличаются от классов тем,
что по умолчанию члены и базовые классы у структуры публичные, а у
класса – собственные.
Стандартная библиотека. В языке программирования C++ термин
Стандартная Библиотека означает коллекцию классов и функций, написанных на базовом языке. Стандартная Библиотека поддерживает несколько основных контейнеров, функций для работы с этими контейнерами, объектов-функции, основных типов строк и потоков (включая интерактивный и файловый ввод-вывод), поддержку некоторых языковых
особенностей, и часто используемые функции для выполнения таких задач, как, например, нахождение квадратного корня числа. Стандартная
26

Библиотека языка C++ также включает в себя спецификации стандарта
ISO C90 стандартной библиотеки языка Си. Функциональные особенности Стандартной Библиотеки объявляются внутри пространства
имен std. Стандартная библиотека шаблонов (STL) – подмножество
стандартной библиотеки C++ и содержит контейнеры, алгоритмы,
итераторы, объекты-функции и т. д. Заголовочные файлы стандартной
библиотеки C++ не имеют расширения «.h». Стандартная библиотека
C++ содержит последние расширения C++ стандарта ANSI (включая
библиотеку стандартных шаблонов и новую библиотеку iostream). Она
представляет собой набор файлов заголовков. Отличия С++ от С показаны на рисунке 2.1.
Рисунок 2.1 – Основные отличия языка С++ от С
В С++ не разрешается:
вызывать функцию main() внутри программы, в то время как в C
•
это действие правомерно;
неявное приведение типов между несвязанными типами указателей;
•
использовать функции, которые еще не объявлены.
•
Достоинства и недостатки. С++ – язык, складывающийся эволюци-
онно. Каждый элемент С++ заимствовался из других языков отдельно
и независимо от остальных элементов (ничто из предложенного С++ за
всю историю его развития не было новшеством в Computer Science), что
сделало язык чрезвычайно сложным, со множеством дублирующихся и
27

взаимно противоречивых элементов, блоки которых основаны на разных формальных базах. Критики С++ не противопоставляют ему какойлибо конкретный язык, а наоборот, утверждают, что для всякого случая
применения С++ всегда существует альтернативный инструментарий,
позволяющий решить ту же задачу более эффективно и качественно.
В свою очередь, сторонники С++ считают некорректным сравнивать
различные аспекты С++ с совершенно различными языками, так как
общий набор средств и возможностей С++ существенно шире, чем в
большинстве языков, с которыми проводится сравнение, и сама по себе
широта возможностей, на их взгляд, является веским оправданием несовершенства каждой отдельно взятой возможности. Более того, по их
мнению, высокая совместимость с Си является одной из принципиальных черт языка, и потому все недостатки С++ оправданы преимуществами, предоставляемыми этой совместимостью. Основные достоинства и
недостатки приведены в таблице 2.1.
Таблица 2.1 – основные достоинства и недостатки С++
Достоинства Недостатки
Высокая совместимость с языком Си
Вычислительная производительность
Поддержка различных стилей программирования
структурное
объектно-ориентированное
обобщенное программирование
функциональное программирование
порождающее метапрограммирование
Автоматический вызов деструкторов
объектов упрощает и повышает надежность управления памятью и другими
ресурсами
Перегрузка операторов
Шаблоны
Возможность расширения языка для
поддержки парадигм, которые не поддерживаются компиляторами напрямую
Доступность
Плохо продуманный синтаксис сужает спектр применимости языка
Язык не содержит многих важных
возможностей
Язык содержит опасные возможности
Производительность труда программистов на языке оказывается неоправданно низка
Громоздкость синтаксиса
Тяжелое наследие
Необходимость следить за памятью
28

РАЗДЕЛ 3
БАЗОВЫЕ ПОНЯТИЯ С++
Любая программа должно отвечать следующим критериям качества:
корректность – программа должна работать правильно;
•
надежность – программа не должна «зависать» или «зацикливаться»
•
при любых исходных данных;
эффективность – программа должна использовать, по возможности,
•
минимальное количество ресурсов, как по памяти, так и по времени;
эргономичность – удобство для пользователя;
•
читабельность – удобство для программиста;
•
переносимость – программа должна работать на любых устройствах.
•
3.1 Состав языка
В тексте на любом естественном языке можно выделить четыре
основных элемента: символы, слова, словосочетания и предложения.
Подобные элементы содержит и алгоритмический язык, только слова
называют лексемами (элементарными конструкциями), словосочетания – выражениями, а предложения – операторами. Лексемы образуются из символов, выражения – из лексем и символов, а операторы – из
символов, выражений и лексем:
алфавит языка, или его символы – это основные неделимые знаки,
•
с помощью которых пишутся все тексты на языке;
лексема, или элементарная конструкция, – минимальная единица
•
языка, имеющая самостоятельный смысл;
выражение задает правило вычисления некоторого значения;
•
оператор задает законченное описание некоторого действия.
•
3.2 Структура программы на С++
Программа на языке С/С++ состоит из:
Директив препроцессора
•
Описаний
•
Функций
•
Главная функция носит имя main и должна быть обязательно. Общую
структуру программы на языке С/С++ можно представить следующим
29

образом:
директивы препроцессора //1
описание глобальных переменных //2
тип_результата main (параметры) //3
{
тело главной функции
}
тип_результата F1 (параметры 1) {
тело функции F1;
}
тип_результата F2 (параметры 2) {
тело функции F2;
}
тип_результата FN (параметры N) {
тело функции FN;
}
Директивы препроцессора – определяют действия по преобразованию программы перед компиляцией, а также включают инструкции,
которым компилятор следует во время компиляции;
Объявления – описания переменных, функций, структур, классов
и типов данных;
Описание функций, выполняемых в проекте. В языке С++ существует только один вид подпрограмм – подпрограмма-функция. Функция
состоит из заголовка и тела функции. Заголовок состоит из: типа ре-
зультата, возвращаемого функцией; имени функции; списка параметров,
необходимых для выполнения функции. Тело функции заключается в опера-
торные скобки {}, и содержит описание локальных данных и операторы
функции:
тип_результата имя_функции (параметры)
{
описание данных;
оператор1;
оператор2;
30
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
