Чтение онлайн

ЖАНРЫ

C# для профессионалов. Том II

Ватсон Карли

Шрифт:

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

// OverflowEX.java

public class OverfTowEX {

 publiс static void main(String args []) {

byte x = 0;

for (int i = 0; i < 130; i++) {

x++;

System.out.println(x);

}

 }

}

Как

известно,
byte
в Java является 8-битовым типом данных со знаком. Это означает, что диапазон значений
byte
лежит от -128 до 128. Результатом добавления единицы к любой границе заданного диапазона целого типа будет другая граница диапазона целого типа. Поэтому в этом примере добавление 1 к 127 создаст -128. И если откомпилировать и выполнить эту программу, то последние пять чисел выведенные на консоли будут следующими:

126

127

– 128

– 127

– 126

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

□ Программный подход. Чтобы бороться с этим типом молчаливых ошибок, C# вводит концепцию проверяемых и непроверяемых инструкций. Ключевое слово

checked
используется для управления контекстом проверки переполнения в случае операций и преобразований арифметики целого типа, таких, как представленные выше. Оно может использоваться как оператор или как инструкция. Инструкции
checked/unchecked
следуют приведенному ниже синтаксису (
i
). Они предназначены для помещения в скобки ряда инструкций, которые могут создавать переполнение. Синтаксис операции
checked/unchecked
показан в пункте (
ii
). Операция checked проверяет переполнение одиночных выражений:

(i) checked {block_of_code}

unchecked { block_of_code}

(ii) checked (expression)

unchecked (expression)

block_of_code
содержит код, в котором инструкция
checked/unchecked
наблюдает за переполнением, a
expression
представляет выражение, в котором
checked/unchecked
наблюдает за переполнением в конечном значении. Показанный далее пример иллюстрирует использование
checked/unchecked
:

// OverflowEX.cs

public class OverflowEX {

 public static void Main(String args) {

sbyte x = 0; // помните, что необходимо изменить byte на sbyte

for (int i = 0; i < 130; i++) {

checked {

// можно также использовать checked(x++)

x++;

Console.WriteLine(x);

}

}

 }

}

□ Подход

с ключом компилятора. Для контроля переполнения во всем приложении может использоваться настройка компилятора
/checked+
. Чтобы проиллюстрировать это, удалим инструкцию
checked
из приведенного выше примера и попытаемся компилировать его, используя флаг
/checked+
. С его помощью можно включать и выключать проверку арифметического переполнения, изменяя состояние конфигурационных свойств на странице свойств проекта. Задание значения как true будет включать проверку переполнения.

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

unchecked
. По сути она предоставляет функциональность для произвольного исключения проверки выражений или блоков инструкций в то время, когда включена проверка во всем приложении. В примере ниже предыдущая инструкция заменяется инструкцией
unchecked
. Компиляция и выполнение этого кода будет создавать вывод, аналогичный выводу
OverflowEX.java
.

// OverflowEX.сs.

public class OverflowEX {

 public static void Main(String[] args) {

sbyte X = 0;

for (int i = 0; i < 130; i++) {

unchecked { // можно также использовать unchecked(x++)

x++;

Console.WriteLine(x);

}

}

 }

}

Входные и выходные данные

Возможность собрать входные данные из командной строки и вывести данные в командной строке является интегральной частью функциональности ввода/вывода в Java. Обычно в Java необходимо создать экземпляр объекта

java.io.BufferedReader
, используя поле
System.in
, чтобы извлечь ввод из командной строки. Ниже представлен простой класс Java —
JavaEcho
, который получает ввод с консоли и выводит его обратно, чтобы проиллюстрировать использование пакета
Java.io
для сбора и форматирования ввода и вывода:

// JavaEcho.java

import java.io.*;

public class JavaEcho {

 public static void main(String[] args) throws IOException {

BufferedReader stdin = new BufferedReader(new InputSreamReader(System.in));

String userInput = stdin.readLine;

System.out.println("You said: " + userInput);

 }

}

Класс

System.Console
предоставляет методы в C#, которые дают аналогичную функциональность для чтения и записи из и в командную строку, Нет необходимости в каких-либо дополнительных объектах, класс
Console
предоставляет методы, которые могут читать целые строки, читать символ за символом и даже показывать описанный выше поток, из которого выполняется чтение. Важно отметить, что эту функциональность дает
System.Console
без создания экземпляра объекта
Console
. Фактически можно обнаружить, что невозможно создать экземпляр объекта
Console
. Члены класса
Console
кратко описаны в таблицах ниже:

Поделиться с друзьями: