4887

Обработка исключений и аномальных ситуаций в программировании

Лекция

Информатика, кибернетика и программирование

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

Русский

2012-11-28

43.5 KB

3 чел.

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

Исключением называют возникновение «аномальной» ситуации во время выполнения, которое программа может обнаружить, например: деление на 0, выход за границы массива или отсутствие требуемого количества свободной памяти. Такие ситуации нарушают нормальный ход работы программы и требуют немедленной реакции. В C++ имеются встроенные средства для оповещения об исключительной ситуации и её обработки. С помощью этих средств активизируется механизм, позволяющий двум несвязанным (или независимо разработанным) фрагментам программы обмениваться информацией об исключении.

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

// Коды статуса, возвращаемые функциями

enum Status

{

  SUCCESS = 0,         // Признак успешного выполнения

  NEGATIVE_ROOT_ERROR, // Ошибка при попытке вычислить квадратный

                       // корень отрицательного аргумента

  ZERO_DIVISION_ERROR  // Ошибка при попытке деления на 0

};

// Функция вычиляет квадратный корень sqrt(val)

Status squareRoot( double val, double * result )

{

  if ( val < 0.0 )

     return NEGATIVE_ROOT_ERROR;

  * result =  std::sqrt( val );

  return SUCCESS;

}

// Функция выполняет деление a / b

Status divide( double a, double b, double * result )

{

  if ( b == 0 )

     return  NEGATIVE_ROOT_ERROR;

  * result = a / b;

  return SUCCESS;

}

// Функция вычисляет sqrt( a / b )

Status sqrtDiv( double a, double b, double * result )

{

  double d;

  Status s = divide( a, b, & d );

  if ( s != SUCCESS )

     return s;

  s = squareRoot( d, result );

  if ( s != SUCCESS )

     return s;

  return SUCCESS;

}

void main()

{

  Double result;

  Status s = sqrtDiv( 5, -1, & result );

  

  if ( s != SUCCESS )

  {

     std::cout << "Ошибка с кодом " << s << std::endl;

     return;

  }

}

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

Блок-обработчик описывается инструкцией catch(arg) (англ. поймать) с аргументом, описывающим тип перехватываемого этим блоком исключения (напоминает определение функции с одним параметром). Блоков-обработчиков может быть несколько, все они описываются последовательно сразу за блоком-инициатором проверки исключений, описываемым ключевым словом try (англ. пробовать). При возбуждении где-либо в пределах try-блока исключения, последующий список catch-блоков будет просматриваться последовательно до тех пор, пока какой-либо из них не окажется способным перехватить возбужденное исключение, в этом случае, управление передается в этот catch-блок, а аргумент catch-блока принимает значение возбужденного исключения (аналогично вызову функции с одним параметром). Если ни один из catch-блоков не способен перехватить исключение, то процесс поиска продолжится во внешнем (вызывающем) коде. Если же подходящий обработчик исключения не обнаружится вовсе, то программа будет аварийно завершена. Для перехвата всех исключений, вне зависимости от их типа, исользуется специальный универсальный блок-обработчик catch(...), который должен быть последним в списке всех блоков-обработчиков. Разумеется, в таком обработчике сам объект-исключение недоступен, поскольку неизвестен его тип. Следующий пример иллюстрирует простейшее использование обработки исключений:

  try // Попытка выполнить "опасный" участок кода

  {

 // Некоторые действия...

     throw 1; // Выбрасываем исключение

// Инструкции после throw не выполняются!

     std::cout << "Не выполняется";

  }

  catch( int e ) // перехват исключения типа int

  {

     std::cout << "Исключение типа int: " << e << std::endl;

  }

  catch( double e ) // перехват исключения типа double

  {

     std::cout << "Исключение типа double: " << e << std::endl;

  }

  catch( ... ) // перехват всех исключений

  {

     std::cout << "Исключение неизвестного типа!" << std::endl;

  }

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

// Коды ошибок (исключения)

enum ErrorCode

{

  NEGATIVE_ROOT_ERROR, // Ошибка при попытке вычислить квадратный

                       // корень отрицательного аргумента

  ZERO_DIVISION_ERROR  // Ошибка при попытке деления на 0

};

// Функция вычиляет квадратный корень sqrt(val)

double squareRoot( double val )

{

  if ( val < 0.0 )

     throw NEGATIVE_ROOT_ERROR; // Выбрасываем исключение

  return std::sqrt( val );

}

// Функция выполняет деление a / b

double divide( double a, double b )

{

  if ( b == 0 )

     throw NEGATIVE_ROOT_ERROR; // Выбрасываем исключение

  return a / b;

}

// Функция вычисляет sqrt( a / b )

double sqrtDiv( double a, double b )

{

  return squareRoot( divide( a, b ) );

}

void main()

{

  try // Попытка выполнить "опасный" участок кода

  {

     double result = sqrtDiv( 5, -1 );

  }

  catch( ErrorCode errorCode ) // перехват исключений типа ErrorCode

  {

     std::cout << "Ошибка с кодом: " << errorCode << std::endl;

  }

}


 

А также другие работы, которые могут Вас заинтересовать

81742. Лирика М.Цветаевой. Основные темы, идеи, художественное мастерство. Чтение наизусть и разбор одного стихотворения 38.65 KB
  В своем первом альбоме юная Цветаева отличалась тем-что ничего не выдумывала и никому не подражала. Но как поэт и как личность Цветаева развивалась стремительно. Зимой 1915-1916 годов Цветаева жилав Петербурге после возвращения домой она стала писать по-иному чем прежде и в этом была некоторая закономерность. Обделенная в детстве сказкой не имевшая няни Цветаева жадно наверстывала упущенное.
81743. Личность и история в романе Л. Н. Толстого « Война и мир». Кутузов и Наполеон как два нравственных полюса романа 30.19 KB
  Он утверждал что существуют история наука и история искусство и что они имеют свои четко различающиеся задачи. История-наука как полагал Т уделяет главное внимание частностям подробностям событий и ограничивается их внешним описанием в то время как история-искусство схватывает общий ход событий проникая в глубины их внутреннего смысла.
81744. Образ Петербурга в произведениях отечественной классики 19 века 32.16 KB
  Со времени образования Петром I Петербурга в 1703 году этому городу стали посвящаться многие произведения классиков русской литературы таких как Радищев но наиболее полно образ этого города был раскрыт в творчестве двух великих писателей: Александра Сергеевича Пушкина и Николая Васильевича Гоголя. Петербург в произведениях Пушкина это прежде всего торжественный парадный город олицетворение государства его силы и могущества. Восхищение городом перед которым померкла старая Москва звучит в каждой строчке вступления поэмы. Например в...
81745. Духовный облик любимых героев Л. Толстого в романе «Война и мир». Разнообразие средств психологической обрисовки героев в произведении 31.93 KB
  Выражая мнение народное писатель страстно осуждает несправедливые захватнические войны и славит героев священной освободительной войны ведя которую народ отстаивает национальную независимость своей родины. Отвергая трактовку Отечественной войны 1812 г как войны Наполеона 1 и Александра I Т. Эти утверждения о некоем фатальном законе определяющем судьбы отдельных людей и народов автор в сущности сводит на нет показывая как дубина народной войны действовавшая с простотой и целесообразностью привела к победе над наполеоновским...
81746. Образ матери и трагедия народа в поэме А. Ахматова «Реквием». Своеобразие композиции поэмы 33.67 KB
  Своеобразие композиции поэмы. Первый смысловой пласт поэмы автобиографичен. Это четвертый пласт поэмы героиня выступает здесь как новая богородица. Окончательно стихи поэмы были скомпанованы в единое произведение лишь осенью 1962 г.
81747. Тип «гордого человека» и его воплощение в произведениях отечественной литературы 32.54 KB
  Макар Чудра упрекает людей за их рабскую психологию. Суть наказания отторжение от людей. Но не только боль за несчастных темных людей превратила обычного человека в подвижника. Смысл деяний Данко установление нового порядка новых законов бытия среди людей.
81748. Автор и главный герой поэмы А. Т. Твардовского «Василий Теркин». Роль фольклорных мотивов в поэме 41.54 KB
  Твардовского Василий Теркин. Вместе с тем Твардовский следовал своему намерению побольше самого себя в поэме: лирическое начало в Теркине расширилось по сравнению со Страной Муравией стало многогранным обогатило эпические традиции которые попрежнему сильно ощутимы в поэме но проявляются иначе чем прежде. Достоверность картин жизни поэт подчеркнул и тем что назвал Василия Теркина не поэмой или эпопеей а книгой про бойца. Кроме массы бойцов плотно населяющих поэму обрисованных лаконично но остро выразительно в Василии...
81749. Нравственная эволюция героя в рассказе А. П. Чехова «Ионыч». Анализ эпизода из рассказа 33.83 KB
  Чехов рассказывает печальную историю образованного дельного врача Дмитрия Ионыча Старцева превращающегося в провинциальной глуши в угрюмого нелюдима и черствого эгоиста. Старцев пытается войти в жизнь горожан найти отклик на те мысли и чувства которыми он живет но скоро опыт научил его малопомалу что пока с обывателем играешь в карты или закусываешь с ним то это мирный благодушны и даже неглупый человек но стоит только заговорить с ним о чемнибудь несъедобном например о политике или науке как он становится в тупик или заводит...
81750. Сны героев. Их художественная функция в произведениях отечественной литературы 32.96 KB
  С одной стороны жизнь в этой деревне поражает своей сонливостью безмолвием бездеятельностью. Закономерности существования определяют приметы: брови чешутся слёзы; лоб кланяться с правой стороны чешется мужчине с левой женщине; уши зачешутся значит к дождю. С другой стороны в описании Обломовки заметен акцент на великолепии окружающей природы на хлебосольстве господ поэзии быта усадьбы красоте народных праздников ласке матери. Подчеркнуты нравственные стороны рисуемой жизни: искренность доброта и незлобие: В глазах...