Мегаобучалка Главная | О нас | Обратная связь


Неявные преобразования



2018-07-06 410 Обсуждений (0)
Неявные преобразования 0.00 из 5.00 0 оценок




ля встроенных числовых типов неявное преобразование можно выполнить, сохраняемое значение может уместиться в переменной без обрезания или округления до ближайшего. Например, переменная типа long (8-байтное целое) может хранить любое значение, которое может хранить int (4 байта в 32-разрядном компьютере). В следующем примере компилятор неявно преобразует значение справа в тип long перед присвоением его типу bigNum.

C#

// Implicit conversion. num long can // hold any value an int can hold, and more! intnum = 2147483647;longbigNum = num;

Полный список всех неявных числовых преобразований см. в разделе Таблица неявных числовых преобразований (Справочник по C#).

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

Derived d = new Derived();Base b = d; // Always OK.

Явные преобразования

Однако если преобразование не может быть выполнено без риска потери данных, для компилятора требуется, чтобы пользователь выполнил явное преобразование, которое называется приведением. Приведение является способом явно указать компилятору, что нужно сделать преобразование, и что известно, что может быть потеря данных. Для выполнения приведения заключите тип, в который производится приведение, в скобки перед преобразуемым значением или переменной. Следующая программа выполняет приведение типа double к типу int. Без приведения эта программа скомпилирована не будет.

C#

class Test{static void Main() {double x = 1234.7;int a;// Cast double to int. a = (int)x;System.Console.WriteLine(a);}}// Output: 1234

Список разрешенных явных числовых преобразований, см. в разделе Таблица явных числовых преобразований (Справочник по C#).

Для ссылочных типов явное приведение необходимо, если нужно выполнить преобразование из базового типа в производный тип:

C#

// Create a new derived type.Giraffe g = newGiraffe(); // Implicit conversion to base type is safe.Animal a = g; // Explicit conversion is required to cast back// to derived type. Note: This will compile but will// throw an exception at run time if the right-side// object is not in fact a Giraffe.Giraffe g2 = (Giraffe) a;

Операция приведения между ссылочными типами не меняет тип времени выполнения базового объекта; меняется только тип значения, которое используется в качестве ссылки на этот объект. Дополнительные сведения см. в разделе Полиморфизм (Руководство по программированию на C#).

Исключения преобразования типов во время выполнения

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

C#

class Animal{public void Eat() { Console.WriteLine("Eating."); }public override stringToString() {return "I am an animal."; }}class Reptile : Animal { }class Mammal : Animal { } classUnSafeCast{static void Main() { Test(new Mammal()); // Keep the console window open in debug mode.System.Console.WriteLine("Press any key to exit.");System.Console.ReadKey(); } static void Test(Animal a) {// Cause InvalidCastException at run time // because Mammal is not convertible to Reptile.Reptile r = (Reptile)a; } }

C# предоставляет операторы is и as, чтобы можно было проверить совместимость перед действительным выполнением приведения.Дополнительные сведения см. в разделе Практическое руководство. Безопасное приведение с помощью операторов as и is (Руководство по программированию на C#).

8. Условный оператор

Условный оператор позволяет проверить некоторое условие и в зависимости от результатов проверки выполнить то или иное действие. Таким образом, условный оператор - это средство ветвления вычислительного процесса.

Структура условного оператора имеет следующий вид:

if<условие> then<оператор1> else<оператор2>;

где if/ then/ else - зарезервированные слова (если, то, иначе);

<условие> - произвольное выражение логического типа;

<оператор1>, <оператор2> - любые операторы языка ObjectPascal.

Условный оператор работает по следующему алгоритму. Вначале вычисляется условное выражение <условие>. Если результат есть True (истина), то выполняется <оператор1>, а <оператор2> пропускается; если результат есть False (ложь), наоборот, <оператор1> пропускается, а выполняется <оператор2>. Например:

Var

X, Y, Max: Integer;

Begin .

if X >Max then

Y := Max else

Y := X;

….

end;

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

Условными называются выражения, имеющие одно из двух возможных значений: истина или ложь. Такие выражения чаще всего получаются при сравнении переменных с помощью операций отношения =, <>, >, >=, <, <=. Сложные логические выражения составляются с использованием логических операций and (логическое И), or (логическое ИЛИ) и not (логическое НЕ). Например:

if(а > b) and(b <>0) then ...

Примечание

В отличие от других языков программирования в ObjectPascal приоритет операций отношения меньше, чем у логинеёкйх" операции, по этому отдельные составные части сложного логического вьфажёния 5заключаются в скобки. Например, такая запись предыдущего оператора будет неверной:

if a>b and b <> 0 then ...// Ошибка так как фактически (с учетом приоритета операции) компилятор будет транслировать такую строку:

if a>(b and b)<>0 then...

Часть else<оператор2> условного оператора может быть опущена. Тогда при значении True условного выражения выполняется <оператор1>, в противном случае этот оператор пропускается:

Var

X, Y, Max: Integer;

Begin

if X >Мах thenМах := X;

Y := X;

end;

В этом примере переменная y всегда будет иметь значение переменной х, а в мах запоминается максимальное значение X.

Поскольку любой из операторов <оператор1> и <оператор2> может быть любого типа, в том числе и условным, а в то же время не каждый из “вложенных” условных операторов может иметь часть else<оператор2>, то возникает неоднозначность трактовки условий. Эта неоднозначность в ObjectPascal решается следующим образом:

любая встретившаяся часть else соответствует ближайшей к ней сверху по тексту программы части then условного оператора. Например:

Var

a,b,c,d : Integer;

begina :=1;

b := 2;

с := 3;

d := 4;

if a < b then// Да

if с < d then// Да

if с < 0 then// Нет

с := 0 // Этот оператор не выполняется

Else

а : = b; // а равно 2

if а < b then// Да

if с < d then// Да

if с < 0 then// Нет

с := 0 // с равно 0

else// if с <О

else//if с< d

else// If a < b

а := b; // Этот оператор не выполняется

end;

Условный оператор if

Условный оператор предназначен для организации разветвлений в программах. Условный оператор if является составным и может быть использован в одной из двух форм:

if (<выражение>) <оператор> или if (<выражение>) <оператор1> else<оператор2>

Обратим внимание на то, что в общих формах записи оператора if отсутствует признак конца оператора(;). Дело в том, что ранее определенная синтаксическая конструкция <оператор> уже включает в себя признак конца. Если <оператор> простой, то он будет завершен точкой с запятой. Если <оператор> является блоком, то блок будет определен парными фигурными скобками, и правая фигурная скобка определяет конец блока.

Оператор if работает следующим образом:

1. Форма записи if(<выражение>) <оператор>. Вначале вычисляется значение выражения <выражение>. Если оно ИСТИНА (т.е. его значение отлично от нуля), то выполняется <оператор>. Если значениеЛОЖЬ (выражение равно нулю), то <оператор> пропускается. Форма записи if(<выражение>) <оператор> соответствует алгоритмической схеме, представленной на рис.5.1.

Рис.5.1. Алгоритмическая схема выполнения if(<выражение>) <оператор>

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

if (d==c) ++d,c+=3;

В этом примере в качестве <оператор> используется оператор-выражение с запятой. Этот же пример перепишем по-другому:

if (d==c) ++d; c+=3;

Разница в том , что теперь здесь два оператора: оператор if и оператор-выражение c+=3. Теперь в случае истинности (d==c) все будет по-прежнему: d увеличится на единицу и c увеличится на три. Но в случае ложности (d==c) d не изменится, а с увеличится на 3. Вновь видоизменив этот пример,

if (d==c) {++d;c+=3;}

возвращаемся к первоначальному эффекту; в случае ложности (d==c) d и c не изменяются, т. к. эти операторы находятся в блоке и логически рассматриваются как один оператор – блок.

2. Форма записиif (<выражение>) <оператор1>else<оператор2>. Как и в предыдущем случае, вначале вычисляется значение <выражение>. Если оно отлично от нуля, т.е. истинно, то выполняется <оператор1>, иначе выполняется <оператор2>. Алгоритмическая схема выполнения для этой формы записи условного оператора представлена на рис.5.2.

 

Рис.5.2. Алгоритмическая схема выполнения if (<выражение>) <оператор1>else<оператор2>

Например, если необходимо вычислить z, равное max из a и b, то можно записать:

if (a>b) z=a;
else z=b;

Наличие точки с запятой после z=a обязательно, т.к. это есть оператор, входящий в состав оператора if.

Если первая сокращенная форма оператораif позволяет в программе выполнить или пропустить какое-либо действие, то вторая полная форма if-else позволяет выполнить одно из двух действий. Однако зачастую необходимо осуществить выбор из большого числа вариантов.

Рассмотрим цепочку операторов:

if (<выражение1>) <оператор1>elseif (<выражение2>) <оператор2>
elseif (<выражение3>) <оператор3>else<оператор4>

Такая цепочка вполне допустима, т. к. на месте оператора может быть любой оператор, в том числе и оператор if в той или иной форме. Однако в такой записи достаточно сложно разобраться, поэтому перепишем цепочку так, чтобы else оказалось под соответствующим if:

if(<выражение1>)<оператор1>elseif(<выражение2>)<оператор2>elseif(<выражение3>)<оператор3>else<оператор4>

Сопоставим последний else с ближайшим if, и это будет новый оператор, который включает в себя уже образованный. Схематично это отобразится следующим образом:

 

Таким образом, мы пришли к канонической форме if-else и теперь понятно, как она будет работать. Выражения вычисляются по порядку; если какое-либо выражение истинно, то выполняется сопоставленный с ним оператор и на этом завершается выполнение всей цепочки. Последний оператор цепочки <оператор4> может быть диагностическим вариантом – реакцией программы на тот случай, если ни одно из условий не выполнено. Рассмотрим конкретный пример организации разветвлений в программе.

Допустим, необходимо рассчитать оплату за пользование электроэнергией. Причем плата за электроэнергию производится на следующих условиях: за первые израсходованные 5000 квт/ч оплачивается 0.4 лея за 1 квт/ч, за вторые 5000 взимается 0.6 лея за 1 квт/ч, за третьи 5000 взимается 0.8 лея за квт/ч и, наконец, за израсходованную электроэнергию свыше 15000 квт/ч оплачивается 1.2 лея за каждый превышающий квт/ч. Фрагмент программы, реализующей эти вычисления, может быть записан следующим образом:

if(kwh<=5000)/*kwh - кол-во израсходованной электроэнергии */st=kwh*0.4;/*st - плата за электроэнергию */elseif(kwh<=10000)st=(5000*0.4)+(10000-kwh)*0.6;elseif(kwh<=15000)st=(5000*0.4)+(5000*0.6)+(15000-kwh)*0.8;elsest=(5000*0.4)+(5000*0.6)+(5000*0.8)+(kwh-15000)*1.2;

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

Фрагмента): if(n>0) if(a>b) z=a; else z=b; Фрагментб): if(n>0){ if(a>b) z=a; } else z=b;

B чем разница между ними? Разница в том, что фрагмент а) представляет собой сокращенную форму if, которой в качестве <оператор> стоит if-else; фрагмент б) представляет собой полную форму if-else, в которой в качестве <оператор1> использована сокращенная форма if. Фрагмент б) внешне отличается от фрагмента а) только наличием фигурных скобок, определяющих блок, которые, как мы видим, играют существенную роль при интерпретации этих операторов. Существует правило интерпретации вложенных конструкций if-else, которое гласит, что else соответствует ближайшему if, кроме тех случаев, когда имеются фигурные скобки.



2018-07-06 410 Обсуждений (0)
Неявные преобразования 0.00 из 5.00 0 оценок









Обсуждение в статье: Неявные преобразования

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (410)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.006 сек.)