И.Г. Головин - Конспект лекций по курсу Языки программирования (1161120), страница 12
Текст из файла (страница 12)
Это очень простойобъектно-ориентированный язык.Типы данных в языке Оберон:BYTESHORT INTINTEGERLONG INTREALCHARТакже были функции ORD и CHR.62В Оберон2 появились динамически связываемые процедуры. Компилятор языка Оберон2занимал менее 1000 строк. В Оберон2 Вирт отказался от диапазонов. Главная концепцияОберона была в расширении типов, а диапазоны плохо поддерживают расширение. Массивыупрощаются:INTEGER 0..N-1ARRAY N OF TВ современных языках программирования массивы ведут себя именно так.Профессиональные программисты игнорируют эти возможности.Перечислимые типыПеречислимые типы были придуманы в языке ПаскальType T = (val1, …, valN);На самом деле это тот же диапазон, в котором каждому значению присвоен уникальныйэлемент.В языке Ада перечислимый тип задается как совокупность литералов, то есть любаяпеременная, представимая как символьная (не строковая) переменная, может бытьлитералом перечисления.
Поэтому у нас есть некоторая «внутренняя» кодировка (способприсвоения значению литерала некоторого целого числа), и мы не привязаны ни к какойвнешней кодировке.Перечислимый тип данных в C – это короткий способ задать совокупность констант.enum -> intint -> enumПриведения типов являются небезопасными (точнее, безопасно приводить из enum в int, нообратное преобразование небезопасно). Поэтому в языке C это просто наименованиецелочисленных констант.Технические проблемы при использовании перечислимого типа:1) проблема ввода-вывода1995 Java диапазона нет, перечисления есть2) наследованиеf(T) => derived f(T)3) неявный экспортАда:type T is (c1, …, cn)type T is (w1, …, wN)Константы в разных перечислимых типах данных могли совпадать.63type TrafficColor is (Red, Green, Blue)type Color is (Red, Green, Blue)Procedure P (X: Color) (Blue)Procedure P (Y: TrafficColor) (Red)P(Red) – что это за функция?P(Color.Red) – однозначно можно определитьC# – перечисления 1) надежны 2) поддерживают компонентыПочему в С# ввели перечисления? Потому что они хорошо сочетаются с языком IDL(Interface Definition Language – язык описания интерфейсов) и компонентнымпрограммированием.
С точки зрения современных языков программирования, компонента –это класс. Причем класс рассматривается отдельно от способа генерации объектов класса.Для генерации объектов класса используется шаблон Фабрика. Фабрика – это класс, методыкоторого генерируют объекты связанных классов. В C# есть ключевое слово sealed class, вJava – final class – это классы, от которых нельзя наследовать.Визуальное отображение компонент: toolbox с иконками/списком компонент.
В окнесвойств можно задавать имя и значение.Пусть есть свойство C типа Color, оно может принимать значение из перечислимого типа.Решение: можно разделить область видимости, сделать отдельную область видимости.Второе решение: рефлексия – отображение свойств исходного текста в бинарном коде. C,C++, Asm – антирефлексивны.Пример – имена функций. Атрибут: 1) рефлексия 2) указание компиляторуАтрибут [Flags] целочисленный тип данных. And, or.Любой перчислимый тип данных совместим с константой 0 (true/false).
Используется дляинициализации начальных значений.Java 2005 – много изменений по сравнению с предыдущими версиями языка. Переченьизменений – перечислимые типы данных. Неявно: константа целочисленного типа данных.byte, … -> традиционная интерпретация. Но у Color есть 4 интерпретации (имяперечислимого типа, имя пространства имен, имя класса, переменная-статический член).Пример: enum: enum Color { Red, Green, Blue } .
Функции-члены, конструкторы. Можнореализовать toInt(). Расширение компилятора: генерирует класс специального вида.Порядковые типы данных делятся на классы и примитивные. Выделяется ссылочный типданных:X a; – здесь ссылке присваивается некое нулевое значение.a = new X();Smalltalk: что угодно – это объект. Исследовательский язык программирования длягенерации прототипов.64Где могут появляться значения: в контексте определения класса.class Xint i;A b;iA…Java: хранится ссылка.C#: все должно быть объектным; неэффективно в работе с примитивными типами данных.Упаковка, распаковка. Класс-оболочка – настоящий класс.s.toString() (или s.ToString())Чем удобно наличие класса-оболочки?строка -> целое, можно настраиватьParse {int Parse (…, <целое число>)}Указатели и ссылкиСильная сторона и большая дыра.Адрес перешел из языка Ассемблера в языки C и C++.BCPL.C отличался типизацией адресов.
Тип в языке C – шаблон, которому должен следоватькомпилятор при распределении памяти.[] – применимо к любому указателю.X a[N] равносильно X* const a;Пример (Fortran)SUBROUTINE P(A, N)DIMENSION A(N,N)f(float* a, int n)a[i*N + j] – неудобный для математиков способ работы с таблицей в C.Указатель:1) ссылка – средство для доступа к объекту без копирования2) ссылка на анонимные объекты в динамической памяти.65Языки программирования подразделяются на «чистые» и «нечистые» в отношенииуказателей. В «нечистых» языках, подобных языку Ассемблера, существует абстракцияадреса на уровне языка.Пример (Ада 83)type Pt is access T;p1type PT = DTВ работе с указателями возникает проблема «курицы или яйца».type T is recordnext ptr…type PT = pointer to TВ C и C++ эта проблема решается при помощи typedef.typedef X* t;Синоним X* теперь t, не определяет нового типа.X* t – как сделать, чтобы компилятор был счастлив?Пример (Ада)type Pt is access;type T is record;X is PT;Пример операций, которые можно делать с указателями в Ада:X := new T;P->(c)P.all ~*pp^Что еще можно сделать с указателями? – больше ничего.Проблемы, возникающие при работе с указателями:661.
Висячая ссылкаX* pa = new X();X* pb = pa;delete pbl;Разыменование – это ошибка. Может упасть, а может и не упасть.2. МусорВторая проблема – мусор. В языке Ада нет операции delete (из соображенийнадежности). В нечистых языках сборка мусора невозможна.Итак, указатель – языковая абстракция понятия адреса. С точки зрения указателей все ЯПделятся на те, в которых есть понятие указателя и в которых нет. Из тех ЯП, которые мырассматриваем, указатели полностью отсутствуют в языке Java, и они отсутствуют в C#(указатели присутствуют в неуправляемой части кода, но мы ее рассматривать не будем).Понятие указателя заменено на понятие ссылки. Но опять же есть строгие и нестрогиеязыки.1.Строгие (АДА, Стандарт Паскаля, Оберон )Операции: == , !=, ↑ в строгих языках – только для ссылок.Упрощается жизненный цикл объекта.Пример (Оберон)TYPE PT = POINTER TO T;X: PT;X.nameЯвно указано, что существует динамическая сборка мусора.В некоторых реализациях АДА рарешена динамическая сборка мусораПример (Ада)type PT in access T;X : PT;X := new T;В некоторых реализациях АДА рарешена динамическая сборка мусораКак превратить строгий язык в нестрогий? Взятием адресаP±i //указатель разыменованный, говорить о котором невозможно,P[i] // но добавляется гибкость67~*(p+i)Если в строгий язык добавить динамическую сборку и отказаться от понятия «указатель»(вместо этого использовать ссылку), то можно решить эту проблемуJava, C#, C++/CLIВ С# есть понятие указателя, но взятия адреса нет (можно использовать malloc,realloc…).Есть конструкция вида unsafe{…}.
Она необходима для1)того, чтобы использовать код на С–подобных языках,2)эффективности С.Запускать unsafe-приложения можно не на всех системах.Ссылка – аналог имени x.[]Ссылки есть в следующих языках: C++,Java,Delphi,C#,SmallTalk…В этих языках ОД соответствует ссылка. Это означает, что реализована объектнореференциальная модель. Ссылка указывает на объект в динамической памяти. Жизненныйцикл объекта упрощается. Инициализация возможна только при помощи new().Такжесуществует специальная операция освобождения объекта (free), либо сборка мусора.Общий вид ссылки: T& refИнициализация ссылки в С++:1) При помощи объекта в статической памятиОбщий синтаксис: T& ref = a;int a = 0;in& refa = a;refa = 1;cout << a;2) При помощи объекта из динамической памятиT& ref = *pa;3) формальный параметр4) член класса(список инициализации)Генерация объекта:Обращение к менеджеру памятиВ выделенной памяти размещается объектВызов конструктораУничтожение объекта: Free (Delphi)p.free – операция уничтоженияВозможен случай, когда две ссылки указывают на один и тот же объект:X a;A = new X();68X b= a;//a,b один и тот же объектПроблема эффективности char,int – накладно размещать ссылки в памяти.В С++ с точки зрения реализации ссылку всегда можно отождествить с адресомПередача параметров по ссылке:P(var T:q)Область ссылки ограничена формальным параметромJava(и другие объектно-референциальные модели)X a;ссылка не мнимаяf(a)объект можно изменить, ссылку - нетВстроенной операции копирования объекта в таких языках нет.С# интерфейсIDisposableМетод Dispose – уничтожает объектИзменить состояние объекта можно только вызовом метода этого объекта.
Есть методClone.В Java есть ключевое слово final => нельзя ничего изменятьSmalltalk: всё есть объектВ С# Value Types (примитивные ТД, перечислимые, структурные)Ада 83 – нет понятия процедурных ТДАда 95 – появилось понятие процедурных ТДАда 2005:CALL P «ссылка на функцию»ExternVoid f(…)API привязаны к C,C++Указатель на что угодно – не может бытьX : INTEGERX : aliased INTEGER; – от X можно взять адресType PA is access all INTEGER – нестрогий указательX: PAX = new INTEGER;69Y: aliased INTEGERX:= Y’ access;Так писать нельзя:A: PA: new INTEGERA: X’ accessСредства дополнительного контроля: у компилятора есть возможность контролироватьРасширение языка с сохранением предыдущих конструкций.Вывод по примитивным типам данных:В современных ЯП происходит тенденция упрощения базиса.