Г. Шилдт - С#4.0 Полное руководство (1160795), страница 18
Текст из файла (страница 18)
Когда переменной Ь присваивается значение 255, то информация не теряется, поскольку это значение входит в диапазон представления чисел для типа Ьусе. Но когда переменной Ь присваивается значение 257, то часть информации теряется, поскольку это значение превышает диапазон представления чисел для типа Ьубе. Приведение типов требуется в обоих случаях, поскольку нелепое преобразование типа ьп с в тип Ьусе невозможно. Когда переменной в типа вЬогс присваивается значение 32 000 переменной и типа 01пс, потери данных не происходит, поскольку это значение входит в диапазон представления чисел для типа зЬогг. Но в следующей операции присваивания переменная и имеет значение 64 000, которое оказывается вне диапазона представления чисел для типа вЬогС, и поэтому данные теряются.
Приведение типов требуется в обоих случаях, поскольку неявное преобразование типа ндпг в тип вбогб невозможно. Далее переменной и присваивается значение 64 000 переменной 1 типа 1опп. В этом случае данные не теряются, поскольку значение 64 000 оказывается вне диапазона представления чисел для типа пупс. Но когда переменной и присваивается значение -12, данные теряются, поскольку отрицательные числа также оказываются вне диапазона представления чисел для типа пдпс.
Приведение типов требуется в обоих случаях, так как неявное преобразование типа 1оп43 в тип и1пг невозможно. И наконец, когда переменной сЬаг присваивается значение типа Ьусе, информация не теряется, но приведение типов все же требуется. Преобразование типов в выражениях Помимо операций прйсваивания, преобразование типов происходит и в самих выражениях. В выражении можно свободно смешивать два или более типа данных, при условии их совместимости друг с другом. Например, в одном выражении допускается применение типов вйогс и 1опп, поскольку оба типа являются числовыми. Когда в выражении смешиваются разные типы данных, они преобразуются в один и тот же тип по порядку следования операций. Преобразования типов выполняются по принятым в Са правилам продвижения типов.
Ниже приведен алгоритм, определяемый этими правилами для операций с двумя операндами. ЕСЛИ один операнд имеет тип бес1та1, ТО и второй операнд продвигается к типу бе с1ыа1 1но если второй операнд имеет тип 11оас или попЬ1е, результат будет ошибочным). 94 Часть 1. Язык Св' ЕСЛИ один операнд имеет тип с1опЬ1е, ТО и второй операнд продвигается к типу г1опЬ1е. ЕСЛИ один операнд имеет тип 11оа с, ТО и второй операнд продвигается к типу 11оа С. ЕСЛИ один операнд имеет тип п1опс, ТО и второй операнд продвигается к типу и1опо (но если второй операнд имеет тип зЬуге, вЬогс, 1пг или 1опд, результат будет ошибочным).
ЕСЛИ один операнд имеет тип 1опп, ТО и второй операнд продвигается к типу 1 опд. ЕСЛИ один операнд имеет тип пйпс, а второй — тип зьусе, зьогс или 1пг, ТО оба операнда продвигаются к типу 1опд. ЕСЛИ один операнд имеет тип п1пс, ТО и второй операнд продвигается к типу пзпг. ИНАЧЕ оба операнда продвигаются к типу 1пс. Относительно правил продвижения типов необходимо сделать ряд важных замечаний. Во-первых, не все типы могут смешиваться в выражении.
В частности, неявное преобразование типа 11оас или с1опЬ1е в тип г1ес1иа1 невозможно, как, впрочем, и смешение типа п1опд с любым целочисленным типом со знаком. Для смешения этих типов требуется явное их приведение. Во-вторых, особого внимания требует последнее из приведенных выше правил. Оно гласит: если ни одно из предыдущих правил не применяется, то все операнды продвигаются к типу 1пс. Следовательно, все значения типа спас, зЬусе, Ьусе, паЬогг и вЬогг продвигаются к типу 1пг в целях вычисления выражения.
Такое продвижение типов называется целочисленным. Это также означает, что результат выполнения всех арифметических операций будет иметь тип не ниже 1пс. Следует иметь в виду, что правила продвижения типов применяются только к значениям, которыми оперируют при вычислении выражения. Так, если значение переменной типа Ьусе продвигается к типу 1пс внутри выражения, то вне выражения эта переменная по-прежнему относится к типу ьусе. Продвижение типов затрагивает только вычисление выражения. Но продвижение типов может иногда привести к неожиданным результатам. Если, например, в арифметической операции используются два значения типа Ьусе, то происходит следующее.
Сначала операнды типа Ьусе продвигаются к типу 1пс. А затем выполняется операция, дающая результат типа 1пг. Следовательно, результат выполнения операции, в которой участвуют два значения типа Ьусе, будет иметь тип 1пг. Но ведь вто не тот результат, который можно было бы с очевидностью предположить. Рассмотрим следующий пример программы. /! Пример неожиданного результата продвижения типов! пвьпд Зувтеьн с1авв Ргоиоаис 1 вгагьс тога Нагл(1 1 Ьуге Ь! Глава 3. Типы данных, литералы и переменные 95 Ь = (Ьуяе) (Ь * Ь)) /У Необходимо приведение типов!! Сопяо1е.нлгяеглпе("Ь: "Ь Ь); Как ни страйно, но когда результат вычисления выражения Ь*Ь присваивается обратно переменной Ь, то возникает потребность в приведении к типу Ьубе! Объясняется это тем, что в выражении Ь*Ь значение переменной Ь продвигается к типу 1пс и поэтому не может быть присвоено переменной типа Ьусе без приведения типов.
Имейте это обстоятельство в виду, если получите неожиданное сообщение об ошибке несовместимости типов в выражениях, которые, на первый взглял. кажутся совершенно правильными. Аналогичная ситуация возникает при выполнении операций с символьными операндами. Например, в следующем фрагменте кода требуется обратное приведение к типу сйаг, поскольку операнды сЬ1 и сЬ2 в выражении продвигаются к типу упс. спал сп1 = 'а', сЬ2 = 'Ь'; сп1 = (спал) (снг + сп2); Без приведения типов результат сложения операндов сЬ1 и сЬ2 будет иметь тип апг, и поэтому его нельзя присвоить переменной типа сЬаг.
Продвижение типов происходит и при выполнении унарных операций, например сунарным минусом. Операнды унарных операций более мелкого типа, чем лпг (Ьубе, яЬусе, яЬогб и пяЬогс), т.е. с более узким диапазоном представления чисел, продвигаются к типу упс, То же самое происходит и с операндом типа сЬаг. Кроме того, если выполняется унарная операция отрицания значения типа папб, то результат продвигается к типу 1опд.
Приведение типов в выражениях Приведение типов можно применять и к отдельным частям крупного выражения. Это позволяет точнее управлять преобразованиями типов при вычислении выражения. Рассмотрим следующий пример программы, в которой выводятся квадратные корни чисел от 1 до 10 и отдельно целые и дробные части каждого числового результата. Для этого в данной программе применяется приведение типов, благодаря которому результат, возвращаемый методом МаСЬ. Ес(гс (), преобразуется в тип апс.
Пример приведения типов в выражениях. ояьпч зуясеы) с1аяя СаяЯЕхрг яяая1с тогб Маго() бооЬ1е и; Гол(п = 1.0; и <= 10) и++) ( Сопяо1е.нггсеъьпе("Квадратный корень из (О) равен (1)", и, Маяп.зйгя(п)); Сопяо1е.иггсеьппе("Мелах часть числа: (О)" (1пщ Маяп.зйгс(п)); Сопяо1е.нггсеъ1пе("Дробная часть числа: (О)", Маяп.5Чга(п) — (ьпс) Масп.5Чгя(п) 96 Часть ). Язык СЮ Сопво1е. Хг1пепьпе ) ) Вот как выглядит результат выполнения этой программы. Квадратный корень из 1 равен 1 Целая часть числа: 1 Дробная часть числа: 0 Квадратный корень из 2 равен 1.4142135623731 Целая часть числа: 1 Дробная часть числа: 0.414213562373095 Квадратный корень из 3 равен 1.73205080756888 Целая часть числа: 1 Дробная часть числа: 0.732050807568877 Квадратный корень из 4 равен 2 Целая часть числа: 2 Дробная часть числа: О Квадратный корень из 5 равен 2.23606797749979 Целая часть числа: 2 Дробная часть числа: 0.23606797749979 Квадратный корень из б равен 2.44948974278318 Целая часть числа: 2 Дробная часть числа: 0.449489742783178 Квадратный корень из 7 равен 2.64575131106459 Целая часть числа: 2 Дробная часть числа: 0.645751311064591 Квадратный корень из 8 равен 2.82842712474619 Целая часть числа: 2 Дробная часть числа: 0.82842712474619 Квадратный корень из 9 равен 3 Целая часть числа: 3 Дробная часть числа: 0 Квадратный корень из 10 равен 3.16227766016838 Целая часть числа: 3 Дробная часть числа: 0.16227766016838 Как видите, приведение результата, возвращаемого методом МатЬ.
Яс)гс (), к типу Тпс позволяет получить целую часть числа. Так, в выражении Магк. Яств ) и) — ) ьпо) Мак ь. Яств ) и ) приведение к типу Тпг дает целую часть числа, которая затем вычитается из всего числа, а в итоге получается дробная его часть. Следовательно, результат вычисления данного выражения имеет тип с)он)71е. Но к типу Тпг приводится только значение, возвращаемое вторым методом мас)7. Яг)гс (). 98 Часть!.
Язык С() Операторы +, —, * и / действуют так, как предполагает их обозначение. Их можно применить к любому встроенному числовому типу данных. Действие арифметических операторов не требует особых пояснений, за исключением следующих особых случаев. Прежде всего, не следует забывать, что когда оператор / применяется к целому числу, то любой остаток от деления отбрасывается; например, результат целочисленного деления 10/3 будет равен 3. Остаток от этого деления можно получить с помощью оператора деления по модулю ($), который иначе называется оператором вычисления остатка.
Он дает остаток от целочисленного деления. Например, 10 $3 равно 1. В С)) оператор $ можно применять как к целочисленным типам данных, так и к типам с плавающей точкой. Поэтому 10. 0 $3. 0 также равно 1. В этом отношении С)) отличается от языков С и С.н; где операции деления по модулю разрешаются только для целочисленных типов данных. В приведенном ниже примере программы демонстрируется применение оператора деления по модулю.