Опубликован: 15.09.2010 | Доступ: свободный | Студентов: 4808 / 630 | Оценка: 3.97 / 3.80 | Длительность: 14:45:00
Лекция 4:

Простейший ввод-вывод. Управляющие операторы

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >

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

В языке C# есть операторы, позволяющие обнаруживать и обрабатывать ошибки (исключительные ситуации), возникающие в процессе выполнения программы.

Исключительная ситуация, или исключение, — это возникновение аварийного события, которое может порождаться некорректным использованием аппаратуры или неправильной работой программы, например, делением на ноль или переполнением. Обычно эти события приводят к завершению программы с системным сообщением об ошибке. С# дает программисту возможность восстановить работоспособность программы и продолжить ее выполнение.

Исключения С# не поддерживают обработку асинхронных событий, таких как ошибки оборудования или прерывания, например, нажатие клавиш Ctrl + C. Механизм исключений предназначен только для событий, которые могут произойти в результате работы самой программы и указываются явным образом. Исключения возникают тогда, когда некоторая часть программы не смогла сделать то, что от нее требовалось. При этом другая часть программы может попытаться сделать что-нибудь иное.

Исключения позволяют логически разделить вычислительный процесс на две частиобнаружение аварийной ситуации и ее обработка. Это важно не только для лучшей структуризации программы. Главное то, что функция, обнаружившая ошибку, может не знать, что предпринимать для ее исправления, а использующий эту функцию код может знать, что делать, но не уметь определить место возникновения. Это особенно актуально при использовании библиотечных функций и программ, состоящих из многих модулей.

Исключения генерирует либо среда выполнения, либо программист с помощью оператора throw. В таблице 4.2 приведены наиболее часто используемые стандартные исключения, генерируемые средой. Они определены в пространстве имен System. Все они являются потомками класса Exception, а точнее, потомками его потомка SystemException.

Таблица 4.2. Часто используемые стандартные исключения
Имя Описание
DivideByZeroException Попытка деления на ноль
FormatException Попытка передать в метод аргумент неверного формата
IndexOutOfRangeException Индекс массива выходит за границы диапазона
InvalidCastException Ошибка преобразования типа
OutOfMemoryException Недостаточно памяти для создания нового объекта
OverflowException Переполнение при выполнении арифметических операций
StackOverFlowException Переполнение стека

Исключения обнаруживаются и обрабатываются в операторе try.

Оператор try

Оператор try содержит три части:

  • контролируемый блок — составной оператор, предваряемый ключевым словом try. В контролируемый блок включаются потенциально опасные операторы программы. Все функции, прямо или косвенно вызываемые из блока, также считаются ему принадлежащими;
  • один или несколько обработчиков исключений — блоков catch, в которых описывается, как обрабатываются ошибки различных типов;
  • блок завершения finally выполняется независимо от того, возникла ошибка в контролируемом блоке или нет.

Синтаксис оператора try:

try блок [ блоки catch ] [ блок finally ]

Отсутствовать могут либо блоки catch, либо блок finally, но не оба одновременно.

Рассмотрим, каким образом реализуется обработка исключительных ситуаций.

  1. Обработка исключения начинается с появления ошибки. Функция или операция, в которой возникла ошибка, генерирует исключение.
  2. Выполнение текущего блока прекращается, отыскивается соответствующий обработчик исключения, и ему передается управление.
  3. Выполняется блок finally, если он присутствует.
  4. Если обработчик не найден, вызывается стандартный обработчик исключения. Обычно он выводит на экран окно с информацией об исключении и завершает текущий процесс.

Обработчики исключений должны располагаться непосредственно за блоком try. Они начинаются с ключевого слова catch, за которым в скобках следует тип обрабатываемого исключения. Можно записать один или несколько обработчиков в соответствии с типами обрабатываемых исключений. Блоки catch просматриваются в том порядке, в котором они записаны, пока не будет найден соответствующий типу выброшенного исключения.

Существуют три формы записи обработчиков:

catch( тип имя ) { ... /* тело обработчика */ }
catch( тип )     { ... /* тело обработчика */ }
catch            { ... /* тело обработчика */ }

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

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

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

Пример:

try {
   ...  // Контролируемый блок 
}
catch ( OverflowException e ) { 
    ...    // Обработка исключений класса OverflowException (переполнение)
}
catch ( DivideByZeroException ) { 
    ... // Обработка исключений класса DivideByZeroException (деление на 0)
}
catch { 
    ...    // Обработка всех остальных исключений 
}

Если исключение в контролируемом блоке не возникло, все обработчики пропускаются.

В любом случае, произошло исключение или нет, управление передается в блок завершения finally (если он существует), а затем — первому оператору, находящемуся непосредственно за оператором try.

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

Оператор throw

До сих пор мы рассматривали исключения, которые генерирует среда выполнения C#, но это может сделать и сам программист. Для генерации исключения используется оператор throw с параметром, определяющим вид исключения. Параметр должен быть объектом, порожденным от стандартного класса System.Exception. Этот объект используется для передачи информации об исключении его обработчику.

Синтаксис оператора throw:

throw [ выражение ];

Форма без параметра применяется только внутри блока catch для повторной генерации исключения. Тип выражения, стоящего после throw, определяет тип исключения, например:

throw new DivideByZeroException();

Здесь после слова throw записано выражение, создающее объект стандартного класса "ошибка при делении на 0" с помощью операции new.

При генерации исключения выполнение текущего блока прекращается и происходит поиск соответствующего обработчика с передачей ему управления. Обработчик считается найденным, если тип объекта, указанного после throw, либо тот же, что задан в параметре catch, либо является производным от него.

Вопросы и задания для самостоятельной работы студента

  1. Какой класс используется для консольного ввода-вывода? Приведите примеры ввода и вывода переменных различных типов.
  2. Какие средства языка используются для преобразования величин из символьной формы представления во внутреннюю?
  3. В каких случаях оператор switch предпочтительнее оператора if?
  4. Какой вид цикла лучше использовать при вводе данных?
  5. Поясните смысл использования базовых конструкций структурного программирования.
  6. Изучите по справочной системе состав пространства имен System.
  7. Изучите свойства и методы стандартного класса Console по справочной системе.

Лабораторные работы

Лабораторная работа 1. Линейные программы

Напишите программу для расчета по двум формулам. Предварительно подготовьте тестовые примеры с помощью калькулятора.

z_1=2sin^2(3\pi-2a)cos^2(5\pi+2a)z_2=\frac 1 4 -\frac 1 4 sin(\frac 5 2 \pi-8a)

Лабораторная работа 2. Разветвляющиеся вычислительные процессы

Задание 1. Вычисление значения функции

Написать программу, которая по введенному значению аргумента вычисляет значение функции, заданной в виде графика:


Задание 2. Попадание точки в заштрихованную область

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


Лабораторная работа 3. Организация циклов

Теоретический материал: глава 4, разделы "Операторы цикла", "Базовые конструкции структурного программирования".

Задание 1. Таблица значений функции

Вычислить и вывести на экран в виде таблицы значения функции, заданной графически (см. задание 1 лабораторной работы 2), на интервале от xнач до xкон с шагом d x. Интервал и шаг задать таким образом, чтобы проверить все ветви программы. Таблицу снабдить заголовком и шапкой.

Задание 2. Серия выстрелов по мишени

Для десяти выстрелов, координаты которых задаются с клавиатуры, вывести текстовые сообщения о попадании в мишень из задания 2 лабораторной работы 2.

Задание 3. Ряды Тейлора

Вычислить и вывести на экран в виде таблицы значения функции, заданной с помощью ряда Тейлора, на интервале от xнач до xкон с шагом d x с точностью \varepsilon. Таблицу снабдить заголовком и шапкой. Каждая строка таблицы должна содержать значение аргумента, значение функции и количество просуммированных членов ряда.

ln\frac {x+1}{x-1}=2\sum^{\infty}_{n=0}\frac 1 {(2n+1)x^{2n+1}}=2(\frac 1 {x} +\frac 1 {3x^3}+\frac 1 {5x^5}+\cdots )\left| x \right| >1
< Лекция 3 || Лекция 4: 1234 || Лекция 5 >
Stefan Berzan
Stefan Berzan
Молдова, Кишинев
Дмитрий Казимиров
Дмитрий Казимиров
Россия, Омск