лекция 18 (Языки программирования (лекции) (2008))

2019-09-19СтудИзба

Описание файла

Файл "лекция 18" внутри архива находится в папке "Языки программирования (лекции) (2008)". Документ из архива "Языки программирования (лекции) (2008)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "лекция 18"

Текст из документа "лекция 18"

Языки программирования.

Лекция 17.

ИС в Java, C++, Delphi.

При обработке ИС мы выделяем 4 аспекта:

  • определение

  • возбуждение

  • распространение

  • обработка

На примере яп Ада мы рассмотрели принципы обработки ИС, эти принципы заимствованы современными яп .

- exception (псевдотип, объекты которого являются ИС (6 предопределенных), пользователь может сам определить свои константы)- определение

- raise имя_ИС - возбуждение

-принцип завершения(динамической ловушки)- распространение

-when имя1 {| имя}=> операторы (среди операторов может быть и raise--> перевозбуждение данной ИС), например блок не знает, как окончательно подавить данную ИС-обработка

Что же с языками Си++, Delphi, Java, Cи#?

Обработка исключений тотальна(как и в Аде), мы не можем написать программу, в которой не было бы ИС.

В Java нагрузка на обработку ИС ложится на ядро виртуальной машины.

В Cи# - на ядро ОС,

В Дельфи приходится эту поддержку "таскать за собой".

Эти яп -тотальны, т.к в Java и Дельфи программирование в терминах одного языка и одной ОС, в C# в терминах общей унифицированной системы типов.

Во всех этих языках есть единый тип, от которых происходят все исключения.

1.Определение

В C++ не любые аварии можно выразить в терминах С++ (так как эти ИС могут быть вызваны подпрограммой на языке С, на ассемблере,...).ИС в С++ ассоциируются только с пользовательскими исключениями, предопределенных ИС нет. В некоторых компиляторах (Microsoft) есть возможность обертывать структурированные ИС в стандартные С++ исключения, происходящие от исключений , порожденные ОС.

В С++ подход следующий:

-В С++ ИС - это произвольный тип данных.

Так как в C#, Java и Дельфи всё унаследовано от класса Object, поэтому исключения наследуются от специальных типов данных.

Java - Throwable

Cи# - Exception

Delphi - TException

Все эти типы содержат строку типа String, содержащую описание ИС(по крайней мере текст- сообщение об ошибке и методы для вывода его на экран ).

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

Программист на С++ начинал работу с исключениями с того, что сам писал свой класс типа CException, в котором определял, например, описание ИС, имя файла и номер строки, где произошла эта ИС. В C#, D, J даже этого делать не надо - всё уже есть. Т.к. система встроена в язык (наличие стеков вызова, откуда программист может узнать, где произошла ошибка, т.о. при завершении программы по необработанной ИС, можно, по крайней мере, распечатать стек вызовов).

2. Возбуждение ИС

В С++ есть единственный способ возбуждения ИС - это оператор throw.

Почему Страуструп не стал использовать ключевое слово raise (так как он за основу брал исключения языка Ада )?

Т.к. в 80-х гг в основном программируют на С. Но в Юниксе raise - системный вызов посылки сигнала самому себе и это сидит в стандартном заголовочном файле юникса. А Страуструп не хотел вводить ключевые слова, которые конфликтовали бы с чем-то из юникса.

throw выражение- тип выражения определяет тип ИС

throw "error" - с этим исключением связывается тип char *

throw CException(); - с типом CException, предполагается ,что соответствующий класс существует

throw new MathError; - с типом MathError *, соответственно ИС должна отводится в особой памяти, т.к. проблема может быть в нехватке динамической памяти.

Поддержка ИС довольно требовательна к ресурсам.

Вызов ИС

(т.к. в этих ИС - объекты классы--> располагаются в динамической памяти--> любые исключения- ссылки на объекты соответ исключения):

Java - throw new Exception();

C# - throw new Exception();

Delphi - raise TException.Create();

Лучше всего создать свой тип, производный от данных.

В этих яп предопределенные ИС содержатся в библиотеке, так в Дельфи ИС, порожденные ОС, можно обернуть в специальный объект типа TException.

3. Распространение ИС:

Во всех языках, кроме языка Ада, принят принцип динамической ловушки или стратегия завершения. Весь блок, в котором произошла ИС считается аварийным и в конце блока ищутся ловушки

...

f() {

...

throw new Err();

}

Если внутри блока, который содержит throw new Err(); то блок, который вызвал данный считается аварийным, т.е.

становится эквивалентным:

{

f();

throw new Err();// аварийная ситуация

}

И т.д. пока не будет найдена ловушка.

В C++ есть 2 ситуации. Можно повесить обработчик terminate вызывается, если выполнение программы заканчивается ели не найден обработчик вызванной ИС. Вызов terminate = вызов обработчика ситуации, когда произошла авария, а обработчика не нашлось.

typedef void (*pvf)(void)(процедура без параметров)

pvf set_terminate(pvf new_term_handler) - установка обработчика ИС. Возвращает предыдущую реакцию.

В норме, при вызове она выдает сообщение о том, что произошла ИС, которая в программе не обработана, и программа абортит.

terminate_handler вызывается, когда стек свернулся до функции main и максимум, что мы можем сделать - это выдать сообщение и перезапустить процесс, так что многого от этого обработчика ожидать нельзя.

В этих яп все зависит от среды, в которой вы программируете, если вы программируете в событийной среде у вас есть главный цикл обработки сообщений . Если вы поставите в нем ловушку, то вы будете перехватывать все сообщения , и у вас есть выбор: либо закончить программу ,либо попытаться заново войти в цикл, проигнорировав ИС.

Существенное отличие С++ от 3-х остальных яп, рассматриваемых в этой лекции:

В С++ есть специальный термин- свертка стека .

Пример:

Стек программы:

среда ссылок ( локальные переменные и формальные параметры) для main

среда ссылок для f();

некий блок внутри, которого произошло- throw();

Если в блоке не обнаружено ловушек, то процесс распространения сводится к тому, что вызов ф-ии f() считается ошибочным и в этом блоке отыскивается ловушек, а блок схлопывается - вызов деструкторов всех локальных объектов, затем выкидывание из памяти.

Пример с курсором:

{

CWaitCursor waitc;// захват курсора- песочные часы

operation();

}

Даже если операция не будет выполнена, то выход из блока всё равно будет, будет вызван деструктор, в котором мы сможем вернуть нормальный вид курсора(гарантировано сверткой текста).

В Аде нет понятия локальных объектов и нет гарантии, что локальный объект будет правильно уничтожен.

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

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

4. Обработка ИС

Где-то программист должен поставить ловушку чтобы обрабатывать ИС.

Ада:

begin

when имя => оператора списков сколько угодно

end

Минимальная обработка(Страуструп):

оператор список_ловушек;

Си++

Страуструп решил, что единицей программной конструкции, где может быть поймано исключение - это блок, так называемый try-блок:

try {

операторы// объявление переменных- оператор!

}

catch (тип1 имя 1) { ... }

catch (тип2 имя 2) { ... }// имя может отсутствовать , т.к. ИС ловится по типу.

...

catch (...) { ... } // ловит все остальные ИС, должна быть последней

Тут catch выглядит как вызов процедуры с соответствующими параметрами.

void f (T /*x*/)

{ ... }

Почему нам не требовать описывать имя? Потому что оно объявлено и не используется, и многие компиляторы на это ругаются и правильно делают .Функции обратного вызова-callback-реакции на события, параметры нам не нужны, но по соответствию типов мы описывать их должны. При обработке события, нам нужно знать только тип.

Просмотр идет сверху вниз.

Среди операторов try-блока может быть оператор throw T(); и при его выполнении производится сопоставление типа Т и типов в ловушках catch. Сначала ищется полное совпадение типа, потом идут неявные преобразования (от производного типа к базовому).

Если есть типы:

Exception => UserException

try {

....

}

catch (Exception *p) {...}

catch (UserException *p) {...}

Exeption -ok!

Если у нас будет возбуждена ИС с типом UserException, то всё равно проработает первая ловушка, а второй обработчик никогда не будет вызван. Чтобы всё работало правильно, эти обработчики надо поменять местами.

В Cи# и Java отсутствует ловушка catch(...), потому что каждое исключение порождено от типа Throwable и достаточно поставить ловушку только на него.

Рассмотрим Java, Си#:

-try блок, внутри которого может встречаться throw;

-список ловушек(catch);

- finally;

Отличие от Си++:

- отсутствует обработчик catch (...)

- добавляется в try-блок обработчик finally, который находится в конце этого блока.

Блок finally выполняется всегда, как бы блок try не завершился. В таких блоках очень хорошо размещать освобождение ресурсов (в Си++ это выполняли деструкторы).

Java:

T x = null;

try {

x = new T();

...

} finally {

if (x != null)

освободить x;

}

В языке Java, если объект забирает какие-то ресурсы( помимо динамической памяти), то обязательно их надо освобождать в блоке finally.

try- блок в Delphi(деструкторы должны вызываться явно):

try

x:=Create;

finally

x.Free;

end;

Си#:

IDisposable- интерфейс, который состоит из 1 метода:

Dispose(); явный вызов этого метода в языке С#, если мы явно хотим освободить ресурс.

Причем после использования данного интерфейса автоматический сборщик мусора не вызывается для этого объекта.

В Си# есть специальная конструкция using:

using (T x = new T()) {

...

}

И если x != null, то для не вызывается Dispose();

Но если х не поддерживает этот Dispose или надо освободить несколько объектов, то конструкция try-finally оказывается полезна.

2 замечания:

1). Синтаксис Дельфи (семантика остаётся такой же):

try

операторы

except

список ловушек

end;

он не имеет блок finally, поэтому если мы хотим его использовать, то надо писать:

try

try

операторы

except

список ловушек

end;

finally

операторы;

end;

Список ловушек имеет вид:

(on имя: тип do операторы)

несколько операторов-begin...end

тип- TException или производные от него.

2).Объявляемые(проверяемые) ИС (С++ и Java-исключения).

тип имя (операторы) throw (список_типов)

{...}

в общем случае

class X {

void f() throw (A,B)

}

Таким образом мы объявляем, что в теле f() могут возбуждаться необработанные исключения типов А и В (и ТОЛЬКО этих типов).

Для чего это сделано:

пусть внутри f() всё же появилась ИС типа С и где-то вызывается эта функция:

X *p;

p->f()

обработчиков ИС типа С в этом блоке скорее всего не будет, т.к. ожидаются ТОЛЬКО А и В, и, как следствие, возникает необработанная ИС и программа должна сразу завершаться (ошибка в коде- непредусмотренная ошибка), но мы дойдём до функции main и будет сообщение, что в main появилась такая ИС(т.к. нет трассировки).

Т.о. чем раньше мы отреагируем на необработанное исключение , тем лучше.

Способы завершения программы при необработанном исключении:

terminate()-система вызывает, когда необработанное исключение доходит до main, что вообще говоря не обязательно, т.к. после выхода из самого внешнего try-блока ловушек не будет можно вызывать terminate().

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