Когда был разработан язык c. §1 Общие сведения о языке

C++ (читается си-плюс-плюс) - компилируемый, статически типизированный язык программирования общего назначения, на котором можно создавать программы любого уровня сложности.
Более 20 лет этот язык находится в тройке самых популярных и востребованных языков программирования. (В этом можно убедиться, посетив сайт TIOBE).
Язык возник в начале 1980-х годов, когда сотрудник фирмы Bell Labs Бьёрн Страуструп придумал ряд усовершенствований к языку C под собственные нужды.

Bjarne Stroustrup – создатель языка C++

Страуструп решил дополнить язык C возможностями, имеющимися в языке Симула . Язык C, будучи базовым языком системы UNIX, на которой работали компьютеры Bell, является быстрым, многофункциональным и переносимым. Страуструп добавил к нему возможность работы с классами и объектами. В результате практические задачи моделирования оказались доступными для решения как с точки зрения времени разработки (благодаря использованию Симула-подобных классов), так и с точки зрения времени вычислений (благодаря быстродействию C).
Вот как об этом говорит сам разработчик языка:



В 1998 году был опубликован первый стандарт языка, известный как C++98, разработанный комитетом по стандартизации. C++ продолжает развиваться, чтобы отвечать современным требованиям. Одна из групп, разрабатывающих язык C++ и направляющих комитету по стандартизации C++ предложения по его улучшению - это Boost , которая занимается, в том числе, совершенствованием возможностей языка путём добавления в него особенностей метапрограммирования. Последний стандарт вышел в 2017 году и носит наименование С++17 . Следующий стандарт не заставит себя долго ждать и появится, как ожидают, в 2020 году.
Никто не обладает правами на язык C++, он является свободным. В марте 2016 года в России была создана рабочая группа РГ21 С++. Группа была организована для сбора предложений к стандарту C++, отправки их в комитет и защиты на общих собраниях Международной организации по стандартизации.
С++ – это мультипарадигмальный язык (от слова парадигма – стиль написания компьютерных программ), включающий широкий спектр различных стилей и технологий программирования. Часто его причисляют к объектно-ориентированным языкам, но, строго говоря, это не так. В процессе работы разработчик получает абсолютную свободу в выборе инструментов для того, чтобы задача, решаемая с помощью того или иного подхода, была решена максимально эффективно. Иными словами, С++ не понуждает программиста придерживаться только одного стиля разработки программы (например, объектно-ориентированного).
C++ имеет богатую стандартную библиотеку, которая включает в себя распространённые контейнеры и алгоритмы, ввод-вывод, регулярные выражения, поддержку многопоточности и другие возможности. C++ повлиял на многие языки программирования, в их числе: Java, C#, D. Посукольку C++ принадлежит семейству языков основанных на синтаксисе языка Си, то можно легко освоить и другие языки программирования этого семейства: JavaScript, PHP, Perl, Objective-C и мн. др., в том числе, и сам родительский язык – Си. ()
За время своего существования за языком С++ закрепились устойчивые мифы, которые легко опровергаются (см. здесь: Часть1 и Часть2)

История языка и выхода стандартов

  • 1983
  • создатель языка – Бьёрн Страуструп , сотрудник Bell Labs, представил раннюю версию языка C++ (“Си с классами”)

  • 1985
  • первый коммерческий выпуск C++, язык приобретает современное название

  • 1986
  • выпуск первого издания The C++ Programming Language - книги, посвящённой C++, которую написал Бьёрн Страуструп

  • 1998
  • ратифицирован международный стандарт языка C++: ISO/IEC 14882:1998 «Standard for the C++ Programming Language»

  • 2003
  • 2005
  • выпущен отчёт Library Technical Report 1 (TR1). Не являясь официально частью стандарта, отчёт описывал расширения стандартной библиотеки, которые должны быть включены в следующую версию языка C++

  • 2011
  • выход нового стандарта – C++11 или ISO/IEC 14882:2011; новый стандарт включил дополнения в ядре языка и расширение стандартной библиотеки, в том числе большую часть TR1

  • 2014
  • выход стандарта C++14 («International Standard ISO/IEC 14882:2014(E) Programming Language C++»); C++14 можно рассматривать как небольшое расширение над C++11, содержащее в основном исправления ошибок и небольшие улучшения

  • 2017
  • выход нового стандарта – C++1z (C++17). Этот стандарт внес много изменений и дополнений. Например, в состав STD вошли библиотеки стандарта C11, файловой системы, основанная на boost::filesystem, большая часть экспериментальной библиотеки TS I.

Философия С++

В книге «Дизайн и эволюция C++» (2007) Бьёрн Страуструп описывает принципы, которых он придерживался при проектировании C++ (приводятся в сокращении):

  • Получить универсальный язык со статическими типами данных, эффективностью и переносимостью языка C.
  • Непосредственно и всесторонне поддерживать множество стилей программирования.
  • Дать программисту свободу выбора, даже если это даст ему возможность выбирать неправильно.
  • Максимально сохранить совместимость с C, тем самым делая возможным лёгкий переход от программирования на C.
  • Избежать разночтений между C и C++: любая конструкция, допустимая в обоих языках, должна в каждом из них обозначать одно и то же и приводить к одному и тому же поведению программы.
  • Избегать особенностей, которые зависят от платформы или не являются универсальными.
  • «Не платить за то, что не используется» - никакое языковое средство не должно приводить к снижению производительности программ, не использующих его.
  • Не требовать слишком усложнённой среды программирования.

C и C++

Синтаксис C++ унаследован от языка C. Хотя, формально, одним из принципов C++ остаётся сохранение совместимости с языком C, фактически группы по стандартизации этих языков не взаимодействуют, а вносимые ими изменения не только не коррелируют, но и нередко принципиально противоречат друг другу идеологически. Так, элементы, которые новые стандарты C добавляют в ядро, в стандарте C++ являются элементами стандартной библиотеки и в ядре вообще отсутствуют, например, динамические массивы, массивы с фиксированными границами, средства параллельной обработки. Как считает Страуструп, объединение разработки этих двух языков принесло бы большую пользу, но оно вряд ли возможно по политическим соображениям. Так что практическая совместимость между C и C++ постепенно будет утрачиваться.
В данном примере, в зависимости от используемого компилятора, будет выведено либо “C++”, либо “C”:

#include int main() { printf("%s\n", (sizeof("a") == sizeof(char)) ? "C++" : "C"); return 0; }

Связано это с тем, что символьные константы в C имеют тип int , а в C++ - тип char , но размеры этих типов различаются.

Модели жизненного цикла приложения

Жизненный цикл программного обеспечения - это период времени, который начинается с момента принятия решения о необходимости создания программного продукта и заканчивается в момент его полного изъятия из эксплуатации. Этот цикл - процесс построения и развития программного обеспечения (ПО). Существует несколько моделей жизненного цикла.
Каскадная модель жизненного цикла (англ. waterfall model) была предложена в 1970 г. Уинстоном Ройсом. Она предусматривает последовательное выполнение всех этапов проекта в строго фиксированном порядке. Переход на следующий этап означает полное завершение работ на предыдущем этапе. Требования, определенные на стадии формирования требований, строго документируются в виде технического задания и фиксируются на все время разработки проекта. Каждая стадия завершается выпуском полного комплекта документации, достаточной для того, чтобы разработка могла быть продолжена другой командой разработчиков.
Этапы проекта в соответствии с каскадной моделью:

  1. Формирование требований;
  2. Проектирование;
  3. Реализация;
  4. Тестирование;
  5. Внедрение;
  6. Эксплуатация и сопровождение.

В каскадной модели переход от одной фазы проекта к другой предполагает полную корректность результата предыдущей фазы. В больших проектах этого добиться практически невозможно. Поэтому такая модель пригодна только для разработки небольшого проекта. (Сам У. Ройс не придерживался данной модели и использовал модель итерационную).
Итерационная модель
Альтернативой каскадной модели является модель итеративной и инкрементальной разработки (англ. iterative and incremental development, IID), получившей от Т. Гилба в 70-е гг. название эволюционной модели. Модель IID предполагает разбиение жизненного цикла проекта на последовательность итераций, каждая из которых напоминает «мини-проект», включая все процессы разработки в применении к созданию меньших фрагментов функциональности, по сравнению с проектом в целом. Цель каждой итерации - получение работающей версии программной системы, включающей функциональность, определённую интегрированным содержанием всех предыдущих и текущей итерации. Результат финальной итерации содержит всю требуемую функциональность продукта. Таким образом, с завершением каждой итерации продукт получает приращение - инкремент - к его возможностям, которые, следовательно, развиваются эволюционно.

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

Государственный стандарт подробно описывает жизненный цикл приложения в ГОСТ Р ИСО/МЭК 12207-2010 «Информационная технология. Системная и программная инженерия. Процессы жизненного цикла программных средств» . Этот стандарт принят Федеральным агентством по техническому регулированию и метрологии РФ и аналогичен международному стандарту ISO/IEC 12207:2008. Данный стандарт, устанавливает общую структуру процессов жизненного цикла программных средств, на которую можно ориентироваться в программной индустрии. Стандарт не предлагает конкретную модель жизненного цикла. Его положения являются общими для любых моделей жизненного цикла, методов и технологий создания ПО. Он описывает структуру процессов жизненного цикла, не конкретизируя, как реализовать или выполнить действия и задачи, включенные в эти процессы.

Процесс разработки – Rational Unified Process (RUP)

Различные варианты итерационного подхода реализованы в большинстве современных методологий разработки:

Rational Unified Process (RUP) (рациональный унифицированный процесс) - методология разработки программного обеспечения, которая поддерживается компанией Rational Software (IBM). В методологии даются рекомендации по всем этапам разработки: от моделирования бизнеса до тестирования и сдачи в эксплуатацию готовой программы. В качестве языка моделирования используется язык Unified Modelling Language (UML).
Полный жизненный цикл разработки продукта состоит из четырех фаз, каждая из которых включает в себя одну или несколько итераций.

  • Начальная стадия (Inception)
  • Определение масштабов проекта и объема необходимых ресурсов. Определяются основные требования, ограничения и ключевая функциональность продукта. Оцениваются риски. Планирование действий. При завершении начальной фазы оценивается достижение этапа жизненного цикла цели (англ. Lifecycle Objective Milestone), которое предполагает соглашение заинтересованных сторон о продолжении проекта.

  • Уточнение (Elaboration)
  • Документирование требований. Проектирование, реализация и тестирование исполняемой архитектуры. Уточнение сроков и стоимости. Снижение основных рисков. Успешное выполнение фазы разработки означает достижение этапа жизненного цикла архитектуры (англ. Lifecycle Architecture Milestone).

  • Построение (Construction)
  • В фазе «Построение» происходит реализация большей части функциональности продукта: дизайн приложения завершен, исходный код написан. Фаза Построение завершается первым внешним релизом системы и вехой начальной функциональной готовности (Initial Operational Capability).

  • Внедрение (Transition)
  • В фазе «Внедрение» создается финальная версия продукта и передается от разработчика к заказчику. Это включает в себя программу бета-тестирования, обучение пользователей, а также определение качества продукта. В случае, если качество не соответствует ожиданиям пользователей или критериям, установленным в фазе Начало, фаза Внедрение повторяется снова. Выполнение всех целей означает достижение вехи готового продукта (Product Release) и завершение полного цикла разработки.


Разговор с Бьерном Страуструпом


Онлайн-конференция разработчиков, использующих Embarcadero C++Builder. Беседу с Бьерном Страуструпом, легендарным создателем языка C++, провёл Дейвид Интерсимоне, вице-президент Embarcadero по связям с разработчиками. (Дублированный перевод).

Язык С (читается "Си") создан в начале 70х годов, когда Кен Томпсон и Дэннис Ритчи из Bell Labs разрабатывали операционную систему UNDC. Сначала они создали часть компилятора С, затем использовали ее для компиляции остальной части компилятора С и, наконец, применили полученный в результате компилятор для компиляции UNIX. Операционная система UNIX первоначально распространялась в исходных кодах на С среди университетов и лабораторий, а получатель мог откомпилировать исходный код на С в машинный код с помощью подходящего компилятора С .

Распространение исходного кода сделало операционную систему UNIX уникальной; программист мог изменить операционную систему, а исходный код мог быть перенесен с одной аппаратной платформы на другую. Сегодня стандарт POSIX определяет стандартный набор системных вызовов UNIX, доступных в С , которые должны быть реализованы в версиях UNIX, являющихся POSIX-совместимыми. С был третьим языком, который разработали Томсон и Ритчи в процессе создания UNIX; первыми двумя были, разумеется, А и В .

По сравнению с более ранним языком - BCPL, С был улучшен путем добавления типов данных определенной длины. Например, тип данных int мог применяться для создания переменной с определенным числом битов (обычно 16), в то время как тип данных long мог использоваться для создания целой переменной с большим числом битов (обычно 32). В отличие от других языков высокого уровня, С мог работать с адресами памяти напрямую с помощью указателей и ссылок. Поскольку С сохранил способность прямого доступа к аппаратному обеспечению, его часто относят к языкам среднего уровня или в шутку называют "мобильным языком ассемблера".

Что касается грамматики и синтаксиса, то С является структурным языком программирования. В то время как многие современные программисты мыслят в категориях классов и объектов, программисты на С думают в категориях процедур и функций. В С можно определить собственные абстрактные типы данных, используя ключевое слово struct . Аналогично можно описывать собственные целые типы (перечисления) и давать другие названия существующим типам данных при помощи ключевого слова typedef . В этом смысле С является структурным языком с зародышами объектно-ориентированного программирования.

Широкое распространение языка C на различных типах компьютеров (иногда называемых аппаратными платформами) привело, к сожалению, ко многим вариациям языка. Они были похожи, но несовместимы друг с другом. Это было серьезной проблемой для разработчиков программ, нуждавшихся в написании совместимых программ, которые можно было бы выполнять на нескольких платформах. Стало ясно, что необходима стандартная версия C . В 1983г. ANSI (Американский Национальный Комитет Стандартов) сформировал технический комитет X3J11 для создания стандарта языка C (чтобы "обеспечить недвусмысленное и машинно-независимое определение языка"). В 1989 стандарт был утвержден. ANSI скооперировался с ISO (Международной Организацией Стандартов), чтобы стандартизовать C в международном масштабе; совместный стандарт был опубликован в 1990 году и назван ANSI/ISO 9899:1990. Этот стандарт совершенствуется до сих пор и поддерживается большинством фирм разработчиков компиляторов.

Бьерн Страуструп высвободил объектно-ориентированный потенциал С путем перенесения возможностей классов Simula 67 в С . Первоначально новый язык носил имя "С с классами" и только потом стал называться C++ . Язык C++ достиг популярности, будучи разработанным в Bell Labs, позже он был перенесен в другие индустрии и корпорации. Сегодня это один из наиболее популярных языков программирования в мире. C++ наследует как хорошие, так и плохие стороны С .

Бьерн Страуструп : "Я придумал C++, записал его первоначальное определение и выполнил первую реализацию. Я выбрал и сформулировал критерии проектирования C++ , разработал его основные возможности и отвечал за судьбу предложений по расширению языка в комитете по стандартизации C++ ", - пишет автор самого популярного языка программирования. - "Язык C++ многим обязан языку C , и язык C остается подмножеством языка C++ (но в C++ устранены несколько серьезных брешей системы типов C). Я также сохранил средства C , которые являются достаточно низкоуровневыми, чтобы справляться с самыми критическими системными задачами. Язык C , в свою очередь многим обязан своему предшественнику, BCPL; кстати, стиль комментариев // был взят в C++ из BCPL. Другим основным источником вдохновения был язык Simula67. Концепция классов (с производными классами и виртуальными функциями) была позаимствована из него. Средства перегрузки операторов и возможность помещения объявлений в любом месте, где может быть записана инструкция, напоминает Algol68. "

Название C++ выдумал Рик Масситти. Название указывает на эволюционную природу перехода к нему от C. "++" - это операция приращения в C. Чуть более короткое имя C+ является синтаксической ошибкой; кроме того, оно уже было использовано как имя совсем другого языка. Знатоки семантики C находят, что C++ хуже, чем ++C. Названия D язык не получил, поскольку он является расширением C и в нем не делается попыток исцеляться от проблем путем выбрасывания различных особенностей...

Изначально язык программирования C++ был разработан, чтобы автору и его друзьям не приходилось программировать на ассемблере, C или других современных языках высокого уровня. Основным его предназначением было сделать написание хороших программ более простым и приятным для отдельного программиста. Плана разработки C++ на бумаге никогда не было; проект, документация и реализация двигались одновременно. Разумеется, внешний интерфейс C++ был написан на C++ . Никогда не существовало "Проекта C++" и "Комитета по разработке C++". Поэтому C++ развивался и продолжает развиваться во всех направлениях, чтобы справляться со сложностями, с которыми сталкиваются пользователи, а также в процессе дискуссий автора с его друзьями и коллегами.

В языке С++ полностью поддерживаются принципы объектно-ориентированного программирования, включая три кита, на которых оно стоит: инкапсуляцию, наследование и полиморфизм. Инкапсуляция в С++ поддерживается посредством создания нестандартных (пользовательских) типов данных, называемых классами. Язык С++ поддерживает наследование. Это значит, что можно объявить новый тип данных (класс), который является расширением существующего.

Хотя язык программирования С++ справедливо называют продолжением С и любая работоспособная программа на языке С будет поддерживаться компилятором С++ , при переходе от С к С++ был сделан весьма существенный скачок. Язык С++ выигрывал от своего родства с языком С в течение многих лет, поскольку многие программисты обнаружили, что для того, чтобы в полной мере воспользоваться преимуществами языка С++ , им нужно отказаться от некоторых своих прежних знаний и приобрести новые, а именно: изучить новый способ концептуальности и решения проблем программирования. Перед тем как начинать осваивать С++ , Страуструп и большинство других программистов, использующих С++ считают изучение языка С необязательным.

Язык программирования C++ в настоящее время считается господствующим языком, используемым для разработки коммерческих продуктов, 90% игр пишутся на С++ с прменением DirectX.

Литература:
Х.М.Дейтел, П.Дж.Дейтел "Как программировать на C++"
Бьерн Страуструп "Язык программирования C++. 3-е издание."
Симон Робинсон, Олли Корнес, Джей Глинн и др. "C# для профессионалов"
Джесс Либерти "Освой самостоятельно С++ за 21 день"
Станислав Горнаков "DirectX, уроки программирования на С++"

Благодаря чему сложился такой статус языка С? Исторически этот язык неотделим от операционной системы Unix, которая в наши дни переживает свое второе рождение. 60-е годы были эпохой становления операционных систем и языков программирования высокого уровня. В тот период для каждого типа компьютеров независимо разрабатывались ОС и компиляторы, а нередко даже свои языки программирования (вспомним, например, PL/I). В то же время, общность возникающих при этом проблем уже стала очевидной. Ответом на осознание этой общности стала попытка создать универсальную мобильную операционную систему, а для этого понадобился не менее универсальный и мобильный язык программирования. Таким языком стал С, а Unix стала первой ОС, практически полностью написанной на языке высокого уровня.

Тесная связь с Unix дала языку С такой полигон для обкатки, какого не было в то время ни у одного другого языка. Задачи системного программирования по праву считались в то время самыми сложными в отрасли. В большинстве своем они были настолько машинно-зависимыми, что многие вообще не мыслили их решение иначе, чем на ассемблере. Языки высокого уровня предназначались для прикладного программирования и лишь очень ограниченно реализовывали функции, необходимые для системных работ, причем зачастую только для определенного типа машин.

Язык С с самого начала создавался так, чтобы на нем можно было писать системные задачи. Создатели С не стали разрабатывать абстрактную модель исполнителя языка, а просто реализовали в нем те возможности, в которых более всего нуждались в практике системного программирования. Это в первую очередь были средства непосредственной работы с памятью, структурные конструкции управления и модульная организация программы. И по сути больше ничего в язык включено не было. Все остальное было отнесено в библиотеку времени исполнения. Поэтому недоброжелатели иной раз отзываются о языке С как о структурном ассемблере. Но что бы они ни болтали, подход оказался очень удачным. Благодаря ему был достигнут новый уровень по соотношению простоты и возможностей языка.

Есть, впрочем, еще один фактор, определивший успех языка. Создатели очень умело разделили в нем машинно-зависимые и независимые свойства. Благодаря этому большинство программ удается писать универсально - их работоспособность не зависит от архитектуры процессора и памяти. Немногочисленные же аппаратно-зависимые части кода можно локализовать в отдельных модулях. А пользуясь препроцессором, можно создавать такие модули, которые при компиляции на разных платформах будут порождать соответствующий машинно-зависимый код.

Много споров вызывал синтаксис языка С. Примененные в нем приемы сокращения записи при неумеренном использовании могут сделать программу совершенно нечитаемой. Но, как говорил Дейкстра, - средства не виноваты в том, что их безграмотно используют. На самом же деле, предложенные в С сокращения синтаксиса соответствуют наиболее часто встречающимся на практике стереотипным ситуациям. Если считать сокращения идиомами для выразительного и компактного представления таких ситуаций, то польза от них становится безусловной и очевидной.

Итак, С возник как универсальный язык системного программирования. Но он не остался в этих рамках. К концу 80-х годов язык С, оттеснив Fortran с позиции лидера, завоевал массовую популярность среди программистов во всем мире и стал использоваться в самых различных прикладных задачах. Немалую роль здесь сыграло распространение Unix (а значит и С) в университетской среде, где проходило подготовку новое поколение программистов.

Как и все языки, С постепенно совершенствовался, но большинство усовершенствований не носило радикального характера. Наиболее существенным из них, пожалуй, следует считать введение строгой спецификации типов функций, которая значительно повысила надежность межмодульного взаимодействия на С. Все такие усовершенствования были в 1989 году закреплены в стандарте ANSI который и поныне определяет язык С.

Но если все так безоблачно, то почему же еще продолжают использоваться все остальные языки, что поддерживает их существование? Ахиллесовой пятой языка С стало то, что он оказался слишком низкоуровневым для тех задач, которые поставили на повестку дня 90-е годы. Причем у этой проблемы есть два аспекта. С одной стороны, в язык были встроены слишком низкоуровневые средства - прежде всего это работа с памятью и адресная арифметика. Недаром смена разрядности процессоров очень болезненно отражается на многих С-программах. С другой стороны, в С недостает средств высокоуровневых - абстрактных типов данных и объектов, полиморфизма, обработки исключений. Как следствие, в программах на С техника реализации задачи часто доминирует над ее содержательной стороной.

Первые попытки исправить эти недостатки стали предприниматься еще в начале 80-х годов. Уже тогда Бьерн Страуструп в AT&T Bell Labs стал разрабатывать расширение языка С под условным названием. Стиль ведения разработки вполне соответствовал духу, в котором создавался и сам язык С, - в него вводились те или иные возможности с целью сделать более удобной работу конкретных людей и групп. Первый коммерческий транслятор нового языка, получившего название C++ появился в 1983 году. Он представлял собой препроцессор, транслировавший программу в код на С. Однако фактическим рождением языка можно считать выход в 1985 году книги Страуструпа. Именно с этого момента C++ начинает набирать всемирную популярность.

Главное нововведение C++ - механизм классов, дающий возможность определять и использовать новые типы данных. Программист описывает внутреннее представление объекта класса и набор функций-методов для доступа к этому представлению. Одной из заветных целей при создании C++ было стремление увеличить процент повторного использования уже написанного кода. Концепция классов предлагала для этого механизм наследования. Наследование позволяет создавать новые (производные) классы с расширенным представлением и модифицированными методами, не затрагивая при этом скомпилированный код исходных (базовых) классов. Вместе с тем наследование обеспечивает один из механизмов реализации полиморфизма - базовой концепции объектно-ориентированного программирования, согласно которой, для выполнения однотипной обработки разных типов данных может использоваться один и тот же код. Собственно, полиморфизм - тоже один из методов обеспечения повторного использования кода.

Введение классов не исчерпывает всех новаций языка C++. В нем реализованы полноценный механизм структурной обработки исключений, отсутствие которого в С значительно затрудняло написание надежных программ, механизм шаблонов - изощренный механизм макрогенерации, глубоко встроенный в язык, открывающий еще один путь к повторной используемости кода, и многое другое.

Таким образом, генеральная линия развития языка была направлена на расширение его возможностей путем введения новых высокоуровневых конструкций при сохранении сколь возможно полной совместимости с ANSI С. Конечно, борьба за повышение уровня языка шла и на втором фронте - те же классы позволяют при грамотном подходе упрятывать низкоуровневые операции, так что программист фактически перестает непосредственно работать с памятью и системно-зависимыми сущностями. Однако язык не содержит механизмов, вынуждающих разработчика правильно структурировать программу, а авторы не выпустили никаких систематических рекомендаций по использованию его довольно изощренных конструкций. Не позаботились они своевременно и о создании стандартной библиотеки классов, реализующей наиболее часто встречающиеся структуры данных.

Все это привело к тому, что многие разработчики вынуждены были сами исследовать лабиринты языковой семантики и самостоятельно отыскивать успешно работающие идиомы. Так, например, на первом этапе развития языка многие создатели библиотек классов стремились построить единую иерархию классов с общим базовым классом Object. Эта идея была заимствована из Smalltalk - одного из наиболее известных объектно-ориентированных языков. Однако она оказалась совершенно нежизнеспособной в C++ - тщательно продуманные иерархии библиотек классов оказывались негибкими, а работа классов - неочевидной. Для того чтобы библиотеками классов можно было пользоваться, их приходилось поставлять в исходных текстах.

Появление темплетных классов и вовсе опровергло это направление развития. Наследованием стали пользоваться только в тех случаях, когда требовалось порождение специализированной версии имеющегося класса. Библиотеки стали составляться из отдельных классов и небольших несвязанных друг с другом иерархий. Однако на этом пути стало снижаться повторное использование кода, так как в C++ невозможно полиморфное использование классов из независимых иерархий. Повсеместное же применение темплетов ведет к недопустимому росту объема скомпилированного кода - не будем забывать, темплеты реализуются методами макрогенерации.

Один из тяжелейших недостатков C++, унаследованный им от синтаксиса С, состоит в доступности компилятору описания внутренней структуры всех использованных классов. Как следствие, изменение внутренней структуры представления какого-нибудь библиотечного класса приводит к необходимости перекомпиляции всех программ, где эта библиотека используется. Это сильно ограничивает разработчиков библиотек в части их модернизации, ведь, выпуская новую версию, они должны сохранять двоичную совместимость с предыдущей. Именно эта проблема заставляет многих специалистов считать, что C++ непригоден для ведения больших и сверхбольших проектов.

И все же, несмотря на перечисленные недостатки и даже на неготовность стандарта языка (это после пятнадцати с лишним лет использования!), C++ остается одним из наиболее популярных языков программирования. Его сила прежде всего в практически полной совместимости с языком С. Благодаря этому программистам C++ доступны все наработки, выполненные на С. При этом C++ даже без использования классов привносит в С ряд настолько важных дополнительных возможностей и удобств, что многие пользуются им просто как улучшенным С.

Что касается объектной модели C++, то пока ваша программа не стала очень большой (сотни тысяч строк), ею вполне можно пользоваться. Наметившаяся в последнее время тенденция перехода к компонентному программному обеспечению только усиливает позиции C++. При разработке отдельно взятых компонентов недостатки C++ еще не проявляются, а связывание компонентов в работающую систему производится уже не на уровне языка, а на уровне операционной системы.

В свете всего сказанного перспективы C++ не выглядят мрачными. Хотя и монополия на рынке языков программирования ему не светит. Пожалуй, с уверенностью можно утверждать только то, что еще одной модернизации-расширения этот язык не переживет. Недаром, когда появилась Java, на нее обратили столь пристальное внимание. Язык, близкий по синтаксису к C++, а значит, кажущийся знакомым многим программистам, был избавлен от наиболее вопиющих недостатков C++, унаследованных им из 70-х годов. Однако не похоже, чтобы Java справлялась с возлагаемой на нее некоторыми ролью.

Особая роль языков C/C++ в современном программировании практически лишает смысла приведение конкретных адресов в Интернете, где можно найти материалы по ним. Таких мест просто слишком много. Однако, если интересно подробнее познакомиться с эволюцией C++, то начните с небольшой статьи http://citforum.syzran.ru/programming/prg96/76.shtml .

Александр Сергеев, [email protected]
Статья из журнала BYTE/Россия, Март 2000

Для того, чтобы наглядно продемонстрировать использование описанных языков на практике нами была выбрана задача, в которой требовалось ввести со стандартного ввода или из файла ряд целых чисел, а затем вывести только нечетные из них, причем в обратном порядке следования. Это одна из простейших задач, которая существенным образом требует для своего решения работы с массивами, циклами, ветвлением и вводом/выводом, а также позволяет продемонстрировать вызовы подпрограмм. При этом она обозрима и легко воспринимается.

Листинг 1. С

1 #include /* Подключаем функции ввода-вывода */ 2 3 void main(void) 4 { 5 int М; /* Массив из 10 целых, счет с 0 */ 6 int N; 7 for (N=0; N<10; ++N) /* Вводим не более 10 чисел */ 8 if (EOF == scanf ("%d, M+N)) 9 break; /* Если конец файла, прерываем цикл */ 10 11 for (-N; N>=0; --N) /* Проходим массив в обратном */ 12 if (M[N]%2) /* порядке и выводим нечетные */ 13 printf("%d\n", M[N]); 14 }

  • Строка 3. В C/C++ выполнение программы всегда начинается с функции main.
  • Строки 7 и 11. В заголовке цикла через точку с запятой указываются начальная установка, условие продолжения и правило пересчета параметра цикла. Операции ++ и -/- - известнейшие из сокращений языка С, означающие инкремент и декремент переменной, то есть увеличение и уменьшение ее значения на единицу.
  • Строка 8. Функция scanf вводит по формату, заданному первым параметром, значения переменных, адреса которых заданы остальными параметрами. Здесь адрес, куда вводится значение, вычисляется с помощью адресной арифметики, к адресу расположения массива М прибавляется смещение на N элементов. Тот же эффект можно получить, записав &M[N] .
  • Строка 12. Операция % вычисляет остаток от деления. Условие оператора if считается выполненным, если численное значение выражения отлично от нуля.
  • Строка 13. Функция printf - печать по формату действует аналогично scanf , но вместо адресов ей передаются значения, подлежащие выводу.
1 #include 2 3 template class Array 4 { 5 public: Array (T Size=1) : M (new T), N(Size), n(0) {} 6 Array (void) { delete М;} 7 T Count (void) const { return n; } 8 T operator (int i) const { return M[i]; } 9 void Add (Т Data); 10 private: 11 T* М; // Адрес распределенной памяти 12 int N, n; // N - распределено; n - использовано 13 }; 14 15 template void Array::Add(T Data) 16 { if (N-n) // Если использовано все распределенное 17 { int* P = new T; // место, распределим побольше 18 for (int i=0; i A; // Массив целых переменного размера 28 while (1) // Бесконечный цикл 29 { int N; 30 cin >> N; // cin - стандартный поток ввода 31 if (cin.eof()) break; // Выход из цикла по концу файла 32 A.Add(N); // Добавляем введенное число в массив 33 } 34 for (int N=A.Count()-1; N>=0; --N) // Проходим по массиву 35 if (A[N]%2) 36 cout <, и освободит память
  • Строки 3-13. Объявляется темплетный класс Аrray с параметром Т . Он представляет собой массив переменного размера объектов типа Т . Конечно, в нашей задаче нет никакой необходимости использовать темплетный класс. Однако нам хотелось продемонстрировать, как на C++ создается полиморфная структура данных, способная работать с любым типом элементов.
  • Строка 5. Конструктор класса. В нем инициализируется представление объекта. Например, в поле М заносится адрес блока памяти, заказанного операцией new T .
  • Строка 8. Пример перегрузки операции . Функция operator будет вызываться, когда квадратные скобки будут появляться справа от объекта класса Array .
  • Строка 9. Эта функция основная в реализации. Она добавляет элементы в массив, расширяя его при необходимости. Поскольку она сложнее остальных, ее определение вынесено из описания класса. Функции, описанные в теле класса, реализуются в C++ не вызовом, а inline-подстановкой. Это ускоряет работу программы, хотя увеличивает ее размер.
  • Строки 15-24. Определение функции Аrrау::Add(T) (между прочим, это ее полное имя).
  • Строка 27. Создаем объект типа Array . Темплет Аггау параметризируется типом int .

Почему C++

С++ в настоящее время считается господствующим языком, используемым для разра-ботки коммерческих программных продуктов. В последние годы это господство слегка по-колебалось вследствие аналогичных претензий со стороны такого языка программирова-ния, как Java, но маятник общественного мнения качнулся в другую сторону, и многие программисты, которые бросили С++ ради Jаvа, в последнее время поспешили вернуться к своей прежней привязанности. В любом случае эти два языка настолько похожи, что, изучив один из них, вы автоматически осваиваете 90% другого.

С# -- это новый язык, разработанный Мiсгоsоft для сетевой платформы. По суще-ству С# является разновидностью С++, и несмотря на ряд принципиальных отличий, языки С# и С++ совпадают примерно на 90%. Вероятно, пройдет немало времени, прежде чем язык С# составит серьезную конкуренцию языку С++; но даже если это и произойдет, то знание языка С++ окажется существенным преимуществом.

С++ является языком программирования общего назначения. Естественная для него область применения - системное программирование, понимаемое в широком смысле этого слова. Кроме того, С++ успешно используется во многих областях приложения, далеко выходящих за указанные рамки. Реализации С++ теперь есть на всех машинах, начиная с самых скромных микрокомпьютеров - до самых больших супер-ЭВМ, и практически для всех операционных систем.

Возникновение и эволюция языка C++

Бьерн Страуструп является разработчиком языка С++ и создателем первого транслятора. Он - сотрудник научно-исследовательского вычислительного центра AT&T Bell Laboratories в Мюррей Хилл (Нью-Джерси, США). Он получил звание магистра математики и вычислительной техники в университете г. Аарус (Дания), а докторское звание по вычислительной технике в кэмбриджском университете (Англия). Он специализируется в области распределенных систем, операционных систем, моделирования и программирования. Вместе с М. А. Эллис он является автором полного руководства по языку С++ - "Руководство по С++ с примечаниями".

Безусловно С++ многим обязан языку С , который сохраняется как его подмножество. Сохранены и все свойственные С средства низкого уровня, предназначенные для решения самых насущных задач системного программирования. С, в свою очередь, многим обязан своему предшественнику языку BCPL . Комментарий языка BCPL был восстановлен в С++. Еще одним источником вдохновения был язык SIMULA-67 ; именно из него была заимствована концепция классов (вместе c производными классами и виртуальными функциями). Возможность в С++ перегрузки операций и свобода размещения описаний всюду, где может встречаться оператор, напоминают язык Алгол-68 .

Более ранние версии языка, получившие название "С с классами" , использовались, начиная с 1980 г. Этот язык возник потому, что автору потребовалось написать программы моделирования, управляемые прерываниями. Язык SIMULA-67 идеально подходит для этого, если не учитывать эффективность. Язык "С с классами" использовался для больших задач моделирования. Строгой проверке подверглись тогда возможности написания на нем программ, для которых критичны ресурсы времени и памяти. В этом языке недоставало перегрузки операций, ссылок, виртуальных функций и многих других возможностей. Впервые С++ вышел за пределы исследовательской группы, в которой работал автор, в июле 1983 г., однако тогда многие возможности С++ еще не были разработаны.

Название С++ (си плюс плюс) , было придумано Риком Маскитти летом 1983 г. Это название отражает эволюционный характер изменений языка С. Обозначение ++ относится к операции наращивания С. Чуть более короткое имя С+ является синтаксической ошибкой. Кроме того, оно уже было использовано как название совсем другого языка. Знатоки семантики С находят, что С++ хуже, чем ++С. Язык не получил названия D, поскольку он является расширением С, и в нем не делается попыток решить какие-либо проблемы за счет отказа от возможностей С. Еще одну интересную интерпретацию названия С++ можно найти в приложении к .

Изначально С++ был задуман для того, чтобы автору и его друзьям не надо было программировать на ассемблере, С или других современных языках высокого уровня. Основное его предназначение - упростить и сделать более приятным процесс программирования для отдельного программиста. До недавнего времени не было плана разработки С++ на бумаге. Проектирование, реализация и документирование шли параллельно. Никогда не существовало "проекта С++" или "Комитета по разработке С++". Поэтому язык развивался и продолжает развиваться так, чтобы преодолеть все проблемы, с которыми столкнулись пользователи. Толчками к развитию служат также и обсуждения автором всех проблем с его друзьями и коллегами.

С момента выхода в свет первого издания этой книги язык С++ подвергся существенным изменениям и уточнениям. В основном это касается разрешения неоднозначности при перегрузке, связывании и управлении памятью. Вместе с тем, были внесены незначительные изменения с целью увеличить совместимость с языком С. Были также введены некоторые обобщения и существенные расширения, как то: множественное наследование, функции-члены со спецификациями static и const, защищенные члены (protected), шаблоны типа и обработка особых ситуаций. Все эти расширения и доработки были нацелены на то, чтобы С++ стал языком, на котором можно создавать и использовать библиотеки. Все изменения описываются в .

Другие расширения, введенные за период между 1985 и 1991 г.г. (такие как множественное наследование, статические функции-члены и чистые виртуальные функции), скорее появились в результате обобщения опыта программирования на С++, чем были почерпнуты из других языков.

Сделанные за эти шесть лет расширения языка прежде всего были направлены на повышение выразительности С++ как языка абстракции данных и объектно-ориентированного программирования вообще и как средства для создания высококачественных библиотек с пользовательскими типами данных в частности.

Примерно в 1987 г. стало очевидно, что работа по стандартизации С++ неизбежна и что следует незамедлительно приступить к созданию основы для нее .

Фирма AT&T Bell Laboratories внесла основной вклад в эту работу. Около ста представителей из порядка 20 организаций изучали и комментировали то, что стало современной версией справочного руководства и исходными материалами для ANSI по стандартизации. С++. Наконец, по инициативе фирмы Hewlett-Packard в декабре 1989 г. в составе ANSI был образован комитет X3J16. Ожидается, что работы по стандартизации С++ в ANSI (американский стандарт) станут составной частью работ по стандартизации силами ISO (Международной организации по стандартизации).

С++ развивался одновременно с развитием некоторых фундаментальных классов.

Выберите интересующие Вас в Си уроки:

Си — язык программирования, который был создан в 1972 г. Деннисом М. Ритчи. Стандарт языка того времени был продемонстрирован в книге Ритчи в соавторстве с Брайаном Керниганом («Язык программирования Си»). Данный стандарт носит название K&R стандарт (по именам Кернигана и Ритчи). Любая программа, написанная с использованием правил K&R-Си, успешно откомпилируется любым компилятором Си.

Программисты, разрабатывающие компиляторы для Си начали модернизировать и развивать язык. Чтобы не было путаниц, Американский Институт Национальных Стандартов (American National Standards Institute) в 1983 году разработал стандарт ANSI языка. ANSI-Си и по сей день устанавливает правила изменения и развития языка Си.

Си — язык программирования компилируемый. Программа представляет из себя инструкции и функции, которые для выполнения их аппаратной частью компьютера должны быть переведены в двоичные коды.
Си достаточно популярен и в настоящее время, это обусловлено такими востребуемыми его качествами, как: скорость, переносимость и структурирование.

  • Скорость

Среди всех языков высокого уровня Си — язык программирования, который более близок к ассемблеру. Так, многие инструкции языка адресованы непосредственно аппаратной части компьютера, из-за чего программа выполняется очень быстро. По этой причине Си можно использовать для написания операционных систем и компиляторов.

Большинство разработанных компиляторов Си генерируют высоко оптимизированные коды, т.е. проще говоря, малые по размеру (чем меньше код генерирует компилятор, тем более оптимизированным он является).

  • Переносимость

В принципе, было бы разумно писать быстро работающие программы на ассемблере. Но пришлось бы писать их под каждую платформу, так как мнемонические ассемблерные коды адаптированы под семейства микропроцессоров.

Си использует стандартные наборы ключевых слов. Т.е. программа пишется один раз для любой платформы, любого компьютера с любой операционной системой. Но компиляторы для языка бывают двух типов: одни для IBM, другие — для Apple. Но сам текст программы создается раз и навсегда.

  • Структурирование

Программы, написанные на Языке Си имеют свою структуру и правила, что побуждает программиста мыслить логически.
Необходимость структурирования программы — это только «плюс», ведь именно благодаря этому программу на Си очень легко проектировать, поддерживать и отлаживать.

  • Библиотеки функций

Си — язык программирования, изначально содержащий в своем синтаксисе небольшое количество операций. К примеру, язык не имеет встроенных операторов ввода и вывода информации, также как и операторов для работы со строками.

Все возможности Си обеспечивается благодаря библиотекам функций, некоторые из которых поставляются вместе с компилятором. Библиотека представляет собой отдельный файл, прилагающийся к компилятору и содержащий функции для решения конкретных задач.



Понравилась статья? Поделитесь с друзьями!