Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
A.doc
Скачиваний:
36
Добавлен:
09.04.2015
Размер:
5.6 Mб
Скачать

74 Глава 2

  1. Любой операнд типа char, signed char, unsigned char, short или unsigned short преобразуется в тип int.

  2. Перечислимый тип преобразуется сначала в int, unsigned int, long или unsigned long, в зависимости от того, какого из них достаточно, чтобы вме- стить диапазон перечислителей.

  3. Если один из операндов типа unsigned long, то другой преобразуется в unsigned long.

  4. Если один из операндов типа long, а другой — типа unsigned int, то оба опе- ранда преобразуются к типу unsigned long.

  5. Если любой из операндов типа long, то второй преобразуется в тип long.

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

Также предположим, что у вас есть следующее, достаточно произвольное арифме- тическое выражение:

Теперь вы можете попробовать предположить, какие приведения выполнит ком- пилятор при выполнении этого оператора.

Первая операция, которую нужно вычислить — это (value — count). Правило 1 здесь не применимо, зато подходит правило 2, поэтому значение count преобразует- ся в double, и в результате получается значение 15.0 типа double.

Следующим должно выполниться (count — num), и здесь первое подходящее пра- вило из последовательности — это правило 4, поэтому num преобразуется из char в int, и получается результат 12 типа int.

Следующий шаг вычисления — перемножение двух первых результатов — double, равное 15.0, и int, равное 12. Здесь применимо правило 2, и 12 преобразуется в 12.0 с типом double, в результате получается значение double, равное 180.0.

Полученный результат теперь должен быть разделен на many, поэтому опять при- меняется правило 2, и значение many преобразуется в double перед генерацией double результата 90.0.

Следующим вычисляется выражение num/many, и здесь применяется правило 3, чтобы получить значение float, равное 2 . Of, после преобразования типа num из char в float.

В конце к double-значению 90.0 прибавляется float-значение 2 . Of, для чего применяется правило 2, которое требует преобразования 2 . Of в double-значение 2.0, и окончательный результат 92.0 присваивается value.

Хотя чтение этой последовательности несколько напоминает "песню аукционис- та", основную идею вы поняли.

Данные, переменные и вычисления 75

Приведения в операторах присваивания

Как вы видели ранее в этой главе на примере, вы можете вызвать не-

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

Например, после выполнения следующего фрагмента кода:

значение number будет равно 2. Обратите внимание на f в конце константы 2 . 5f. Это указывает компилятору, что это константа с плавающей точкой одинарной точ- ности. Без f по умолчанию она бы имела тип double. Любая константа, содержащая десятичную точку, является значением с плавающей точкой. Если вам не нужно, что- бы она имела двойную точность, добавляйте к ней f. Заглавная F тоже подходит.

Явные приведения

Когда смешанные выражения включают базовые типы, то компилятор при необхо- димости выполняет нужные приведения, но вы также можете принудительно указать приведение одного типа к другому, используя явные приведения. Чтобы привести значение выражения к определенному типу, необходимо написать так:

Ключевое слово staticcast отражает тот факт, что приведение выполняется статически — то есть, когда программа компилируется. Никаких дальнейших прове- рок безопасности приведения во время выполнения программы не осуществляется. Позднее, когда вы будете иметь дело с классами, вы познакомитесь с dynamic_cast — когда преобразование проверяется динамически, то есть, во время выполнения программы. Есть еще два других вида приведений: const_cast — для исключения константности выражения и reinterpretcast, которое означает безусловное при- ведение, но о них я пока не буду говорить.

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

Вот специфический пример применения:

Инициализирующим выражением для whole_number является сумма целых частей valuel и value2, в которых остается 10.5 и 15.5 соответственно. Значения 10 и 15, порожденные приведением, сохраняются лишь временно, для использования в вы- числении суммы, а затем теряются. Хотя оба приведения приводят при вычислении к потере информации, компилятор предполагает, что вы знаете, что делаете, приме- няя явное приведение.