Стандартные преобразования типов.
При вычислении выражений некоторые операции требуют, чтобы операнды имели соответствующий тип, а если требования к типу не выполнены, принудительно вызывают выполнение нужных преобразований. Та же ситуация возникает при инициализации, когда тип инициализирующего выражения приводится к типу определяемого объекта. Напомним, что в языках Си и Си++ присваивание является бинарной операцией, поэтому сказанное относительно преобразования типов относится и ко всем формам присваивания. Правила преобразования в языке Си++ для основных типов полностью совпадают с правилами преобразований, стандартизованными в языке Си:
операнды разных типов приводятся к "старшему", т.е. более длинному типу; ниже перечислены типы, начиная от самого старшего, в порядке убывания старшинства: самый старший - long double, double, float, unsigned long, long int, unsigned, int, char - самый младший;
при выполнении операции присваивания результат приводится к типу переменной слева от знака операции; в этом случае может возникнуть ситуация преобразования "старшего" типа к "младшему".
При преобразовании типов нужно различать преобразования, изменяющие внутреннее представление данных, и преобразования, изменяющие только интерпретацию внутреннего представления. Например, когда данные типа unsigned unt переводятся в тип int, менять их внутреннее представление не требуется - изменяется только интерпретация. При преобразовании типа float в тип int недостаточно изменить только интерпретацию, необходимо изменить длину участка памяти для внутреннего представления и кодировку. При таком преобразовании из float в int возможен выход за диапазон допустимых значений типа int, и реакция на эту ситуацию существенно от конкретной реализации. Именно поэтому для сохранения мобильности программ в них рекомендуется с осторожностью применять преобразование типов.
Рассмотрим этапы (последовательность выполнения) преобразования операндов в арифметических выражениях.
Все короткие целые типы преобразуются в типы неменьшей длины в соответствии с табл. 1. Затем оба значения, участвующие в операции, принимают тип float или int либо double в соответствии со следующими правилами.
Если один из операндов имеет тип long double, то второй тоже будет преобразован в long double.
Если п.2 не выполняется и один из операндов есть double, другой приводится к типу double.
Если п.2 - 3 не выполняются и один из операндов имеет тип float, то второй приводится к типу float.
Если п.2 - 4 не выполняются (оба операнда целые) и один операнд long int, а другой unsigned int, то, если long int может представить все значения unsigned int, последний преобразуется к long int; иначе оба операнда преобразуются к unsigned long int.
Если п.2 - 5 не выполняются и один операнд есть long, другой преобразуется к long.
Если п.2 - 6 не выполнены и один операнд unsigned, то другой преобразуется к unsigned.
Если п.2 - 7 не выполнены, то оба операнда принадлежат типу int.
Таблица 4
Правила стандартных арифметических преобразований
Исходный тип | Преобразуется в | Правила преобразования |
char | int, unsigned int, long int, unsigned long | Расширение нулем или знаком в зависимости от умолчания для char (см. пример 1) |
unsigned char | int | Старший байт заполняется нулем |
signed char | int | Расширение знаком |
short | int | Сохраняется то же значение |
unsigned short | unsigned int | Сохраняется то же значение |
int | unsigned int | Сохраняется то же значение |
int | long, unsigned long | Расширение знаком |
unsigned int | long unsigned | Добавление двух нулевых старших байтов |
long int | unsigned long | Сохраняется то же значение |
enum | int | Сохраняется то же значение |
битовое поле | int | Сохраняется то же значение |
Пример:
char ff = '\xff ', gg = '\x7f '; int i, j;
i = ff; //0xffff для signed char (размножение знака);
//0x00ff для unsigned char (размножение нуля)
j = gg; //0x007f для signed char (размножение знака);
//0x007f для unsigned char (размножение нуля)
Используя арифметические выражения, следует учитывать приведенные правила и не попадать в "ловушки" преобразования типов, так как некоторые из них приводят к потерям информации, а другие изменяют интерпретацию битового представления данных.
Дата добавления: 2017-01-29; просмотров: 586;