1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 15
Текст из файла (страница 15)
Поэтому вместо этого С# преобразует nl в значение типа d o u b l e и использует оператор умножения d o u b l e * d o u b l e . Это действие известно как неявное повышение типа (implicit promotion).Такое повышение называется неявным, поскольку С# выполняет его автоматически,и является повышением, так как включает естественную концепцию высоты типа.
Списокоператоров умножения был приведен в порядке повышения— от i n t до d o u b l e , илиот i n t до d e c i m a l — от типа меньшего размера к типу большего размера. Между типами с плавающей точкой и d e c i m a l неявное преобразование не выполняется. Преобразование из более емкого типа, такого как d o u b l e , в менее емкий, такой как i n t , называется понижением (demotion).Повышение иногда называют преобразованием вверх (up conversion), а понижение —преобразованием вниз (down conversion).Неявные понижения запрещены.
В таких случаях С# генерирует сообщение обошибке.Явное преобразование т и п аНо что, если С# ошибается? Если на самом деле программист хотел выполнить целоеумножение?Вы можете изменить тип любой переменной с типом-значением с помощью оператораприведения типа (cast), который представляет собой требуемый тип, заключенный в скобки,и располагаемый непосредственно перед приводимой переменной или выражением.Глава 4. Операторы81Таким образом, в следующем выражении используется оператор умножения i n t * i n t :int nldoubledouble= 10;d2 = 5 . 0 ;nResult =nl*(int)d2;Приведение d2 к типу i n t известно как явное понижение (explicit demotion) или noiнижающее приведение (downcast).
Понижение является явным, поскольку программю!явно объявил о своих намерениях.Вы можете осуществить приведение между двумя любыми типами-значениями, немвисимо от их взаимной высоты.Избегайте неявного преобразования типов. Делайте все изменения типов!значений явными с помощью оператора приведения.Оставьте л о г и к у в покоеС# не позволяет преобразовывать другие типы в тип b o o l или выполнять преобразование типа b o o l в другие типы.Т и п ы при присваиванииВсе сказанное о типах выражений применимо и к оператору присваивания.Случайные несоответствия типов, приводящие к генерации сообщений обошибках, обычно происходят в операторах присваивания, а не в точке действительного несоответствия.Рассмотрим следующий пример умножения:i n t n l = 10;i n t П2 = 5 .
0*nl;Вторая строка этого примера приведет к генерации сообщения об ошибке, связаннойс несоответствием типов, но ошибка произошла при присваивании, а не при умножении.Вот что произошло: для того чтобы выполнить умножение, С# неявно преобразовал nlв тип d o u b l e . Затем С# выполнил умножение двух значений типа d o u b l e , получив врезультате значение того же типа d o u b l e .Типы левого и правого аргументов оператора присваивания должны совпадать, нотип левого аргумента не может быть изменен.
Поскольку С# не может неявно понизитьтип выражения, компилятор генерирует сообщение о том, что он не может неявно преобразовать тип d o u b l e в i n t .При использовании явного приведения никаких проблем не возникнет:int nli n t n2==10;(int) (5.0*nl) ;(Скобки необходимы, потому что оператор приведения имеет очень высокий приоритет.)Такой исходный текст вполне работоспособен, так как явное понижение разрешено.Здесь значение nl будет повышено до d o u b l e , выполнено умножение, а результат типаd o u b l e будет понижен до i n t .
Однако в этой ситуации надо подумать о душевном здоровье программиста, поскольку написать просто 5 * п 1 было бы проще как для программиста, так и для С#.82Часть II. Основы программирования в С#Большинство операторов имеют два аргумента, меньшинство —- один. И только одиноператор — тернарный — имеет три аргумента. Лично я считаю, что это ненужная экзотика. Вот формат этого оператора:Выражение т и п а b o o l ? Выражение1:Выражение2А это пример его применения:int а = 1 ;int Ь = 2 ;int nMax =(a>b)? а:Ь;Если а больше Ь (условие в скобках), значение выражения равно а.
Если а не больше Ь,значение выражения равно Ь.Выражения 1 и 2 могут быть любой сложности, но это должны быть истинные выражения— они не могут содержать объявлений или других инструкций, не являющихсявыражениями.3Тернарный оператор непопулярен по следующим причинам.Он не является необходимым. Использование оператора i f , описанного в главе 5, "Управление потоком выполнения", дает тот же эффект, и его легче понять.На тернарный оператор накладываются дополнительные ограничения.
Например, выражения 1 и 2 должны быть одного и того же типа. Это приводитк следующему:int а = 1 ;double b = 0 . 0 ;i n t nMax = ( a > b ) ? а : b;Такой исходный текст не будет компилироваться, несмотря на то что в конечномитоге nMax будет иметь значение а. Поскольку а и b должны быть одного и тогоже типа, а будет повышено до d o u b l e , чтобы соответствовать Ь. Тип результирующего значения оператора ?:оказывается d o u b l e , и этот тип должен бытьпонижен до i n t перед присваиванием:int а = 1 ;double b = 0 . 0 ;i n t nMax;/ / Можно п о с т у п и т ьnMax = ( i n t ) ( ( a > b )/ / . . . или т а к :nMax = ( a > b ) ? а :так:? а : b) ;(int)b;Увидеть тернарный оператор в реальной программе — большая редкость.3Непопулярность этого оператора относится к С#, программистами на С и С++ он употребляется достаточно часто и не вызывает никаких отрицательных эмоций.
— Примеч. ред.Глава 4. Операторы83Глава 5Управление потоком выполнения> Что делать, если...> Цикл w h i l e> Цикл f o r> Конструкция s w i t c hассмотрим следующую простую программу:using S y s t e m ;namespace H e l l o W o r l d(publicclassProgram{/ / С т а р т о в а я т о ч к а программыs t a t i c void Main(string[] args){/ / Приглашение д л я в в о д а и м е н иC o n s o l e . W r i t e L i n e ( " В в е д и т е ваше и м я : " ) ;/ / Считывание в в е д е н н о г о и м е н иs t r i n g sName = C o n s o l e . R e a d L i n e ( ) ;// П р и в е т с т в и е с и с п о л ь з о в а н и е м в в е д е н н о г о имениConsole.WriteLine("Привет, " + sName);/ / Ожидание п о д т в е р ж д е н и я п о л ь з о в а т е л яC o n s o l e .
W r i t e L i n e ( " Н а ж м и т е <Enter> для ""завершенияпрограммы...");Console.Read();Толку от этой программы, помимо иллюстрации некоторых фундаментальных моментов программирования С#, очень мало. Она просто возвращает вам то, что вы ввели.Вы можете представить более сложный пример программы, в которой выполняются некоторые вычисления над введенными данными и генерируется какой-то более сложныйвывод на экран (иначе для чего проводить вычисления?...), но и эта программа будеточень ограничена в своей функциональности.Одним из ключевых элементов любого компьютерного процессора является его возможность принимать решения.
Под выражением "принимать решения" имеется в виду,! что процессор может пустить поток выполнения команд по одному или другому путив зависимости от того, истинно или ложно некоторое условие. Любой язык программирования должен обеспечивать такую возможность управления потоком выполнения.Основой возможности принятия решения в С# является оператор i f :ifi(Условие)IIЭтоткодвыполняется,еслиУсловиеистинно}////Этот код выполняется вне з а в и с и м о с т и отистинностиУсловияНепосредственно за оператором if в круглых скобках содержится некоторое условное выражение типа b o o l (см.
главу 4, "Операторы"), после чего следует код, заключенный в фигурные скобки. Если условное выражение истинно (имеет значение true),программа выполняет код, заключенный в фигурных скобках. Если нет — этот код программой опускается.Работу оператора if проще понять, рассматривая конкретный пример:// Гарантируем, ч т о а - н е о т р и ц а т е л ь н о :/ / Е с л и а меньше 0 .
. .i f ( а < 0){// ...присваиваем э т о й переменной значение 0а = 0;}В этом фрагменте исходного текста проверяется, содержит ли переменная а отрицательное значение, и если это так, переменной а присваивается значение 0.Если в фигурных скобках заключена только одна инструкция, то их можно неиспользовать, т.е. в приведенном выше фрагменте можно было бы написатьif ( а < 0 ) а = 0,-. Но на мой взгляд, для большей удобочитаемости лучше всегда использовать фигурные скобки.О п е р а т о р ifРассмотрим небольшую программу, вычисляющую проценты. Пользователь вводитвклад и проценты, и программа подсчитывает сумму, получаемую по итогам года (это неслишком сложная программа).