- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
Ключевое слово checked
Вы, несомненно, прекрасно знаете, что любой числовой тип данных имеет свои строго заданные верхний и нижний пределы (значения которых можно выяснить программными средствами с помощью свойств MaxValue и MinValue). При выполнении арифметических операций с конкретным типом вполне возможно случайное переполнение блока хранения данного типа (попытка присвоения типу значения, которое оказывается больше максимально допустимого) или потеря значимости (попытка присвоения значения, которое оказывается меньше минимально допустимого). Чтобы "идти в ногу" с CLR, обе эти возможности будут обозначаться, как "переполнение". (И переполнение, и потеря значимости приводят к созданию типа System.OverflowException. Типа System.UnderflowException в библиотеках базовых классов нет.)
Для примера предположим, что мы создали два экземпляра типа System.Byte (тип byte в C#), присвоив им значения, не превышающие максимального (255). При сложении значений этих типов (с условием преобразования результата в тип byte) хотелось бы предполагать, что результат будет точной суммой соответствующих членов.
namespace CheckedUnchecked {
class Program {
static void Main(string[] args) {
// Переполнение для System.Byte.
Console.WriteLine("Макс, значение для byte равно {0}", byte.MaxValue);
Console.WriteLine("Мин. значение для byte равно {0}", byte.MinValue);
byte b1 = 100;
byte b2 = 250;
byte sum = (byte)(b1 + b2);
// Значением sum должно быть 350, но.…
Console.WriteLine("sum = {0}", sum);
Console.ReadLine();
}
}
}
Вывод этого приложения покажет, что sum содержит значение 94 (а не ожидаемое 350). Причина очень проста. Поскольку System.Byte может содержать только значения, находящиеся между 0 и 255 (что в итоге составляет 256 значений), sum будет содержать значение переполнения (350 – 256 = 94). Как видите, в отсутствие специальной коррекции переполнение происходит без генерирования исключений. Иногда скрытое переполнение не создает никаких проблем. В других случаях соответствующая потеря данных может быть совершенно неприемлемой.
Для обработки переполнений или потери значимости в приложении имеются две возможности. Первой возможностью является использование программистского опыта и квалификации с тем, чтобы обработать все условия переполнения вручную. Предполагая, что вы можете найти все условия переполнения в программе, можно было бы решить проблему, связанную с переполнением в предыдущем программном коде, как показано ниже.
// Использование int для sum, чтобы не допустить переполнения.
byte b1 = 100;
byte b2 = 250;
int sum = b1 + b2;
Конечно, проблемой этого подхода является то, что вы – человек, а значит, при всех ваших усилиях, могут остаться ошибки, ускользнувшие от вашего взгляда. Поэтому в C# предлагается ключевое слово checked. При помещении оператора (или блока операторов) в рамки контекста ключевого слова checked компилятор C# генерирует специальные CIL-инструкщии, с помощью которых проверяются условия переполнения, возможные при выполнении сложения, умножение, вычитания или деления числовых типов данных. Если происходит переполнение, среда выполнения генерирует тип System.OverflowException. Рассмотрите следующую модификацию программы.
class Program {
static void Main(string[] args) {
// Переполнение для System.Byte.
Console.WriteLine("Макс. значение для byte равно {0}.", byte.MaxValue);
byte b1 = 100;
byte b2 = 250;
try {
byte sum = checked((byte)(b1 + b2));
Console.WriteLine("sum = {0}", sum);
} catch (OverflowException e) { Console.WriteLine(e.Message); }
}
}
Здесь оператор сложения b1 и b2 помещается в контекст ключевого слова checked. Если вы хотите, чтобы проверка переполнения происходила для блока программного кода, можно взаимодействовать с ключевым словом checked так, как показано ниже.
try {
checked {
byte sum = (byte)(b1 + b2);
Console.WritaLine(sum = {0}", sum);
}
} catch (OverflowException e) {
Console.WriteLine(e.Message);
}
В любом случае соответствующий программный код будет проверяться на возможное переполнение автоматически, и если переполнение будет обнаружено, то будет сгенерирована соответствующее переполнению исключение.
Проверки переполнения для всего проектаЕсли вы создаете приложение, которое не должно позволять скрытое переполнение ни при каких условиях, будет слишком утомительно указывать ключевое слово checked для каждой строки программного кода. В качестве альтернативы компилятор C# предлагает использовать флаг /checked. Когда этот флаг активизирован, все арифметические операции будут проверяться на переполнение без указания ключевого слова checked. Если обнаружится переполнение, вы получите OverflowException среды выполнения.
Чтобы активизировать этот флаг в Visual Studio 2005, откройте страницу свойств проекта и щелкните на кнопке Advanced на вкладке Build. В появившемся диалоговом окне отметьте флажок Check for arithmetic overflow/underflow (Проверять условия переполнения/потери значимости для арифметических операций), рис. 9.3.
Рис. 9.З. Активизация проверки переполнения в Visual Studio 2005
Ясно, что эта установка оказывается очень полезной при отладке. После того как все связанные с переполнением исключения будут из программного кода удалены, флаг /checked для последующей компоновки можно отключить.
Ключевое слово unchecked
В предположении, что вы активизировали проверку переполнения для всего проекта, как разрешить игнорирование переполнений для тех блоков программного кода, где "молчаливая реакция" на переполнение вполне приемлема? Поскольку флаг /checked предполагает проверку всей арифметической логики, в языке C# предлагается ключевое слово unchecked, которое позволяет отключить генерирование System.OverflowException для конкретных случаев, Правила использования этого ключевого слова аналогичны правилам использования ключевого слова checked, и вы можете указать для него один оператор или блок операторов, например:
// Даже если флаг /checked активизирован,
// этот блок не генерирует исключения в среде выполнения.
unchecked {
byte sum = (byte)(b1 + b2);
Console.WriteLine(sum = {0}", sum);
}
Подводя итога обсуждения ключевых слов C# checked и unchecked, снова подчеркнем, что по умолчанию среда выполнения .NET игнорирует условии переполнения, возникающие при использовании арифметических операций. Если вы хотите селективно контролировать условия переполнения для отдельных операторов, используйте ключевое слово checked. Если нужно контролировать ошибки переполнения во всем приложении, укажите флаг /checked, Наконец, можно использовать ключевое слово unchecked, если у вас есть блок программного кода, для которого переполнение приемлемо (и поэтому оно не должно генерировать исключение в среде выполнения).
Исходный код. Проект CheckedUnchecked размещен в подкаталоге, соответствующем главе 9.
Работа с типами указателя
Из главы 8 вы узнали, что платформа .NET определяет две главные категории данных: типы, характеризуемые значениями, и типы, характеризуемые ссылками (ссылочные типы). Однако, справедливости ради., следует сказать, что имеется и третья категория: это типы указателя. Для работы с типами указателя предлагаются специальные операции и ключевые слова, с помощью которых можно "обойти" схему управления памятью CLR и "взять управление в свои руки" (табл. 9.3).
Таблица 9.3. Операции и ключевые слова C# для работы с указателями
Операция или ключевое слово Описание * Используется для создания переменной указателя (т.е. переменной, представляющей непосредственно адресуемую точку в памяти). Как и в C(++), тот же знак используется для операции разыменования указателя (т.е, для операции, которая возвратит значение, размещенное по адресу, указанному операндом) & Используется для получения адреса переменной в памяти –› Используется для доступа к полям типа, представленным указателем (небезопасная версия операции, обозначаемой в C# точкой) [] Операция [] (в небезопасном контексте) позволяет индексировать элемент, на который указывает переменная указателя. (Обратите внимание на аналогию между переменной указателя и операцией [] в C(++).) ++, -- В небезопасном контексте к типам указателя могут применяться операции приращения и отрицательного приращения +, - В небезопасном контексте к типам указателя могут применяться операции сложения и вычитания ==, !=, <, >, <=, >= В небезопасном контексте к типам указателя могут применяться операции сравнения и проверки на тождественность stackalloc В небезопасном контексте можно использовать ключевое слово stackalloc, чтобы размещать массивы C# в стеке fixed В небезопасном контексте можно использовать ключевое слово fixed, временно фиксирующее переменную с тем, чтобы можно было найти ее адресПеред рассмотрением деталей позвольте заметить, что необходимость в использовании типов указателя возникает очень редко, если она возникает вообще. Хотя C# и позволяет "спуститься" на уровень манипуляций с указателями, следует понимать, что среда выполнения .NET не имеет никакого представления о ваших намерениях. Поэтому если вы ошибетесь в направлении указателя, то за последствия будете отвечать сами. Если учитывать это, то когда же на самом деле возникает необходимость использования типов указателя? Есть две стандартные ситуации.