
C_Kurs_Lekt / C_I_семестр / 03_ПРАВИЛА ПРЕОБРАЗОВАНИЯ ТИПОВ
.pdf
ПРАВИЛА ПРЕОБРАЗОВАНИЯ ТИПОВ.
При вычислении выражений некоторые операции требуют, чтобы операнды имели соответствующий тип, а если требования к типу не выполнены, принудительно вызывают выполнение нужных преобразований. Та же ситуация возникает при инициализации, когда тип инициализирующего выражения приводится к типу определяемого объекта. В языке Си присваивание является бинарной операцией, поэтому сказанное относительно преобразования типов относится и ко всем формам присваивания, однако при присваиваниях значение выражения из правой части всегда приводится к типу переменной из левой части, независимо от соотношения этих типов.
Правила преобразования в языке Си для основных типов определены стандартом языка. Эти стандартные преобразования включают перевод "низших" типов в "высшие".
Среди преобразований типов выделяют:
• преобразования в арифметических выражениях;
• преобразования при присваиваниях;
• преобразования указателей.
Рассмотрим преобразования типов при арифметических операциях и особенности преобразований типов при присваиваниях.
При преобразовании типов нужно различать преобразования, изменяющие внутреннее представление данных, и преобразования, изменяющие только интерпретацию внутреннего представления. Например, когда данные типа unsigned int переводятся в тип int, менять их внутреннее представление не требуется - изменяется только интерпретация. При преобразовании значений типа float в значение типа int недостаточно изменить только интерпретацию, необходимо изменить длину участка памяти для внутреннего представления и кодировку. При таком преобразовании из float â int возможен выход за диапазон допустимых значений типа int, и реакция на эту ситуацию существенно зависит от конкретной реализации. Именно поэтому для сохранения мобильности программ в них рекомендуется с осторожностью применять преобразование типов.
Рассмотрим последовательность выполнения преобразования операндов в арифметических выражениях.
1.Все короткие целые типы преобразуются в типы не меньшей длины в соответствии с табл.. Затем оба значения, участвующие в операции, принимают одинаковый тип в соответствии со следующими ниже правилами.
2.Если один из операндов имеет тип long double, то второй тоже будет преобразован в long double.
3.Если п. 2 не выполняется и один из операндов есть double, другой приводится к типу double.
4.Если п. 2 - 3 не выполняются и один из операндов имеет тип float, то второй приводится к типу float.
5.Если п. 2 - 4 не выполняются (оба операнда целые) и один операнд unsigned long int, то оба операнда преобразуются к типу unsigned long int.
6.Если п. 2 - 5 не выполняются и один операнд есть long, другой преобразуется к типу long.
7.Если п. 2 - 6 не выполняются и один операнд unsigned, то другой преобразуется к типу unsigned.
8.Если п. 2 - 7 не выполнены, то оба операнда принадлежат типу int.
Используя арифметические выражения, следует учитывать приведенные правила и не попадать в "ловушки" преобразования типов, так как некоторые из них приводят к потерям информации, а другие изменяют интерпретацию битового (внутреннего) представления данных. На рис. стрелками отмечены "безопасные" арифметические преобразования, гарантирующие сохранение точности и неизменность численного значения.
Таблица Правила стандартных арифметических преобразований
Исходный тип |
Преобразованный тип |
Правила преобразований |
|
|
|
char |
int |
Расширение нулем или знаком в зависимости от |
|
|
умолчания для char |
|
|
|
unsigned char |
int |
Старший байт заполняется нулем |
|
|
|
signed char |
int |
Расширение знаком |
|
|
|
short |
int |
Сохраняется то же значение |
|
|
|
unsigned short |
unsigned int |
Сохраняется то же значение |
|
|
|
enum |
int |
Сохраняется то же значение |
|
|
|
битовое поле |
int |
Сохраняется то же значение |
|
|
|
Арифметические преобразования типов, гарантирующие сохранение значимости
При преобразованиях, которые не отнесены схемой к безопастным, возможны существенные информационные потери. Для оценки значимости таких потерь рекомендуется проверить обратимость преобразования типов. Преобразование целочисленных значений в вещественные осуществляется настолько точно, насколько это предусмотрено аппаратурой. Если конкретное целочисленное значение не может быть точно представлено как вещественное, то младшие значащие цифры теряются и обратимость невозможна.
Приведение вещественного значения к целому типу выполняется за счет отбрасывания дробной части. Преобразование целой величины в вещественную также может привести к потере точности.