Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky.rtf
Скачиваний:
27
Добавлен:
22.03.2016
Размер:
11.9 Mб
Скачать

16.5. Исключения в арифметических выражениях

При вычислениях значений арифметических выражений возникают особые

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

по разному. Рассмотрим следующий фрагмент кода.

int x=111111, y=111111, z=0;

double a=x/0.0; //результат: "бесконечность"

double b=x/0; //ошибка компиляции

double c=x/z; //исключение DivideByZeroException

double d=x*y; //результат: -539247567

Как отмечено в комментариях, все приведённые выражения приводят к

возникновению особых ситуаций. В первых трёх случаях программист по

сообщениям компилятора или по результатам выполнения программы может явно

распознать ситуацию. Значением переменной a=x/0.0 является бесконечно большая

величина. В случае b=x/0 компилятор выдаёт сообщение о попытке целочисленного

деления на нулевую константу. Выражение c=x/z не смущает компилятор, н

о

приводит к генерации исключения System.DivideByZeroException на этапе

выполнения программы. В случае вычисления x*y происходит целочисленное

переполнение, но никаких признаков особой ситуации нет. Правда, переменной d

присваивается

некоторое

отрицательное

значение

после

умножения

двух

положительных величин. В нашем простом примере этот результат может служить

сигналом об особой ситуации. Однако в сложных арифметических выражениях

целочисленное переполнение может остаться незамеченным, но приведёт к

неверному результату.

Для отслеживания таких ошибок в арифметических выражениях следует

использовать служебное слово checked "служебное слово: checked" . Это слово

играет две роли, оно обозначает операцию и вводит специальный блок "наблюдения"

за переполнениями при вычислениях выражений:

checked (выражение)

checked {операторы}

В первом случае отслеживаются возникновения переполнений в заключённом

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

операторах блока. В обоих случаях при возникновении переполнения генерируется

исключение System.OverflowException.

Наш пример можно дополнить оператором

double е= checked(x*y);

В этом случае переполнение при вычислении выражения x*y не будет

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

исключения может быть организована обычным образом с помощью блока try/catch.

Рассмотренный пример может привести к другим результатам, если будут

изменены опции компилятора или настройки исполняющей системы. Чтобы при

выполнении программы никогда не посылались исключения переполнения в

арифметических операциях, можно использовать служебное слово unchecked

"служебное слово: unchecked"

.

16.6. Генерация исключений

Об обработке исключений, посылаемых методами библиотечных классов, мы

уже говорили и неоднократно пользовались. Чтобы глубже разобраться в механизме

генерации исключений "исключения:генерация исключений" и научиться создавать

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

выполнении программы, нужно ясно понять и усвоить, что исключения – это

объекты некоторых специальных классов. Все системные классы исключений

являются производными от класса System.Exception. Этот класс имеет несколько

замечательных свойств, два из которых (Message и Source) мы уже применяли. При

создании объектов классов исключений наиболее важными являются Message и

InnerException. Оба эти свойства в обязательном порядке используются всеми

исключениями. Оба свойства предназначены только для чтения.

Message

"свойство: Message"

– это свойство типа String, значение которого

представляет собой текст сообщения о причине возникновения исключения.

InnerException "свойство: InnerException" – имеет тип Exception и представляет

собой ненулевую ссылку на то исключение, которое является причиной

возникновения данного исключения.

Значения этих свойств можно задать с помощью параметров конструктора при

создании объекта класса System.Exception. Нам могут быть полезны следующие

конструкторы:

Exception()

"конструктор исключений: Exception()"

– инициализирует

умалчиваемыми значениями данных новый экземпляр класса Exception.

Exception(String) "конструктор исключений: Exception(String)" – инициализирует

новое исключение (новый объект). Параметр задаёт значение свойства

Message.

Exception(String,

Exception)

"конструктор

исключений:

Exception(String,

Exception)" – параметр типа String определяет значение свойства Message,

а

второй параметр представляет собой ссылку на внутреннее исключение,

которое явилось причиной данного исключения.

Зная конструкторы, создать объект-исключение, применяя операцию new мы

уже сможем. Осталось выяснить каким образом послать исключение и как

определить условие, при выполнении которого это нужно делать. Определение

условия не относится к механизму обработки исключений, а зависит от той

конкретной задачи, для решения которой создаётся программа.

Для генерации (для посылки) исключения из выбранной точки кода программы

используется оператор, имеющий одну из следующих двух форм:

throw выражение;

throw;

Оператор throw

"оператор: throw"

без выражения; можно использовать

только в catch-блоке для ретрансляции исключения в catch-блок следующего

уровня.

Значением выражения, использованного в операторе throw, должна быть

ссылка на объект класса исключений. Именно этот объект посылается в качестве

исключения. Если значение выражения равно null, то вместо него посылается

исключение

System.NullReferenceException

" исключения :

System.NullReferenceException" .

Одной из наиболее важных задач, решаемых с применением исключений,

является проверка корректности данных, получаемых программой или отдельным

методом. Мы уже показали на нескольких примерах как использовать исключения

автоматически формируемые при чтении данных от клавиатуры.

В следующей программе продемонстрируем как программировать генерацию

исключений. Пусть требуется вычислить значение электрической мощности,

рассеиваемой на сопротивлении в 100 Ом при включении его в сеть с напряжением

110 или 127 или 220 вольт. Пользователь может ввести только одно из указанных

значений напряжения. Ошибаться при вводе можно только два раза. При третье

й

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

Ошибки ввода в данном случае могут быть двух видов – лексические и

семантические. Лексическая ошибка – это неверная запись вещественного числа при

его наборе на клавиатуре. Семантическая ошибка – отличие введённого числа от

трёх допустимых условием задачи значений (110, 127, 220). Для преобразования

введённой с клавиатуры последовательности символов в числовое значение

применим метод TryParse(). Тогда послать исключение при лексической ошибке

можно с помощью следующих операторов:

string input = Console.ReadLine();

Соседние файлы в папке CSBasicCourse2ndedPodbelsky