Лекция 07 (1160807), страница 2

Файл №1160807 Лекция 07 (лекции (2002)) 2 страницаЛекция 07 (1160807) страница 22019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 2)

В традиционных ЯП решить эту проблему можно только с помощью объединений. Объединение – расширения понятия записи. Впервые объединения появились в языке Паскаль. Запись в Паскале – это постоянная часть и вариантная часть. Этот синтаксис был принят и в других языках практически один в один.

record

{ постоянная часть – возможно пустая совокупность описания полей ]

[ возможно пустая вариантная часть ]

end;

При этом вариантная часть выглядит так

case имя_дискриминанта : тип of

значение 1: (структура 1);

значение 2: (структура 2);

Где каждая структура является описанием записи без скобок и слов record, end.

Есть специальное поле, которое мы называем дискриминант. Структура записи выглядит следующим образом


постоянная часть


дискриминант

структура 1 структура 2 структура 3 …


Структуры 1, 2 и 3 могут сильно отличаться.

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

procedure HandleEvent (VAR E: Event);

которой по ссылке передается параметр - событие, будет выглядеть как большой оператор выбора

case E.EvType of

KBEvent: begin … end;

MouseEvent: begin … end;

end;

Языковые абстракции оператор выбора и объединение очень тесно связаны между собой. И программа в большинстве случаев имеет такой вид. Это позволяет считать, что Event – это в некотором смысле какой-то обобщенный ТД, который служит объединением частных случаев.

У данного стиля программирования есть проблема, связанная с ненадежностью. Программист сам должен связывать значение дискриминанта и операторы обработки. Никаких возможностей контроля у компилятора нет. Значение дискриминанта в языке Паскаль мы можем ошибочно изменить. В результате память отведена по одному варианту, но дискриминант изменен, и поэтому программа, которая обрабатывает соответствующие части, будет работать не правильно. Может получиться так, что память отведена по самому короткому варианту, а мы ошибочно поменяли значение дискриминанта и работаем по длинному варианту. Следовательно, мы портим память.

VAR x: Event;

В большинстве языков, в которых есть вариантные записи, компилятор в случае такого объявления отводит память по максимуму.

В языке Паскаль есть специальная процедура new(p), где р – указатель на тип данных Т. У этой процедуры есть еще один синтаксис: new(p, t1, …,tn). В случае, если р указывает на запись с вариантами, то t1, …, tn – значения дискриминантов во вложенных вариантных записях. Но в реальной жизни, как правило, синтаксис сводится к new(p, t), где t – это значение дискриминанта. В этом случае память будет отводиться по тому варианту, на который указывает значение t. Самое неприятное в этой процедуре то, что в Паскале в этот момент не происходит инициализация дискриминанта. Надо писать что-то вроде

p^.discr := t;

Возникает некоторая ненадежность. Если мы напишем

new(p, t1);

p^.discr := t2;

память будет отведена по одному варианту, дискриминант проинициализирован по другому варианту.

Записи с вариантами необходимы. Поэтому объединения есть во всех традиционных ЯП.

Приведенный синтаксис в языке Паскаль не полный потому, что имя дискриминанта может отсутствовать. А зачем нужен дискриминант, если поле отсутствует? А как без этого в языке Паскаль, реализованном на машине БЭСМ-6, получить доступ ко всем видам числа? Описать соответствующую структуру как неразмеченное объединение.

type word =

record

case Boolean of

true:(bits: packed array[1..48] of Boolean);

false:(w: integer);

end;

48 битов – длина ячейки памяти в соответствующей архитектуре. integer занимает 48 битов. Значит, обе эти части занимают одно и то же место, но они задают разную интерпретацию. Таким образом, на уровне языка без всяких побитовых операций мы можем получить доступ к отдельным битам. Т.е. описывая переменную

x: word;

мы можем писать

x.w := 127;

x.bits[1] – доступ по другому варианту. При этом нет никакого явного дискриминанта. Иногда нам нужны неразмеченные объединения. В языке С только неразмеченные объединения без постоянной части. По определению все поля, которые описаны в union, размещаются с одного и того же адреса.

Есть еще одна проблема – проблема трудной модификации программ. Если у нас есть некий комплекс процедур и функций, основанных на механизме событий, и появляется новое периферийное устройство, появляется еще один класс событий. Это события, которые поступают от нового периферийного устройства. Нужно расширить соответствующий ТД, пролистать всю программу, найти везде соответствующие case и расширить их. В случае если мы модифицируем объединение, мы должны модифицировать практически всю программу. Мы должны перекомпилировать всю систему. Если мы забудем что-нибудь исправить, это значит, что данный тип события в данном обработчике обрабатываться не будет. Компилятор не сможет найти такую ошибку.

Ненадежность и трудность модификации – основные проблемы, связанные с объединениями в традиционных ЯП.

Язык Ада создавался прежде всего с расчетом на надежность. Каким образом создатели языка Ада попытались решить эту проблему? Принцип языкового дизайна языка Ада: если есть какая-то критичная технологическая потребность, в базис языка вводится некоторая конструкция, которая отвечает этой критичной технологической потребности. Для решения проблемы объединения типов появляется новая концепция – параметризованные типы записи. Общий синтаксис параметризованной записи

type T(Discr: DT) is record

[постоянная часть]

case Discr of

when зн1|зн2|зн3 => вариант1 вариантная

when зн4 => вариант2 часть

end record;

Т.е. мы параметризуем запись дискриминантом. Ситуация аналогична ситуации с неограниченными массивами. Мы не можем написать

А:T;

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

А:T(t);

t должно принадлежать дискриминантному типу DT.

Тоже самое и в случае, если ОД размещается в динамической памяти.

type PT is access T;

X: PT := new T(t);

Просто написать new T в этом случае нельзя – компилятор выдает ошибку. Нельзя описать ОД без указания значения дискриминанта. При этом автоматически происходит инициализация значения дискриминанта. Изменяться значение дискриминанта не может. Т.е. мы не имеем права писать

A.Discr := -1;

Все объединения могут быть только дискриминированными, т.е. размеченными.

Таким образом часть ненадежности снимается. Однако проблемы с трудностями модификации остаются. ООЯП эту проблему снимают. В современных ООЯП, особенно в тех, которые проектировались без соображений совместимости с существующими языками, понятие запись с вариантами отсутствует. Это такие языки как Java, C# и Оберон. В языках С++ и Delphi понятие записи с вариантами осталось исключительно для совместимости со старым кодом. И если понятие struct расширено в языке С++, то понятие union никаким образом не расширяется потому, что в программах на С++ union употреблять не надо. В С++ есть механизм наследования, который обеспечивает механизм объединения типов, но без проблем, связанных с записями с вариантами. Именно поэтому в основном все современные языки объектно-ориентированные.

Множество.

Впервые множества появились в языке Паскаль.

type T = set of D;

где D – это некоторый дискретный тип данных. Основные операции, которые можно проводить над множествами это операция объединения двух множеств +, операция разности двух множеств -, операция пересечения двух множеств *. Кроме это есть конструктор множества [x1, …, xn]. Операция x in S дает логический результат – true, если х содержится в S, и false, если нет. Операция добавления элемента выглядит так

S:= S+[x]

Аналогично исключение элемента может быть описано с помощью операции -.

В языке Модула 2 была полностью перенята эта концепция, за исключением того, что для повышения эффективности компиляции были введены псевдофункции INCL(S, x) - включить элемент х в множество S, и EXCL(S, x) – исключить элемент х из множества S. В стандарте языка Паскаль ничего не сказано про мощность множества D. Но в большинстве реализаций она ограничена. Наиболее простая реализация множества – упакованный массив булевского типа.

packed array [D] of boolean;

Индекс D дискретного типа. Если S – переменная этого типа, то, если S[x]=true x содержится в этом множестве, если S[x]=false – не содержится. В Паскале, Модуле 2 и многих других языках множество реализуется в виде битовой шкалы, которая пакуется в одно или два машинных слова. Отсюда ограничение на размер множества в 32 или 64 элемента. Основное назначение множеств в такой реализации – именованный доступ к отдельным битам числа. В Паскаль и Модула 2 нет побитовых операций потому, что их можно заменить манипуляциями с объектами множества. Установка бита – включение соответствующего значения, сброс бита – исключение. Чаще всего такие манипуляции с именованными битами нужны для программ, которые управляют вводом/выводом. Регистры устройств – некоторые ячейки памяти. В ряде систем регистры устройств являются частью ОП (например, система PDP 11), а в ряде систем это особые отдельные ячейки, которые адресуются с помощью специальных команд ввода/вывода in и out (например, системы, построенные на базе процессоров Intel). Управление внешними устройствами осуществляется с помощью установки или сброса особых битов в регистрах внешних устройств. Получается, что для решения очень частной задачи в базис языка вводится некоторое понятие.

В языке Модула 2 дополнительно был введен специальный ТД

BITSET = SET OF [0..N-1]

Он был встроен в базис языка (т.е. это стандартный идентификатор языка). N – количество битов в слове для данной реализации.

В языке Оберон все дискретные ТД сводятся к ТД integer. Понятие множества исчезает полностью. Вместо него в Обероне появляется ТД, который называется SET. Он соответствует понятию BITSET в языке Модула 2.

В языке Ада понятия множество нет потому, что в Аде можно описывать упакованные массивы. Вместо того, чтобы встраивать в базис языка ТД множество, Ада предлагает нужный вариант множества реализовать в виде упакованного массива. В языке Ада можно перекрывать стандартные знаки операций. Учитывая это, можно описать ТД – упакованный массив логических чисел, перекрыть для него операции +, * и - , и работать с ним, как мы работали с множествами в языке Паскаль.

В современных ООЯП, таких как Java, C#, Delphi, C++, понятие множества отсутствует. Реализация множества на Паскале – битовая шкала. Множество можно реализовать и на других структурах данных. Множество всех целых чисел в виде упакованного массива скорее всего представить не удастся – большим будет диапазон индексов. А с помощью дерева поиска – можно. Тогда операция поиска – реализация операции in. При этом множество превращается в более обобщенное понятие – таблица. В множестве мы храним булевское значение, которое говорит есть элемент в множестве или нет. В таблице есть понятие ключа и связанное с ним понятие данных. Т.е. в таблице хранятся данные, а ищем мы их по ключу. В простейшем случае ключ может совпадать с данными, в этом случае мы приходим к обычному понятию множества. Таблица может реализовываться с помощью дерева поиска, хэш-таблицы. Какая реализация лучше – зависит от ситуации. (В случае если размер данных сопоставим с размером хэш-таблицы, она перестает работать. Есть специальные методы перехэширования.) Поэтому встраивать какой-то вариант в язык – не лучшая идея.

Характеристики

Тип файла
Документ
Размер
291,5 Kb
Материал
Тип материала
Высшее учебное заведение

Список файлов лекций

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6314
Авторов
на СтудИзбе
312
Средний доход
с одного платного файла
Обучение Подробнее