Файл: Современные языки программирования (История создания).pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 31.03.2023

Просмотров: 361

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

3. Python в отличие от Pascal, C, C++ не поддерживает работу с указателями, динамической памятью и адресную арифметику. В этом он похож на Java. Как известно, указатели служат источником трудноуловимых ошибок и работа с ними относится больше к программированию на низком уровне. Для обеспечения большей надежности и простоты они небыли включены в Python.

4. Одним из особенностей Python является то, как происходит присваивание одной переменной другой, т.е. когда по обе стороны от оператора "=" стоят переменные.

Следуя Тимоти Бадду ([1]), будем называть семантикой указателей случай, когда присваивание приводит лишь к присваиванию ссылки (указателя), т.е. новая переменная становится лишь другим именем, обозначающим тот же участок памяти, что и старая переменная. При этом изменение значения, обозначаемого новой переменной, приведет к изменению значения старой, т.к. они, фактически, означают одно и то же.

Когда же присваивание приводит к созданию нового объекта (здесь объект - в смысле участка памяти для хранения значения какого-либо типа) и копированию в него содержимого присваиваемой переменной, этот случай назовем семантикой копирования. Таким образом, если при копировании действует семантика копирования, то переменные по обе стороны от знака "=" будут означать два независимых объекта с одинаковым содержанием. И здесь последующее изменение одной переменной никак не скажется на другой.

Присваивание в Python происходит следующим образом: если присваеваемый объект является экземпляром таких типов как числа или строки, то действует семантика копирования, если же в правой части стоит экземпляр класса, список, словарь или тьюпл, то действует семантика указателей. Пример: 
a = 2; b = a; b = 3 
print ' семантика копирования: a=', a, 'b=', b 
a = [2,5]; b = a; b[0] = 3 
print ' семантика указателей: a=', a, 'b=', b 
Результат
семантика копирования: a= 2 b= 3 
семантика указателей: a= [3,5] b= [3,5]

Для тех из вас, кто хочет знать в чем тут дело, я приведу другой взгляд на присваивание в Python. Если в таких языках как Basic, Pascal, C/C++ мы имели дело с переменными-"емкостями", и хранимыми в них константами (числовыми, символьными, строковыми - не суть важно), а операция присваивания означала "занесение" константы в присваиваемую переменную, то в Python мы уже должны работать с переменными-"именами" и именуемыми ими объектами. (Замечаете некоторую аналогию с языком Prolog?) Что же такое объект в Python? Это все то, чему можно дать имя: числа, строки, списки, словари, экземпляры классов (которые в Object Pascal и называются объектами), сами классы (!), функции, модули и т.д. Так вот, при присваивании переменной некоторого объекта, переменная становится его "именем", причем таких "имен" объект может иметь сколько угодно и все они никак не зависят друг от друга.


Теперь, объекты делятся на модифицируемые (мутируемые) и неизменные. Мутируемые - те, которые могут изменить свое "внутреннее содержание", например, списки, словари, экземпляры классов. А неизменные - такие как числа, тьюплы, строки (да, строки тоже; можно переменной присвоить новую строку, полученную из старой, но саму старую строку модифицировать не получится).

Так вот, если мы пишем a = [2,5]; b = a; b[0] = 3, Python это интерпретирует так:

 дать объекту "список [2,5]" имя a ;

 дать этому объекту еще одно имя - b ;

 модифицировать нулевой элемент объекта.
Вот и получилась "псевдо" семантика указателей.

И последнее, что стоит сказать насчет этого: хотя нет возможности изменения структуры тьюпла, но содержащиеся в нем мутируемые компоненты по-прежнему доступны для модификации:

t = (1, 2, [7,5], 'string')

t[0] = 6 # так нельзя

del t[1] # тоже ошибка

t[2][1] = 0 # допустимо, теперь третья компонента - список [7,0]

t[3][0] = 'S' # ошибка: строки не мутируемы

5. Весьма оригинальным является то, как в Python группируются операторы. В Pascal для этого служат операторные скобки begin-end, в C, C++, Java - фигурные скобки {}, в Basic применяются закрывающие окончания конструкций языка (NEXT, WEND, END IF, END SUB). 
В языке Python все гораздо проще: выделение блока операторов осуществляется путем сдвига выделяемой группы на один или более пробелов или символов табуляции вправо относительно заголовка конструкции к которой и будет относиться данный блок. Например:

 if x > 0:

      print ‘ x > 0 ’

      x = x - 8

 else:

      print ‘ x <= 0 ’

      x = 0

Тем самым, хороший стиль записи программ, к которому призывают преподаватели языков Pascal, C++, Java и т.д., здесь приобретается с самого начала, поскольку, по-другому просто не получится. 

Глава 5. С++

Глава 5.1. Общие сведения

C++ (читается си-плюс-плюс) — компилируемый, статически типизированный язык программированияобщего назначения.

Поддерживает такие парадигмы программирования, как процедурное программирование, объектно-ориентированное программирование, обобщённое программирование. Язык имеет богатую стандартную библиотеку, которая включает в себя распространённые контейнеры и алгоритмы, ввод-вывод, регулярные выражения, поддержку многопоточности и другие возможности. C++ сочетает свойства как высокоуровневых, так и низкоуровневых языков.[3][4] В сравнении с его предшественником — языком C, — наибольшее внимание уделено поддержке объектно-ориентированного и обобщённого программирования.[4]


C++ широко используется для разработки программного обеспечения, являясь одним из самых популярных языков программирования. Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов устройств, приложений для встраиваемых систем, высокопроизводительных серверов, а также игр. Существует множество реализаций языка C++, как бесплатных, так и коммерческих и для различных платформ. Например, на платформе x86 это GCC, Visual C++, Intel C++ Compiler, Embarcadero (Borland) C++ Builder и другие. C++ оказал огромное влияние на другие языки программирования, в первую очередь на Java и C#.

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

Глава 5.2. История

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

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


Разрабатывая C с классами, Страуструп написал программу cfront — транслятор, перерабатывающий исходный код C с классами в исходный код простого C. Это позволило работать над новым языком и использовать его на практике, применяя уже имеющуюся в UNIX инфраструктуру для разработки на C. Новый язык, неожиданно для автора, приобрёл большую популярность среди коллег и вскоре Страуструп уже не мог лично поддерживать его, отвечая на тысячи вопросов.

К 1983 году в язык были добавлены новые возможности, такие как виртуальные функции, перегрузка функций и операторов, ссылки, константы, пользовательский контроль над управлением свободной памятью, улучшенная проверка типов и новый стиль комментариев (//). Получившийся язык уже перестал быть просто дополненной версией классического C и был переименован из C с классами в «C++». Его первый коммерческий выпуск состоялся в октябре 1985 года.

До начала официальной стандартизации язык развивался в основном силами Страуструпа в ответ на запросы программистского сообщества. Функцию стандартных описаний языка выполняли написанные Страуструпом печатные работы по C++ (описание языка, справочное руководство и так далее). Лишь в 1998 году был ратифицирован международный стандарт языка C++: ISO/IEC 14882:1998 «Standard for the C++ Programming Language»; после принятия технических исправлений к стандарту в 2003 году — следующая версия этого стандарта — ISO/IEC 14882:2003

Глава 5.3. Особенности языка

C++ содержит средства разработки программ контролируемой эффективности для широкого спектра задач, от низкоуровневых утилит и драйверов до весьма сложных программных комплексов. В частности:

Высокая совместимость с языком Си : код на Си может быть с минимальными переделками скомпилирован компилятором C++. Внешнеязыковой интерфейс является прозрачным, так что библиотеки на Си могут вызываться из C++ без дополнительных затрат, и более того — при определённых ограничениях код на C++ может экспортироваться внешне не отличимо от кода на Си (конструкция extern "C").

  • Как следствие предыдущего пункта — вычислительная производительность. Язык спроектирован так, чтобы дать программисту максимальный контроль над всеми аспектами структуры и порядка исполнения программы. Один из базовых принципов C++ — «не платишь за то, что не используешь» — то есть ни одна из языковых возможностей, приводящая к дополнительным накладным расходам, не является обязательной для использования. Имеется возможность работы с памятью на низком уровне.
  • Поддержка различных стилей программирования: традиционное императивное программирование (структурное, объектно-ориентированное), обобщённое программирование, функциональное программирование, порождающее метапрограммирование.
  • Автоматический вызов деструкторов объектов в адекватном порядке (обратном вызову конструкторов) упрощает и повышает надёжность управления памятью и другими ресурсами (открытыми файлами, сетевыми соединениями, соединениями с базами данных и т. п.).
  • Перегрузка операторов позволяет кратко и ёмко записывать выражения над пользовательскими типами в естественной алгебраической форме.
  • Имеется возможность управления константностью объектов (модификаторы const, mutable, volatile). Использование константных объектов повышает надёжность и служит подсказкой для оптимизации. Перегрузка функций-членов по признаку константности позволяет определять выбор метода в зависимости цели вызова (константный для чтения, неконстантный для изменения). Объявление mutable позволяет сохранять логическую константность при виде извне кода, использующего кэши и ленивые вычисления.
  • Шаблоны C++ дают возможность построения обобщённых контейнеров и алгоритмов для разных типов данных. Попутно шаблоны дают возможность производить вычисления на этапе компиляции.
  • Возможность встраивания предметно-ориентированных языков программирования в основной код. Такой подход использует, например библиотека Boost.Spirit, позволяющая задавать EBNF-грамматику парсеров прямо в коде C++.
  • Доступность. Для C++ существует огромное количество учебной литературы, переведённой на всевозможные языки. Язык имеет высокий порог вхождения, но среди всех языков такого рода обладает наиболее широкими возможностями.

К числу обычно упоминаемых недостатков языка можно отнести:

  • Отсутствие системы модулей. C++ унаследовал от Си подключение заголовочных файлов с помощью препроцессора. Это вынуждает дублировать описания объектов, порождает неочевидные требования к коду и увеличивает объём компилируемого текста, а значит и время компиляции.
  • Наличие более чем одного механизма для выполнения одних и тех же задач, что усложняет язык и приводит к неоптимальному и небезопасному кодированию.
  • Унаследованные от Си опасные и провоцирующие ошибки возможности, такие как макроопределения #define, адресная арифметика и неявное приведение типов.
  • Возможность прямого управления распределением памяти провоцирует ошибки, приводящие к внезапному краху программ из-за разрушения стека или обращения к невыделенной памяти.
  • Шаблоны порождают объёмный и не всегда оптимальный код. Частичное определение шаблонов усложняет как сам язык, так и программы, где оно используется.
  • Объектно-ориентированная подсистема построена так, что оказывается затруднительно применять многие приёмы, обычные для других объектных языков.
  • Множественное (в том числе виртуальное) наследование усложняет транслятор и приводит к созданию громоздких иерархий классов, которые при любом изменении требований к программе могут потребовать серьёзного пересмотра.
  • Сложный синтаксис и объёмная спецификация языка затрудняют его изучение.
  • Язык не поощряет создание надёжного, легко читаемого и удобного в сопровождении кода, вместо этого зачастую предлагая выбор между короткими и простыми, но опасными средствами, унаследованными от Си, и новыми, объёмными и сложными, но более безопасными механизмами.
  • Сложная и постоянно разрастающаяся стандартная библиотека, затрудняющая изучение и дополнительно увеличивающая объём программ.
  • Отсутствие или ограниченность поддержки ряда полезных технологий и методик программирования.

Глава 6. С Sharp

Глава 6.1. Общие сведения

C# (произносится си шарп) — объектно-ориентированный язык программирования. Разработан в 1998—2001 годах группой инженеров компании Microsoft под руководством Андерса Хейлсберга и Скотта Вильтаумота[4] как язык разработки приложений для платформы Microsoft .NET Framework. Впоследствии был стандартизирован как ECMA-334 и ISO/IEC 23270.