Языки программирования, 05 лекция (от 19 сентября)
Материал из ESyr's Wiki pages.
Предыдущая лекция | Следующая лекция
Содержание |
Связывание
Статическое связывание — во время компиляции
Динамическое связывание — в момент выполнения
- Данный код на С++:
(C++) Х х; Х.F();
- Транслируется в:
(Asm) CALL _F
Когда произойдёт связывание? Кто и в какой момент решает? Правильный из вызова дать нельзя. Для ответа надо посмотреть на объявление Х, и посмотреть, виртуальная функция или нет. Но это может быть недостаточно, так как Х может быть унаследован от ХХ, где функция объявлена виртуальной. Для невиртуальных методов можно по тексту программы можно определить, какая функция вызывается, для виртуальных — в общем случае нет.
Виртуальная машина
Виртуальная машина языка — некая машина, у которой язык программирования является машинным языком. Это понятие возникло в 60-е годы на базе языка Algol 60, так как понятие ВМ позволило разделить окружение языка и сам язык. До Алгол 60 окружение включалось в язык, например, у Паскаля стандартные функции (ввод-вывод) есть часть языка.
Понятие виртуальной машины оказалось не чисто теоретическим понятием. Сейчас понятие ВМ является часто употребляемым и не столь ясным. Идея реализовать в железе ВМ было довольно частой, особенно в 60–70 годы.
- SYMBOL (Европа и Америка) для, которой языком был Алгол 60 (не являлась чистой, так как некоторые конструкции языка не были реализованы).
- Burroughs работал на расширенном варианте Алгол 60 со стеком и был чистой ВМ
- в СССР для машин Мир–1, 2, 3 единственным языком был Аналитик — русифицированный и расширенный вариант Алгол 60, например в Аналитике были опреации для символьного дифференцирования и интегрирования. Но в последствии развитие собственных машин было убито и СССР перешло на копирование чужих платформ.</p>
- В 70-е годы получили распространение LISP-ВМ (LISP-machines). Аппаратная реализация была нужна для увеличения быстродействия.
Сейчас с точки зрения количества различных архитектур сейчас их не очень много. И аппаратная реализация выглядит анахронизмом, так как реализация эта дорогая и, что еще хуже - не гибкая, так как языки сложны и отсутствует универсальный язык. Кроме того, в языке имеются недостатки, эти недостатки распространяются на архитектуру. Сейчас же языки ориентируются на архитектуру и базис очень и очень примитивен.
Понятие ВМ в том виде, в котором оно сформировалось
Стандартным вариантом языка Smalltalk есть реализация в виде байт-кода. Была попытка аппаратной реализации этой ВМ в виде Катаны (так и не была реализована), но была программная реализация. Понятие ВМ — JVM — Java Virtual Machine.Sun стандартизовала язык Java, байт-код и набор системных вызовов = Java RunTime. Любой интерпретатор - и есть JVM. Понятие ВМ оказалось достаточно мощным и гибким. Понятно, за счёт чего обеспечивается гибкость. За счёт того, что мы не зависим от реализации. Программы, удовлетворяющие стандарту Pure Java, действительно переносимы.
Чем мы платим? Производительностью. Например, Lotus Notes, написанная на Java, сильно тормозит. Как только речь идёт о нетривиальных приложениях, сказываются проблемы с производительностью. Спор о эффективности-неэффективности ведётся с 50-х годов.
Каждые 10 лет говорят, что через 10 лет компьютеры будут так быстры, что ничего уже не будет тормозить.
Действиетльно, сейчас эффективности уделяется меньшее внимание, о чём говорит распространение скриптовых языков — PHP, Perl, JSP, ASP, они используются на стороне сервера. Но они остаются достаточно специализированными, они занимаются обработкой и генерацией текста, и с точки зрения программирования это достаточно узкая область, а Java претендовала на роль универсального языка, и роль эффективности тут больше.
.NET Framework ещё одна попытка, где стандартизируется только окружение, а не байт-код. ЯП.NET — MIL — JIT компиляция. Это несколько более эффективно. То есть стандартизован некий виртуальный язык. Одно время говорили, что вместо WinAPI будут использовать защищённые вызовы .NET, но это нескоро, так как как только начинаешь писать что-то хитрое, сразу надо вспоминать, как вызывать WinAPI.
Часть 1. Основные понятия традиционных процедурных ЯП
Будем рассматривать не Алгол и Фортран, а современные ООП языки, точнее ту часть, где они наследуют традиционную парадигму
- Базис
- скалярный
- структурный
- Средства развития
- Средства защиты
Глава 1. Скалярный базис.
Пункт 1. Классификация простых типов данных
Простые типы данных (они же примитивные) — не имеют внутр структуры.
- Арифметические типы
- Целые
- Вещественные
- С плавающей точкой
- С фиксированной точкой — не во всех языка поддерживается это разделение
- Логический тип
- Символьные типы
Целые, символьные и логические ТД сводятся к целым.
Типы, основанные на других типах:
- Ссылочные типы / Указатели
- Порядковые типы
- Перечисление
- Диапазон — производный тип данных, опирающийся на другой тип данных — перечислимый
- Процедурные (функциональные) типы данных — не есть указатель, но его разновидность — в Modula-2, Oberon, Ada 95.
Любой ЯП обладает подобным набором ТД. Традиционно базысным типом является целый тип. Инновационный подход - использование строк как базисного типа.
Пункт 2. Целые типы и проблема представления беззнаковых чисел
Две проблемы, возникающие при реализации целых чисел: Представление беззнаковых чисел и длина
Решения проблемы знаковых-беззнаковых типов:
-
Pascal — два отдельных типа
-
C — две разновидности типа
-
Java — только знаковый
в C# — все типы парами: short — ushort; int — uint; long — ulong. По традиции byte беззнаковый, посему sbyte — byte. Длина зафиксирована: byte – 1, short – 2, int – 4, long – 8 байт.
Какая проблема связана с беззнаковым типом — проблема преобразований из и в знаковый тип.
- Классический пример (На одной архитектуре он зацикливается, на другой работает нормально):
(C) char c; while ((c=getchar())!=EOF) {}
Проблема в том, что EOF = –1. И все функции стандартной библ возвращают знаковый тип — int. В одних архитектурах char знаковый, в других — беззнаковый. Тогда получаем такую цепочку преобразований:
0xFFFF => 0xFF => 0x00FF.
Для правильной реализации надо писать int c.
В стандартном Паскале не было беззнаковых типов.
В Modula-2 было два типа INTEGER и CARDINAL, которые неявно друг к другу не преобразовывались.
Программист-профессионал должен включать макс уровень предупреждений и добиваться, чтобы у него предупреждений не было.
Была мода в 80-е годы делать знаковый и беззнаковый типы несовместимыми, так как явное преобразование заставляет задумываться над ошибками. Страуструп в первом варианте Си с классами запретил преобразование между знаковыми и беззнаковыми типами. Ни одна из существ программ на языке C не прошла тест на компиляцию в первом варианте C++. Но эти программы работают, правильно работаю. Объяснение состоит в том, что профессионалы представляют проблемы, с этим связанные, и эти проблемы решают. В результате неявные преобразования были разрешены (так как главным критерием при проектировании С++ являлась совместимость со стандартными библиотеками), но при опасных выдаётся предупреждения. Дабы не ограничивать возможности программиста, Страуструп в результате сдался.
Другим решением была в Java, самое простое решение — запретили беззнаковые типы данных. А зачем вообще нужны беззнаковые типы? Чуть больше диапазон значений в одну сторону, что было важно раньше, когда машины были большие, а байты маленькие. И беззнаковые типы тогда были нужны.
В Pascal не было беззнаковых типов — В Modula-2 были два несовместимых типа — В Обероне один беззнаковый тип байт и остальные только знаковые.
Modula создавалась для 16 битных архитектур, и это было важно, а Oberon для 32, где неважно, 2 миллиарда или 4.
Почему же в Delphi и C шарп есть беззнаковые типы? Для адресов и манипуляции с ними. Поэтому в языках системного программирования оставляют беззнаковые типы, а Java не является языком для системного программирования, посему проблем с беззнаковостью решили не иметь.
Языки Программирования
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Календарь
чт | вт | чт | вт | чт | вт | чт | вт | чт | вт | |
Сентябрь
| 05 | 07 | 12 | 14 | 19 | 21 | 26 | 28 | ||
Октябрь
| 03 | 05 | 10 | 12 | 17 | 19 | 24 | 26 | 31 | |
Ноябрь
| 02 | 14 | 16 | 21 | 23 | 28 | 30 | |||
Декабрь
| 05 | 07 | 12 | 14 | 19 |