Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Null, NaN и Infinity






Значение null не является единственным особым значением, входящим в множество возможных значений значимого типа. У вещественного типа данных (double и float) есть и другие особые значения, не являющиеся обыкновенными числами. Таких значений три - Infinity, NegativeInfinity и NaN. Первые два хорошо известны из математики - это бесконечность и отрицательная бесконечность. Третье значение NaN (Not a Number) появляется тогда, когда результат не является вещественным числом или значением null иInfinity. Рассмотрим правила, приводящие к появлению особых значений.

Если при выполнении операций умножения или деления результат по модулю превосходит максимально допустимое число, то значением является бесконечность или отрицательная бесконечность в зависимости от знака результата. У типов double и float есть константы, задающие эти значения. При выполнении операций сложения, вычитания и умножения бесконечности с обычными вещественными числами результат имеет значение бесконечность, возможно, с противоположным знаком. При делении вещественного числа на бесконечность результат равен нулю.

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

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

Рассмотрим примеры:

static void NullAndNan(){ double? u = null, v = 0, w = 1.5; Console.WriteLine(" u = {0}, v = {1}, w = {2}", u, v, w);

Пока что введены три переменные типа double?, одна из которых получила значение null. Введем еще несколько переменных этого же типа, которые получат в результате вычислений особые значения:

double? x, y, z; x = u + v; y = w / v; z = x + y; Console.WriteLine(" x = u + v = {0}, y = w / v = {1}, " +" z = x + y = {2}", x, y, z);

При вычислении значения переменной x в выражении участвует null, поэтому и x получит значение null. При вычислении значения переменной y выполняется деление на ноль, поэтому y получит значение бесконечность. При вычислении значения переменной z в выражении участвует null и бесконечность, поэтому z получит значение null. Рассмотрим еще один фрагмент кода:

x = -y; y = v * y; z = x + y; Console.WriteLine(" x = -y = {0}, y = v * y = {1}, " +" z = x + y = {2}", x, y, z);

При вычислении значения переменной x происходит смена знака и x получает значение отрицательной бесконечности. При вычислении значения переменной y бесконечность умножается на ноль, результат не определен и будет иметь значение NaN. При сложении бесконечности со значением NaN результат будет NaN. Ну и еще один заключительный фрагмент:

double p = -(double)w, q = double.NegativeInfinity; Console.WriteLine(" p = {0}, q = {1}, 1 / q = {2}", Math.Sqrt(p), q, 1 / q); p = 1e160; Console.WriteLine(" p = {0}, p * p = {1}", p, p * p); float p1 = 1e20f; Console.WriteLine(" p1 = {0}, p1 * p1 = {1}", p1, p1 * p1);

Выражения над строками. Преобразования строк

Начнем с символьного типа. Давайте уточним, какие выражения можно строить над операндами этого типа. На алфавите символов определен порядок, задаваемый Unicode кодировкой символов. Знать, как кодируется тот или иной символ, не обязательно, но следует помнить, что кодировка буквенных символов таких алфавитов, как кириллица, латиница и других языковых алфавитов, являющихся частью Unicode алфавита, является плотной, так что, например, код буквы " а" на единицу меньше кода буквы " б". Исключение составляет буква " Ё", выпадающая из плотной кодировки. Большие буквы (заглавные) в кодировке предшествуют малым буквам (строчным). Для цифр также используется плотная кодировка.

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

char sym = 'Ё'; int code_Sym = sym; Console.WriteLine(" sym = {0}, code = {1}", sym, code_Sym); code_Sym++; sym = (char)code_Sym; Console.WriteLine(" sym = {0}, code = {1}", sym, code_Sym);

Существование неявного преобразования между типом char и целочисленными типами позволяет рассматривать тип char как целочисленный. Как следствие, к операндам символьного типа применимы все операции, применимые к целочисленным типам - операции отношения, арифметические операции, логические операции над целыми числами. В реальных программах к таким операндам чаще всего применяются операции сравнения и операция вычитания, позволяющая определить " расстояние" между символами в кодировке.

Рассмотрим теперь строковый тип. В некоторых языках программирования используется тот факт, что порядок на символах алфавита порождает лексикографический порядок на словах, составленных из этих символов. Но в языке C# это не так, и здесь не существует неявного преобразования строки в целочисленный тип. Понять причину этого не трудно. Строки C# имеют переменную длину и могут быть сколь угодно длинными, так что не существует безопасного преобразования ни в один из целочисленных типов.

По этой причине над операндами строкового типа из множества операций, задаваемых знаками логических, арифметических и операций отношения, определены только три операции. Две операции позволяют сравнивать строки на эквивалентность (==,! =). Третья операция, задаваемая знаком операции " +", называется операцией конкатенации или сцепления строк и позволяет вторую строку присоединить к концу первой строки.

Операторы языка C#

Only assignment, call, increment, decrement, and new object expressions can be used as a statement

Оператор присваивания

Синтаксически присваивание состоит из левой и правой частей, разделенных знаком операции присваивания. Правая часть - это выражение, в том числе выражение присваивания, как в последнем примере. Левая часть - это переменная; более точно: левая часть представляет собой lvalue - выражение левой части, которому можно присвоить значение. Переменная является наиболее распространенным частным случаем lvalue.

Выражение присваивания представляет собой пример выражения с побочным эффектом. Прямым эффектом вычисления такого выражения является вычисленное значение и тип выражения expr. Побочным эффектом является присваивание вычисленного значения переменной левой части.

Выражение с побочным эффектом в языке C# можно легко преобразовать в соответствующий оператор. Стоит такое выражение закончить символом точка с запятой, как получится оператор, который можно использовать всюду, где синтаксически допустимы операторы языка. Так что синтаксически оператор присваивания выглядит так:

X = expr;

Допустимы и многочисленные вариации:

X1 += X2 *= … = Xk = expr;

К операторам присваивания можно отнести и такие операторы, как:

X++; X--; ++X; --X;

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

Блок, или составной оператор

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

{ оператор_1 … оператор_N}

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

Пустой оператор

Пустой оператор - это " пусто", завершаемое точкой с запятой. Иногда полезно рассматривать отсутствие операторов как существующий пустой оператор.

Операторы выбора

Как в С++ и других языках программирования, в языке C# для выбора одной из нескольких возможностей используются две конструкции - if и switch. Первую из них обычно называют альтернативным выбором, вторую - разбором случаев.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.