Файл: Современные языки программирования (основы программирования).pdf
Добавлен: 15.06.2023
Просмотров: 327
Скачиваний: 3
СОДЕРЖАНИЕ
Глава 1. Основы программирования
1.1 Стандартизация языков программирования
1.4 Семантика языков программирования
Глава 2. Классификация языков программирования
2.1 Процедурные языки программирования
2.3. Объектно-ориентированные языки программирования
2.4. Язык программирования С++
2.5. Язык программирования Java
2.5.3. Независимость от целевой платформы
2.5.4. Безопасное выполнение удаленного кода
Использование объектно-ориентированного программирования является хорошим решением при разработке крупных программных проектов. Чем проект объемнее и сложнее, тем больше выгоды вы получите при использовании объектно-ориентированной технологии программирования. Одним из наибольших преимуществ объектно-ориентированного программирования является возможность многократного использования программного кода. Если вы, к примеру, создали класс, то можете порождать от него новые классы и изменять их свойства и функциональное назначение.
В качестве примера объектно-ориентированных языков в дальнейшем будем рассматривать такие языки как C++, Java, Python.
2.4. Язык программирования С++
2.4.1. Описание
C++ — компилируемый статически типизированный язык программирования общего назначения. Поддерживает разные парадигмы программирования, но, в сравнении с его предшественником — языком Си, — большое внимание уделяется поддержке объектно-ориентированного и обобщённого программирования.
В 1990-х годах язык стал одним из наиболее широко применяемых языков программирования общего назначения.
С++ — язык общего назначения и задумка его в том, чтобы настоящие программисты довольствовались процессом программирования. За исключением второстепенных деталей он содержит язык С как подмножество. Язык С расширяется введением гибких и эффективных средств, предназначенных для построения новых типов. Программист структурирует свою задачу, определяя новые типы, точно соответствующие понятиям предметной области задачи. Такой метод построения программы обычно называют абстракцией данных. Информация о типах содержится в некоторых объектах типов, определенных пользователем. С такими объектами можно работать надежно и просто даже в тех случаях, когда их тип нельзя установить на стадии трансляции. Программирование с использованием таких объектов обычно называют объектно-ориентированным. Если этот метод применяется правильно, то программы становятся короче и понятнее, а сопровождение их упрощается.
Ключевым понятием С++ является класс. Класс — это определяемый пользователем тип. Классы обеспечивают упрятывание данных, их инициализацию, неявное преобразование пользовательских типов, динамическое задание типов, контролируемое пользователем управление памятью и средства для перегрузки операций. В языке С++ концепции контроля типов и модульного построения программ реализованы более полно, чем в С. Кроме того, С++ содержит усовершенствования, прямо с классами не связанные: символические константы, функции-подстановки, стандартные значения параметров функций, перегрузка имен функций, операции управления свободной памятью и ссылочный тип. В С++ сохранены все возможности С эффективной работы с основными объектами, отражающими аппаратную «реальность» (разряды, байты, слова, адреса и т.д.). Это позволяет достаточно эффективно реализовывать пользовательские типы.
Язык С++ проектировался для поддержки абстракции данных и объектно-ориентированного программирования в добавление к традиционному стилю С. Впрочем, это не значит, что язык требует какого-то одного стиля программирования от всех пользователей.
Сейчас мы рассмотрим достоинства и недостатки языка, чтобы понять, что же делает его настолько мощным и универсальным инструментом в руках программиста.
Но для начала необходимо подчеркнуть, что оценивать достоинства и, в особенности, недостатки C++ необходимо в контексте тех принципов, на которых строился язык, и требований, которые к нему изначально предъявлялись.
2.4.2. Достоинства
C++ — чрезвычайно мощный язык, который содержит средства создания эффективных программ практически любого назначения, от низкоуровневых утилит и драйверов до сложных программных комплексов самого различного назначения. В частности: поддерживаются различные стили и технологии программирования, включая традиционное директивное программирование, ООП, обобщённое программирование, метапрограммирование(шаблоны, макросы).
Предсказуемое выполнение программ является серьезным достоинством для построения систем реального времени. Весь код, который неявно генерируется компилятором для реализации языковых возможностей (например, при x нулевое значение, а потом интерпретирует его как значение условия в операторе if). Так как нуль соответствует логическому значению «ложь», блок операторов в условной конструкции не выполнится никогда. Ошибки такого рода трудно выявлять, но во многих современных компиляторах предлагается диагностика некоторых подобных конструкций.
Операции присваивания (=), инкрементации (++), декрементации (--) и другие возвращают значение. В сочетании с изобилием операций это позволяет создавать трудночитаемые выражения. Наличие этих операций в Си было вызвано желанием создать инструмент ручной оптимизации кода, но в нынешнее время оптимизирующие компиляторы обычно генерируют оптимальный код и на традиционных выражениях. С другой стороны, один из главных принципов языков Си и C++ — позволять программисту писать в любом стиле, а не навязывать «хороший» стиль.
Макросы (#define) являются мощным, но опасным средством. Они сохранены в C++ несмотря на то, что необходимости в них, благодаря шаблонам и встроенным функциям, почти нет. В унаследованных стандартных Си-библиотеках много потенциально опасных макросов.
Некоторые преобразования типов неинтуитивны. В частности, операция над беззнаковым и знаковым числами выдаёт беззнаковый результат.
C++ допускает пропуск break в ветви оператора switch с целью последовательного выполнения нескольких ветвей. В языке Java принят такой же подход. Есть мнение, что понимание кода при этом затрудняется. Например, в языке C# следует всегда писать либо break, либо использовать goto case N для явного указания порядка выполнения.
Препроцессор, унаследованный от Си, довольно примитивен. С одной стороны это приводит к тому, что с его помощью нельзя (или тяжело) осуществить некоторые задачи метапрограммирования, а с другой, вследствие своей примитивности, он нередко приводит к ошибкам и требует много действий по обходу потенциальных проблем. Некоторые языки программирования (например, Scheme и Nemerle) имеют намного более мощные и более безопасные системы метапрограммирования (также называемые макросами, но мало напоминающие макросы Си/C++).
Плохая поддержка модульности (по сути, в классическом Си модульность на уровне языка отсутствует, её обеспечение переложено на компоновщик). Подключение интерфейса внешнего модуля через препроцессорную вставку заголовочного файла (#include) серьёзно замедляет компиляцию при подключении большого количества модулей (потому что результирующий файл, который обрабатывается компилятором, оказывается очень велик). Эта схема без изменений скопирована в C++. Для устранения этого недостатка, многие компиляторы реализуют механизм прекомпиляции заголовочных файлов (англ. Precompiled header).
2.4.3. Недостатки
Трудность и избыточность, из-за которых C++ трудно изучать, а построение компилятора сопряжено с большим количеством проблем. В частности:
Многие конструкции С++ позволяют делать то же самое, что и конструкции Си, которые также присутсвуют в С++. Например, приведение типов при помощи dynamic_cast позволяет привести указатель или ссылку строго в пределах иерархии классов. Это делает код более надёжным, декларативным и позволяет находить приведения в пределах иерархии при помощи инструментов типа grep. Однако вследствие требования высокой степени совместимости с Си старое приведение типов всё ещё поддерживается.
Иногда шаблоны приводят к порождению кода очень большого объёма. Для уменьшения размера машинного кода можно специальным образом подготавливать исходный код. Иным решением является стандартизованная ещё в 1998 году возможность экспорта шаблонов. Некоторые авторы считают, что её трудно реализовать и поэтому она доступна не во всех компиляторах. «Раздувание» машинного кода вследствие использования шаблонов часто преувеличивается, и современные компиляторы во многих случаях успешно устраняют это явление.
Метапрограммирование на основе шаблонов C++ весьма трудоемко и при этом ограничено в возможностях. Оно состоит в реализации средствами шаблонов C++ интерпретатора примитивного функционального языка программирования, выполняющегося во время компиляции. Сама по себе данная возможность весьма привлекательна, но такой код довольно сложно воспринимать и отлаживать. Менее распространённые языки Lisp/Scheme, Nemerle имеют более мощные и одновременно более простые для восприятия подсистемы метапрограммирования. Кроме того, в языке D реализована сравнимая по мощности, но значительно более легкая в применении подсистема шаблонного метапрограммирования.
Явная поддержка функционального программирования есть только в будущем стандарте c++0x. Данный пробел устраняется различными библиотеками (Loki, Boost), использующими средства метапрограммирования для расширения языка функциональными конструкциями (например, поддержкой лямбд/анонимных методов), но качество подобных решений сильно уступает качеству встроенных в функциональные языки решений. Такие возможности функциональных языков, как сопоставление с образцом, вообще крайне сложно эмулировать средствами метапрограммирования.
Некоторые считают недостатком языка C++ отсутствие встроенной системы сборки мусора. С другой стороны, средства C++ позволяют реализовать сборку мусора на уровне библиотеки. Противники сборки мусора полагают, что RAII является более достойной альтернативой. С++ позволяет пользователю самому выбирать стратегию управления ресурсами.
Синтаксис, провоцирующий ошибки. Операция присваивания обозначается как =, а операция сравнения как ==. Их легко спутать, при этом операция присваивания возвращает значение, поэтому присваивание на месте выражения является синтаксически корректным, а в конструкциях цикла и ветвления появление числа на месте логического значения также допускается, так что ошибочная конструкция оказывается синтаксически правильной.
2.4.4. Оценка
Язык C++ явился мощным и стремительным рывком в развитии программирования. C++ и по сей день занимает господствующее положение среди языков программирования в мире. Огромное множество профессиональных программистов использует именно его при разработке разного рода проектов. Очевидно, этот язык будет сохранять свое положение ещё не один год, при этом по-прежнему развиваясь и совершенствуясь.
2.5. Язык программирования Java
2.5.1. Описание
Язык программирования Java является объектно-ориентированным языком программирования, который был создан Джеймсом Гослингом (James Gosling) и другими инженерами в компании Sun Microsystems. Он был разработана в 1991 году, как часть проекта "Green Project", и официально объявлен 23 мая 1995 года, в SunWorld, а выпущен в ноябре. Java была изначально разработана как замена для C++ (хотя набор функций больше похожа на Objective C) и известный как Дуб (в честь дерева за пределами офиса Гослинга).
Существовали четыре основных цели при создании языка Java:
1. Объектно-ориентированный язык.
2. Независимость от целевой платформы (более или менее).
3. Содержание объектов и библиотеки для работы в сети.
4. Безопасное выполнение удаленного кода.
2.5.2. Объектная ориентация
Первая характеристика, объектно-ориентированный подход ("ОО"), относится к методу программирования для чайников и дизайну язык. Основная идея ОО заключается в разработке программного обеспечения все это "вещи" (то есть объекты), которыми можно манипулировать, а не действия, которые нужно выполнять. Это основано на том, что первое (вещи) изменяются реже и радикальнее, чем действия, что делает такие объекты (на самом деле вещи, содержащие данные) более стабильной основу для разработки программного обеспечения. Целью является, делать большие проекты программного обеспечения легко управляемыми, таким образом, можно добиться повышения качества и сокращения числа неудачных проектов программирования для начинающих.
2.5.3. Независимость от целевой платформы
Вторая характеристика, независимость от целевой платформы, означает, что программы, написанные на языке Java должны работать аналогично на различном оборудовании. Программист должен быть в состоянии написать программу один раз и запустить её в любом месте. Это достигается путем компиляции Java-кода "наполовину" в байт-код - упрощенные машинные команды, которым соответствуют стандартный набор реальных команд процессору. Этот код затем необходимо запустить на виртуальной машине, то есть программе, написанойя на машинном коде для взаимодействия с аппаратными средствами, которая переводит байт-код Java в пригодный для использования код на конкретном оборудовании. Кроме того, предоставляются стандартизированные библиотеки для обеспечения доступа к особенностям архитектуры конкретной машины (например, графики и сетей) единым способам. Язык Java также включает поддержку для многопоточных программ - жизненно важная необходимость для многих сетевых приложений и основа программирования.