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;

  }

}


 

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

24658. Аналіз витрат на виробництво за елементами та статтями витрат 26.5 KB
  Аналіз витрат на виробництво за елементами та статтями витрат. Найбільш корисним для вивчення змін у структурі витрат на виробництво є аналіз собівартості за елементами витрат. Елементні витрати це однорідні за складом витрати підприємства. До них належать матеріальні витрати оплата праці відрахування на соціальні потреби амортизаційні відрахування інші грошові витрати.
24659. Аналіз витрат на одну гривню товарної продукції 25 KB
  Аналіз витрат на одну гривню товарної продукції.товарної продукції є основним показником який харзує рівень і динаміку витрат на підво які розробляють різновидну продукцію. товварної продукції є загальним показником рівня витрат він може бути розрахованим для будь якого підващо дуже важливо до порівняння аналізу між підвами їх оцінки конкурентно спроможності. товарної продукції харзує успішність роботи підвапо впровадженя нової технікипідвищення продукції праці раціонально викорастаних ресурсів.
24660. Методика аналізу фінансових результатів підприємства 32 KB
  Кінцевим позитивним результатом господарської діяльності підприємства є прибуток. Прибуток це грошовий дохід утворений в результаті виробничогосподарської діяльності. Прибуток виконує такі основні функції: оцінки підсумків діяльності підприємства; розподілу розподілу доходу між підприємством і державою підприємством і його робітниками між сферою виробництва і невиробничою сферою; джерела утворення фондів економічного стимулювання і соціальних фондів. Джерелами аналітичної інформації є плани економічного та соціального...
24661. Аналіз валового прибутку від реалізації продукції 29 KB
  У процесі аналізу доходів визначають такі показники: 1 рівень доходів підва: доходи в сумі на 100 на товаро оборот. 2 розмір зміни рівня доходів:фактичний рівень доходівплан рівня доходів. 3 відхилення доходів суми:фактич.товарооборотвідхилення у 100 4 рентабельність: R=ЧП ВК 5 рівень рентабельності продажу Rпр=ЧП ЧР У процесі аналізу доходів визначаются такі показники: 1 рівень доходів підва= доходи в сумі 100 товарооборот 2 розмір зміни рівня підва=фактичній плановий 3 відхилення доходів в сумі= фактичний товарооборотна відхил.
24662. Аналіз показників рентабельності 27.5 KB
  Аналіз показників рентабельності. Аналіз рентабельності підприємства дозволяє визначити ефективність вкладення коштів у підприємство та раціональність їхнього використання. Аналіз рентабельності підприємства здійснюється шляхом розрахунку таких показників коефіцієнтів: коефіцієнт рентабельності активів коефіцієнт рентабельності власного капіталу коефіцієнт рентабельності діяльності та коефіцієнт рентабельності продукції. Коефіцієнт рентабельності активів Ра розраховується як відношення чистого прибутку підприємства до середньорічної...
24663. Організація і методика аналізу фінансового стану підприємства в ринкових умовах 29 KB
  Відносні показники фінансового стану розподіляються на коефіцієнти розподілення і координації. Коефіцієнт розподілення відображають яку частину той чи інший абсолютний показник становить від підсумкового показника складовою частиною якого є цей показник.аналіз рентабельності Аналіз рентабельності підприємства здійснюється шляхом розрахунку таких показників коефіцієнтів: коефіцієнт рентабельності активів коефіцієнт рентабельності власного капіталу коефіцієнт рентабельності діяльності та коефіцієнт рентабельності продукції.
24664. Аналіз динаміки, складу та структури майна підприємства 25 KB
  В процесі аналізу активу і пасиву балансу визначають показники структури динаміки балансу структурної динаміки балансу. Для загальної оцінки динаміки фінансового стану підприємства необхідно виконати групування статей балансу по окремих групах за відзнакою ліквідності за ознакою активу та пасиву і зобовязання. Використовуючи горизонтальний і вертикальний аналіз здійснення аналізу активу та пасиву балансу за групами.
24665. Аналіз структури джерел коштів підприємства 30.5 KB
  Аналіз структури джерел коштів підприємства. Як ми уже говорили раніше внутрішній аналіз структури джерел коштів підприємства пов'язаний з оцінкою альтернативних варіантів фінансування діяльності підприємства.До числа основних показників які характеризують структуру джерел коштів належить коефіцієнт фінансової незалежності автономії КАВТ як відношення загальної суми джерел власних коштів до підсумку балансу. Цей коефіцієнт є важливим і для інвесторів і для кредиторів тому що характеризує частку коштів вкладених власником у загальну...
24666. Аналіз дебіторсько-кредиторської заборгованості 37 KB
  Аналіз дебіторськокредиторської заборгованості. Значення аналізу дебіторської заборгованості особливо зростає в період інфляції коли іммобілізація власних оборотних активів стає дуже невигідною.У найзагальнішому вигляді зміни в обсязі дебіторської та кредиторської заборгованості за звітний період можуть бути охарактеризовані даними горизонтального та вертикального аналізу балансу. Особливу увагу в процесі аналізу дебіторської заборгованості приділяють статті Дебіторська заборгованість за товари роботи послуги яка має найбільшу питому вагу...