Файл: Современные языки программирования (История создания).pdf
Добавлен: 31.03.2023
Просмотров: 359
Скачиваний: 2
СОДЕРЖАНИЕ
Язык Си разрабатывался как язык системного программирования, для которого можно создать однопроходный компилятор. Стандартная библиотека также невелика. Как следствие данных факторов — компиляторы разрабатываются сравнительно легко. Поэтому данный язык доступен на самых различных платформах. К тому же, несмотря на свою низкоуровневую природу, язык ориентирован на переносимость. Программы, соответствующие стандарту языка, могут компилироваться под различные архитектуры компьютеров.
Целью языка было облегчение написания больших программ с минимизацией ошибок по сравнению с ассемблером, следуя принципам процедурного программирования, но избегая всего, что может привести к дополнительным накладным расходам, специфичным для языков высокого уровня.
Основные особенности Си:
простая языковая база, из которой в стандартную библиотеку вынесены многие существенные возможности, вроде математических функций или функций работы с файлами;
ориентация на процедурное программирование;
система типов, предохраняющая от бессмысленных операций;
использование препроцессора для абстрагирования однотипных операций;
доступ к памяти через использование указателей;
небольшое число ключевых слов;
передача параметров в функцию по значению, а не по ссылке (передача по ссылке эмулируется с помощью указателей);
наличие указателей на функции и статических переменных;
области видимости имён;
структуры и объединения — определяемые пользователем собирательные типы данных, которыми можно манипулировать как одним целым.
В то же время в Си отсутствуют:
вложенные функции;
прямое возвращение нескольких значений из функций;
сопрограммы;
средства автоматического управления памятью;
встроенные средства объектно-ориентированного программирования;
средства функционального программирования.
Часть отсутствующих возможностей может имитироваться встроенными средствами часть добавляется с помощью сторонних библиотек (например, для поддержки многозадачности и для сетевых функций можно использовать библиотеки pthreads, sockets и тому подобные; существуют библиотеки для поддержки автоматической сборки мусора[3]), часть реализуется в некоторых компиляторах в виде расширений языка (например, вложенные функции в GCC). Существует несколько громоздкая, но вполне работоспособная методика, позволяющая реализовывать на Си механизмы ООП[4], базирующаяся на фактической полиморфности указателей в Си и поддержке в этом языке указателей на функции. Механизмы ООП, основанные на данной модели, реализованы в библиотеке GLib и активно используются в фреймворке GTK+. GLib предоставляет базовый класс GObject, возможности наследования от одного класса[5] и реализации множества интерфейсов.
После появления язык был хорошо принят, потому что он позволял быстро создавать компиляторы для новых платформ, а также позволял программистам довольно точно представлять, как выполняются их программы. Благодаря близости к языкам низкого уровня программы на Си работали эффективнее написанных на многих других языках высокого уровня, и лишь оптимизированный вручную код на ассемблере мог работать ещё быстрее, потому что давал полный контроль над машиной. На сегодняшний день развитие компиляторов и усложнение процессоров привело к тому, что вручную написанный ассемблерный код (кроме разве что очень коротких программ) практически не выигрывает по сравнению с кодом, генерируемым компиляторами, при этом Си продолжает оставаться одним из наиболее эффективных языков высокого уровня.
Глава 3.2 История развития
Язык программирования Си разрабатывался в период с 1969 по 1973 годы в лабораториях Bell Labs, и к 1973 году на него была переписана большая часть ядра UNIX, первоначально написанного на ассемблере PDP-11/20. Название языка стало логическим продолжением старого языка «Би»[a], многие особенности которого были положены в основу.
По мере развития язык сначала стандартизировали как ANSI C, а затем этот стандарт был принят комитетом по международной стандартизации ISO как ISO C, ставший также известным под названием C90. В стандарте С99 язык получил новые возможности, из которых в качестве наиболее значимых можно отметить массивы переменной длины и встраиваемые функции. А в стандарте C11 в язык добавили реализацию потоков и поддержку атомарных типов. Однако с тех пор язык развивается медленно, и в стандарт С18 попали лишь исправления ошибок стандарта C11.
Глава 3.3 Особенности языка
Си (C) является языком функций, типов данных, операторов присваивания и управления последовательностью вычислений. Программируя на Си (C), вы осуществляете обращение к функциям, и большинство функций возвращают некоторые значения. Значение, возвращаемое функцией, будь то значение переменной или константа, может использоваться в операторе присваивания, который изменяет значение другой переменной. Дополненный операторами управления последовательностью вычислений (while, for, do, switch), Си (C) превращается в язык высокого уровня, способствующий хорошему стилю программирования. Си (C) имеет небольшой набор типов данных: целые числа, числа с плавающей запятой, битовые поля и перечислимый тип. В языке Си (C) вы можете описать переменную типа указатель, который связывается с объектом, принадлежащим к любому типу данных. Адресная арифметика языка Си (C) является чувствительной к типу данных того объекта, с которым связан используемый указатель. Разрешены также указатели к функциям. Вы можете расширить список типов данных путем создания структур с иерархической зависимостью входящих в него типов данных. Каждый тип данных может принадлежать либо к основному типу, либо к ранее описанному структурному типу. Объединения напоминают структуры, но определяют различные виды иерархических зависимостей, в которых данные разных типов располагаются в памяти.
Допустимо описание массивов данных различных типов, включая структуры и объединения. Массивы могут быть многомерными. Функции Си (C) являются рекурсивными по умолчанию. Вы можете, правда, создать функцию, которая не будет рекурсивной, но сам язык по своей природе стремится поддерживать рекурсивность и требует минимальных усилий при программировании рекурсий.
Программа функции на языке Си (C) разбивается на блоки, в каждом из которых могут быть определены свои собственные локальные переменные. Блоки могут выбираться для исполнения по результату выполнения оператора управления последовательностью вычислений. Блоки могут быть вложенными друг в друга. Переменные и функции могут быть глобальными для программы, глобальными для исходного модуля или локальными для блока, в котором они описаны. Локальные переменные могут быть описаны таким образом, что они будут сохранять свои значения при всех обращениях внутри данного блока (статические переменные) или же будут восприниматься как новые объекты при каждом обращении (автоматические переменные).
Глава 4. Python
Глава 4.1 Общие сведения
Python (МФА: [ˈpʌɪθ(ə)n]; в русском языке распространено название пито́н) — высокоуровневый язык программирования общего назначения, ориентированный на повышение производительности разработчика и читаемости кода. Синтаксис ядра Python минималистичен. В то же время стандартная библиотека включает большой объём полезных функций.
Python поддерживает структурное, объектно-ориентированное, функциональное, императивное и аспектно-ориентированное программирование. Основные архитектурные черты — динамическая типизация, автоматическое управление памятью, полная интроспекция, механизм обработки исключений, поддержка многопоточных вычислений, высокоуровневые структуры данных. Поддерживается разбиение программ на модули, которые, в свою очередь, могут объединяться в пакеты.
Эталонной реализацией Python является интерпретатор CPython, поддерживающий большинство активно используемых платформ. Он распространяется под свободной лицензией Python Software Foundation License, позволяющей использовать его без ограничений в любых приложениях, включая проприетарные. Есть реализация интерпретатора для JVM с возможностью компиляции, CLR, LLVM, другие независимые реализации. Проект PyPy использует JIT-компиляцию, которая значительно увеличивает скорость выполнения Python-программ.
Python — активно развивающийся язык программирования, новые версии с добавлением/изменением языковых свойств выходят примерно раз в два с половиной года. Язык не подвергался официальной стандартизации, роль стандарта де-факто выполняет CPython, разрабатываемый под контролем автора языка.
Глава 4.2 История создания
Разработка языка Python была начата в конце 1980-х годов сотрудником голландского института CWI Гвидо ван Россумом. Для распределённой ОС Amoeba требовался расширяемый скриптовый язык, и Гвидо начал писать Python на досуге, позаимствовав некоторые наработки для языка ABC (Гвидо участвовал в разработке этого языка, ориентированного на обучение программированию). В феврале 1991 года Гвидо опубликовал исходный текст в группе новостей alt.sources. С самого начала Python проектировался как объектно-ориентированный язык.
Наличие дружелюбного, отзывчивого сообщества пользователей считается наряду с дизайнерской интуицией Гвидо одним из факторов успеха Python. Развитие языка происходит согласно чётко регламентированному процессу создания, обсуждения, отбора и реализации документов PEP (англ. Python Enhancement Proposal) — предложений по развитию Python.
3 декабря 2008 года, после длительного тестирования, вышла первая версия Python 3000 (или Python 3.0, также используется сокращение Py3k). В Python 3000 устранены многие недостатки архитектуры с максимально возможным (но не полным) сохранением совместимости со старыми версиями Python. На сегодня поддерживаются обе ветви развития (Python 3.x и 2.x).
4.3 Особенности языка
1. Python, в отличие от многих языков (Pascal, C++, Java, и т.д.), не требует описания переменных. Они создаются в месте их инициализации, т.е. при первом присваивании переменной какого-либо значения. Значит, тип переменной определяется типом присваиваемого значения. В этом отношении Python напоминает Basic.
Тип переменной не является неизменным. Любое присваивание для нее корректно и это приводит лишь к тому, что типом переменной становится тип нового присваиваемого значения.
2. В таких языках как Pascal, C, C++ организация списков представляла некоторые трудности. Для их реализации приходилось хорошо изучать принципы работы с указателями и динамической памятью. И даже имея хорошую квалификацию, программист, каждый раз заново реализуя механизмы создания, работы и уничтожения списков, мог легко допустить трудноуловимые ошибки. Ввиду этого были созданы некоторые средства для работы со списками. Например, в Delphi Pascal имеется класс TList, реализующий списки; для С++ разработана библиотека STL (Standard Template Library), содержащая такие структуры как векторы, списки, множества, словари, стеки и очереди. Однако, такие средства имеются не во всех языках и их реализациях.
Одной из отличительных черт Python является наличие таких встроенных в сам язык структур как тьюплы (tuple), списки (list) и словари (dictionary), которые иногда называют картами (map). Рассмотрим их поподробней.
Тьюпл. Он чем-то напоминает массив: состоит из элементов и имеет строго определенную длину. Элементами могут быть любые значения - простые константы или объекты. В отличие от массива, элементы тьюпла не обязательно однородны. А тем, что отличает тьюпл от списка (list) является то, что тьюпл не может быть изменен, т.е. мы не можем i-тому элементу тьюпла присвоить что-то новое и не можем добавлять новые элементы. Таким образом, тьюпл можно назвать списком-константой. Синтаксически тьюпл задается путем перечисления через запятую всех элементов, и все это заключено в круглые скобки:
(1, 2, 5, 8)
(3.14, ‘ string ’, -4)
Все элементы индексируются с нуля. Для получения i-го элемента необходимо указать имя тьюпла затем индекс i в квадратных скобках. Пример:
t = (0, 1, 2, 3, 4)
print t[0], t[-1], t[-3]
Результат: 0 4 2
Таким образом, тьюпл можно было назвать вектором-константой, если бы его элементы всегда были однородными.
Список. Хорошим, частным примером списка может служить строка (string) языка Turbo Pascal. Элементами строки являются одиночные символы, ее длина не фиксирована, имеется возможность удалять элементы или, напротив, вставлять их в любом месте строки. Элементами же списка могут быть произвольные объекты не обязательно одного и того же типа. Чтобы создать список, достаточно перечислить его элементы через запятую, заключив все это в квадратные скобки:
[3, 5.14, ‘s’]
[‘string’, (0,1,8), [1,1]]
В отличие от тьюпла, списки можно модифицировать по своему желанию. Доступ к элементам осуществляется также как и в тьюплах. Пример:
l = [1, ‘s’, (2,8), [0,3,4]]
print l[0], l[1], l[-2], l[-1][0]
Результат: 1 s (2,8) 0
Словарь. Напоминает тип запись (record) в Pascal или структуры (structure) в С. Однако, вместо схемы "поле записи"-"значение" здесь применяется "ключ"-"значение". Словарь представляет собой набор пар "ключ"-"значение". Здесь "ключ" - константа любого типа (но преимущественно применяются строки), он служит для именования (индексирования) некоторого соответствующего ему значения (которое можно менять).
Словарь создается путем перечисления его элементов (пар "ключ"-"значение", разделенных двоеточием), через запятую и заключения всего этого в фигурные скобки. Для получения доступа к некоторому значению необходимо, после имени словаря, в квадратных скобках записать соответствующий ключ. Пример:
d = {'a': 1, 'b': 3, 5: 3.14, 'name': 'John'}
d['b'] = d[5]
print d['a'], d['b'], d[5], d['name']
Результат: 1 3.14 3.14 John
Для добавления новой пары "ключ"-"значение" достаточно присвоить элементу с новым ключом соответствующее значение:
d['new'] = 'new value'
print d
Результат: {'a':1, 'b':3, 5:3.14, 'name':'John', 'new':'new value'}