Киберфак – бесплатно скачать презентации PowerPoint, лекции, рефераты, шпоры, курсовые cyberfac logo
cyberfac.ru
На главную | Регистрация | Вход
  Статьи  
Главная » Статьи » Информатика » Высокоуровневые методы информатики и программирования

Понятие исключения, генерация исключений, обработка исключений

Полезная статья? Пожалуйста, поставьте "+"
К содержанию

Обработка исключительных ситуаций (exception handling) — механизм языков программирования, предназначенный для описания реакции программы на ошибки времени выполнения и другие возможные проблемы (исключения), которые могут возникнуть при выполнении программы и приводят к невозможности (бессмысленности) дальнейшей отработки программой её базового алгоритма. В русском языке также применяется более короткая форма термина: «обработка исключений».

Общее понятие исключительной ситуации
Во время выполнения программы могут возникать ситуации, когда состояние данных, устройств ввода-вывода или компьютерной системы в целом делает дальнейшие вычисления в соответствии с базовым алгоритмом невозможным или бессмысленными. Классические примеры подобных ситуаций приведены ниже.
Нулевое значение знаменателя при выполнении операции целочисленного деления. Результата у операции быть не может, поэтому ни дальнейшие вычисления, ни попытка использования результата деления не приведут к решению задачи.
Ошибка при попытке считать данные с внешнего устройства. Если данные не удаётся ввести, любые дальнейшие запланированные операции с ними бессмысленны.
Исчерпание доступной памяти. Если в какой-то момент система оказывается не в состоянии выделить достаточный для прикладной программы объём оперативной памяти, программа не сможет работать нормально.
Появление сигнала аварийного отключения электропитания системы. Прикладную задачу, по всей видимости, решить не удастся, в лучшем случае (при наличии какого-то резерва питания) прикладная программа может озаботиться сохранением данных.
Появление на входе коммуникационного канала данных, требующих немедленного считывания. Чем бы ни занималась в этот момент программа, она должна перейти к чтению данных, чтобы не потерять поступившую информацию.

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

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

Обработчики исключений

В отсутствие собственного механизма обработки исключений для прикладных программ наиболее общей реакцией на любую исключительную ситуацию является немедленное прекращение выполнения с выдачей пользователю сообщения о характере исключения. Можно сказать, что в подобных случаях единственным и универсальным обработчиком исключений становится операционная система. Например, в операционную систему Windows встроена утилита Dr. Watson, которая занимается сбором информации об необработанном исключении и ее отправкой на специальный сервер компании Microsoft.

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

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

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

Существует два варианта подключения обработчика исключительных ситуаций к программе: структурная и неструктурная обработка исключений.

Неструктурная обработка исключений
Неструктурная обработка исключений реализуется в виде механизма регистрации функций или команд-обработчиков для каждого возможного типа исключения. Язык программирования или его системные библиотеки предоставляют программисту как минимум две стандартные процедуры: регистрации обработчика и разрегистрации обработчика. Вызов первой из них «привязывает» обработчик к определённому исключению, вызов второй — отменяет эту «привязку». Если исключение происходит, выполнение основного кода программы немедленно прерывается и начинается выполнение обработчика. По завершении обработчика управление передаётся либо в некоторую наперёд заданную точку программы, либо обратно в точку возникновения исключения (в зависимости от заданного способа обработки — с возвратом или без). Независимо от того, какая часть программы в данный момент выполняется, на определённое исключение всегда реагирует последний зарегистрированный для него обработчик. В некоторых языках зарегистрированный обработчик сохраняет силу только в пределах текущего блока кода (процедуры, функции), тогда процедура разрегистрации не требуется. Ниже показан условный фрагмент кода программы с неструктурной обработкой исключений:
УстановитьОбработчик(ОшибкаБД, ПерейтиНа ОшБД)
// На исключение "ОшибкаБД" установлен обработчик - команда "ПерейтиНа ОшБД"
... // Здесь находятся операторы работы с БД
ПерейтиНа СнятьОшБД // Команда безусловного перехода - обход обработчика исключений
ОшБД:  // метка - сюда произойдёт переход в случае ошибки БД по установленному обработчику
... // Обработчик исключения БД 
СнятьОшБД: 
// метка - сюда произойдёт переход, если контролируемый код выполнится без ошибки БД.
СнятьОбработчик(ОшибкаБД)
// Обработчик снят


Неструктурная обработка — практически единственный вариант для обработки асинхронных исключений, но для синхронных исключений она неудобна: приходится часто вызывать команды установки/снятия обработчиков, всегда остаётся опасность нарушить логику работы программы, пропустив регистрацию или разрегистрацию обработчика.

Структурная обработка исключений
Структурная обработка исключений требует обязательной поддержки со стороны языка программирования — наличия специальных синтаксических конструкций. Такая конструкция содержит блок контролируемого кода и обработчик (обработчики) исключений. Наиболее общий вид такой конструкции (условный):
НачалоБлока
... // Контролируемый код
...
если (условие) то СоздатьИсключение Исключение2
...
Обработчик Исключение1
... // Код обработчика для Исключения1
Обработчик Исключение2
... // Код обработчика для Исключения2
ОбработчикНеобработанных
... // Код обработки ранее не обработанных исключений
КонецБлока


Здесь «НачалоБлока» и «КонецБлока» — ключевые слова, которые ограничивают блок контролируемого кода, а «Обработчик» — начало блока обработки соответствующего исключения. Если внутри блока, от начала до первого обработчика, произойдёт исключение, то произойдёт переход на обработчик, написанный для него, после чего весь блок завершится и исполнение будет продолжено со следующей за ним команды. «ОбработчикНеобработанных» — это обработчик исключений, которые не соответствуют ни одному из описанных выше в данном блоке. Обработчики исключений в реальности могут описываться по-разному (один обработчик на все исключения, по одному обработчику на каждый тип исключение), но принципиально они работают одинаково: при возникновении исключения находится первый соответствующий ему обработчик в данном блоке, его код выполняется, после чего выполнение блока завершается. Исключения могут возникать как в результате программных ошибок, так и путём явной их генерации с помощью соответствующей команды (в примере — команда «СоздатьИсключение»). С точки зрения обработчиков такие искусственно созданные исключения ничем не отличаются от любых других.

Блоки обработки исключений могут многократно входить друг в друга, как явно (текстуально), так и неявно (например, в блоке вызывается процедура, которая сама имеет блок обработки исключений). Если ни один из обработчиков в текущем блоке не может обработать исключение, то выполнение данного блока немедленно завершается, и управление передаётся на ближайший подходящий обработчик более высокого уровня иерархии. Это продолжается до тех пор, пока обработчик не найдётся и не обработает исключение или пока не выйдет из обработчиков заданных программистом и не будет переданно системному обработчику, поумолчанию аварийно закроющий программу.

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

Блоки с гарантированным завершением

Помимо блоков контролируемого кода для обработки исключений, языки программирования могут поддерживать блоки с гарантированным завершением. Их использование оказывается удобным тогда, когда в некотором блоке кода, независимо от того, произошли ли какие-то ошибки, необходимо перед его завершением выполнить определённые действия. Простейший пример: если в процедуре динамически создаётся какой-то локальный объект в памяти, то перед выходом из этой процедуры объект должен быть уничтожен (чтобы избежать утечки памяти), независимо от того, произошли после его создания ошибки или нет. Такая возможность реализуется блоками кода вида:
НачалоБлока
... // Основной код
Завершение
... // Код завершения
КонецБлока


Заключённые между ключевыми словами «НачалоБлока» и «Завершение» операторы (основной код) выполняются последовательно. Если при выполнении их не возникает исключений, то затем выполняются операторы между ключевыми словами «Завершение» и «КонецБлока» (код завершения). Если же при выполнении основного кода возникает исключение (любое), то сразу же выполняется код завершения, после чего весь блок завершается, а возникшее исключение продолжает существовать и распространяться до тех пор, пока его не перехватит какой-либо блок обработки исключений более высокого уровня.

Принципиальное отличие блока с гарантированным завершением от обработки — то, что он не обрабатывает исключение, а лишь гарантирует выполнение определённого набора операций перед тем, как включится механизм обработки. Стоит заметить, что блок с гарантированным завершением легко реализуется с помощью команд «возбудить исключение» и «структурный обработчик исключения».

Поддержка в различных языках
Большинство современных языков программирования, такие как Ada, C++, D, Delphi, Objective-C, Java, JavaScript, Eiffel, OCaml, Ruby, Python, Common Lisp, SML, PHP, все языки платформы .NET и др. имеют встроенную поддержку структурной обработки исключений. В этих языках при возникновении исключения, поддерживаемого языком, происходит раскрутка стека вызовов до первого обработчика исключений подходящего типа, и управление передаётся обработчику.

За исключением незначительных различий в синтаксисе, существует лишь пара вариантов обработки исключений. В наиболее распространённом из них исключительная ситуация генерируется специальным оператором (throw или raise), а само исключение, с точки зрения программы, представляет собой некоторый объект данных. То есть, генерация исключения состоит из двух этапов: создания объекта-исключения и возбуждения исключительной ситуации с этим объектом в качестве параметра. При этом конструирование такого объекта само по себе выброса исключения не вызывает. В одних языках объектом-исключением может быть объект любого типа данных (в том числе строкой, числом, указателем и так далее), в других — только предопределённого типа-исключения (чаще всего он имеет имя Exception) и, возможно, его производных типов (типов-потомков, если язык поддерживает объектные возможности).

Область действия обработчиков начинается специальным ключевым словом try или просто языковым маркером начала блока (например, begin) и заканчивается перед описанием обработчиков (catch, except, resque). Обработчиков может быть несколько, один за одним, и каждый может указывать тип исключения, который он обрабатывает. Если язык поддерживает наследование и типы-исключения могут наследоваться друг от друга, то обработкой исключения занимается первый обработчик, совместимый с исключением по типу.

Некоторые языки также допускают специальный блок (else), который выполняется, если ни одного исключения не было сгенерировано в соответствующей области действия. Чаще встречается возможность гарантированного завершения блока кода (finally, ensure). Заметным исключением является Си++, где такой конструкции нет. Вместо неё используется автоматический вызов деструкторов объектов. Вместе с тем существуют нестандартные расширения Си++, поддерживающие и функциональность finally (например в MFC).

В целом, обработка исключений может выглядеть следующим образом (в некотором абстрактном языке):
try {
line = console.readLine();
if (line.length() == 0)
throw new EmptyLineException("Строка, считанная с консоли, пустая!");

console.printLine("Привет, %s!" % line);
}
catch (EmptyLineException exception) {
console.printLine("Привет!");
}
catch (Exception exception) {
console.printLine("Ошибка: " + exception.message());
}
else {
console.printLine("Программа выполнилась без исключительных ситуаций");
}
finally {
console.printLine("Программа завершается");
}


В некоторых языках может быть лишь один обработчик, который разбирается с различными типами исключений самостоятельно.


Категория: Высокоуровневые методы информатики и программирования | Добавил: Ni-Cd (01 Декабря 2011)
Просмотров: 2480 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
  Полезные материалы  

В нашем каталоге файлов можно найти много полезной информации. Также советуем заглянуть в каталог статей: в нем есть полезные статьи по темам: Экономика предприятия, Общая экономика, Финансы и Кредит, также Словарь терминов по экономике, Маркетинг, Бухучет и Мировая экономика
Также есть полезная страница Факультеты МИФИ, которая расскажет о том, какие есть в МИФИ факультеты.
Меню
 

Навигация
Высокоуровневые методы информатики и программирования [28]
Информатика и программирование [34]
Информационные системы в экономике [36]
Языки программирования и методы трансляции [15]
Алгоритмизация и программирование [61]
 

Поиск
 

Онлайн
Онлайн всего: 1
Гостей: 1
Пользователей: 0
 

Статистика


Рейтинг@Mail.ru

 


2007 - 2024 © Ni-Cd. All Rights Reserved