лекции (2008) (by Михайлишин Алексей_ Жбанков Денис_ Щербинин Виктор_ Чеботарев Павел) (1160831), страница 3
Текст из файла (страница 3)
Решение проблемы – абстракция. Для каждой конкретной области приходится создавать своюабстракцию. Впервые в фортране, абстракция – подпрограммы. Именно благодаря этому скопилосьогромное количество библиотек для Fortran’а, и он все еще жив. Т.е. ЯП различаются в основном вабстракции, а не в базисе.Схема.1) Базис• Скалярный (простые ТД и операции)• Составной (составные ТД и операторы)2) Средства абстракции (новые ТД, классы, подпрограммы), пример, в языке Си тип данных FILE* абстрактный тип данных3) Средства защиты, хорошо реализованы в языке Ада.
Чем они лучше, тем больше уверенность, чтоесли программа компилируется, то она семантически тоже верна.IV) Традиционные ЯП.С точки зрения базиса в языке Си++ (после Си) появились только ссылки.Глава 1. Простые типы данных.I) Классификация1) Простые типы данных2) Числовые типы данных (в некоторых языках есть только тип Number (язык Lua) – интерпретаторсам выбирает, какой это тип – целый или вещественный)• Целочисленные• Вещественные (бывают плавающие и фиксированные (для банковских систем))3) Логические4) Символьные5) Порядковые (перечисления, диапазоны)6) Ссылки и указателиФункциональные типы данных (с одной стороны похожи на указатели, но все же это средствоабстракции)II) Целочисленные типы данныхПроблемы:1) Фиксация представления (набор)2) Беззнаковые целые (самый простой в этом смысле – Pascal, там есть только integer; а вот в Си –много таких типов, для покрытия всех надобностей программиста: char – short int – int – long – longlong)CLI – common language infrastructure (contain CTS – common types system) – стандарт: sbyte – byte,short – ushort, int – uint, long – ulong (в порядке от 1 до 8 байт).
Это используется в C#.Немного о развитии 64бит – архитектур. Процессоры Itanium (Intel) IA-64 – «родная» 64битархитектура, а x64-32 – адреса 64бит, а все остальное – 32бит, как и было (надо переписать толькокомпилятор, предложено AMD).Смешивать беззнаковые и знаковые типы очень опасно. Си, например, сравнивает их «нехорошо».Беззнаковые типы и арифметика нужны в основном для адресации (а не для счетчиков).
Поэтому досих пор много где есть беззнаковые типы (нет в Java – так они решили эту проблему, ввелиспециальный беззнаковый оператор сдвига >>>).[lect7] 2 подхода к реализации числовых типов данных1) фиксированный базис2) обобщенные числовые типыНоменклатура ЦТД:• С, С++ (фикс.
базис, но определен только char, а int зависит от архитектуры)• С#, D, M-2, Оберон (фикс. базис, ориентированы на конкретную архитектуру)• Java (фикс. базис, JVM)• Ада (обобщенные числовые типы, можно вывести новый тип, можно подтип)Примеры объявления:•••Ада: type NewInt is new integer range 0..MAX; //NewInt и integer теперь разные типы данных(i16 = INT16(ui16) – явное преобразование, а вот i16 = ui16 - нельзя)Паскаль: type NewInt = integer; //NewInt и integer совместимыС++: typedef int NewInt; //аналогично использованию #defineКвазистатический контроль – (например, в Ада или Pascal) контроль, который компилятор неявновставляет на этапе компиляции (range check, контроль присвоений разных типов); если сразу понятно, что вкоде ошибка, компилятор сообщит это, если же ошибка возможна, то вставит код контроля.III) Плавающие вещественные типы данныхНужны для математических расчетов+/- M * B^p, представление нормализовано 1/B <= M < 1, B = 2Существует проблема точности вычислений.
Если мы даже не можем точно представить все числа, то какобеспечить точность вычислений? Стандартизировали (стандарт 1985 года, IEEE-754), представлениямантиссы и степени (сколько битов выделять). А также ввели машинную бесконечность и ноль (+inf, -inf,+0, -0), все это NaN (not a number). Во всех современных языках теперь есть два типа данных: float (4byte)и double (8byte).Фиксированные вещественные типы данныхНужны, например, для представления оцифрованного аналогового сигнала. По сути, число целое (можетпринимать ограниченное множество значений, например от –M до M), но при вычислениях нужны именновещественные типы.type Data is delta 1/4096 range –M..+M; //пример фикс. типа на Аде, 1/4096 – точностьТакже придумывали особые типы данных (например, decimal – для business oriented programs, удобнеепереводить в символы) для каких-либо специфических нужд.
В языках с классовой структурой те типы,которые можно реализовать классами не вводятся в базис.[lect8] IV) Логические и символьные типы данныхboolean (операции or, and, nor, xor, equ, значения true = 1, false = 0)Так сделано практически во всех языках, кроме Си (там нет boolean, для этого используется int, простозначение сравнивается с нулем – неявное преобразование int в boolean).Сначала, для символьного типа данных хватало 1 байта. Но для многоязычной поддержки такой размерне годится. Т.е. существует две проблемы: мощность алфавита (сколько байт) и набор символов (characterset). Появилось множество самых различных кодировок (ASCII-7 – был базовым в 70е, 80е годы; включаетв себя символы: 0-31 – непечатаемые, A-z, 0..9, пунктуация).
SBCS (single byte character set) – однобайтовоепредставление символьных типов данных, первоначально в ЯП было именно так. Для национальныхалфавитов предназначались символы 128-256. Но даже для Европы этого не хватало. [Рассказ про то, какпоявилась КОИ-8Р – отбрасывание старшего бита почтовыми серверами].
Японцы ввели систему на подобии UTF, еслипервый бит = 0, то байт считался ASCII, иначе добавлялись дополнительные байты. UNICODE (USC2 –universal character set, название по ISO; практически то же самое что и UNICODE) – универсальнаякодировка, предполагала количество символов от 0 до 65535. Начиная с WinNT, MS использует UNICODE.
ВC# и Java тип данных char подразумевает именно UNICODE (2 байта). А в старых языках просто ввелиновые типы данных (по сути, просто был define от unsigned short). В C++ ввели wchar_t, который не былпросто define (typedef), т.к. надо было поддерживать перегрузку функций (вызов от разных типов данных).Параллельно с UNICODE был разработан стандарт UTF (UTF-7) для того, чтобы экономить трафик (восновном по сети передается англ. тексты и цифры). Весь UNICODE разбивался на промежутки 0-127, 1282047, 2048-65535 и кодировался так, что любой ASCII-текст был одновременно UTF из диапазона 0-127 ит.д. Тогда, если нужен расширенный алфавит, то передавалось больше байтов, если же нет – то меньшее.Порядковые типы данных:• диапазоны• перечислимые типыЕсли L и R являются данными типа T, то L..R – диапазон.
Должны быть определены функции pred, succ(как в Pascal), определенные только для типов, которые созданы на основе целого типа данных. Диапазонывпервые появились в Pascal и после этого были практически во всех ЯП. Они полезны т.к. используетсяквазистатический контроль (см. пред. лекцию). Однако диапазонов нет в Обероне, так как без них впринципе можно обойтись. Но как объяснить, что их нет в Java и C#? Диапазоны – не расширяемый типданных (наследование не проходит), что противоречит концепциям ООП.[lect9] V) Перечислимые типыВ Обероне конструкция входит в язык, только если она необходима в нем.
Перечислимые типы были убраныиз языка Оберон, т.к. они противоречат расширению типа. Перечисляемый тип - это просто удобный способименования целочисленных констант.••1995 год - Java, проектировался с нуля1999 - C#, содержал перечислимые типы. В первой главе руководства к C# автор "оправдывается" втом, что в язык введены перечислимые типы данных.
Причина - перечислимые типы удачноподходят для визуального проектирования. Например, свойства компонентов удобно представлять ввиде перечислимых типов: выравнивание - влево, вправо, по центру. Такой текст кода сперечислимыми типами называют самодокументированным.Еще одно неприятное свойство перечислимых типов: вместе с именем типа происходит неявный импортимен значений, и импорт происходит на том же уровне видимости. Вопросы неявного импорта сложны имогут приводить к труднообнаруживаемым ошибкам.В Java 5.0 (Java 2) в 2005 году перечислимые типы вернулись.
Подход к ПТД в Java 2 снимает всепретензии к ним в других языках. Здесь это не целочисленный тип, а класс.Как перечислимые ТД реализованы в различных языках.Pascal, Ада, М-2, Delphi:type T = ( ... )type T is ( ... )Фактически перечислимые типы реализуются с помощью целочисленных констант. К этим типам применимафункция ord() - явное приведение перечислимого ТД к числовым константам. В языке Ада символьный ТД частный случай перечислимого типа данных. Кроме идентификаторов констант могут быть литералыперечисления (напр.: 'A').Таким образом, литералы перечислений могут пересекаться, т.е.
иметь несколько форм в одной и той жеобласти видимости (что недопустимо ни в Паскале, ни в других подобных языках):type RGBCOLOR is (... Red ...);type TrafficColor is (Red, Green, Blue);Ада:function Fun return T isобъявление локальных именbeginоператорыend Funx:T;x:=Fun;Паскаль:y:=Red;Т.о. присваивание перечислимых значений можно рассматривать как вызов функции, которая все времявозвращает одно и то же.procedure P(x:RGBColor);procedure P(y:TrafficColor);P(Red) - неоднозначность при компиляции. Для этих случаев в языке Ада существует "указание типа":Тип'ЗначениеДля данного случая:P(RGBColor'Red) - указание использовать тип RGBColor.C#:enum E {c1, c2, ..., cN} //здесь видно только имя E, чтобы обратиться например кcK, надо написать: E.cK;Таким образом, проблема неявного типа уходит, более того программы не становятся менее читабельными.Можно указывать базисные типы:enum E:byte{ ...