2.6. Преобразование типов
Преобразование типов при присваивании.
Преобразование типов предназначено для ситуации, в которой переменные одного типа смешиваются с переменными другого типа. Когда возникает подобная ситуация в выражении присваивания, используется правило преобразования типов: значение операнда справа от операции присваивания преобразуется к типу операнда, стоящего слева. Это демонстрируется следующим примером:
int x;
char ch;
float f;
void func(void)
{
ch = x; /* 1 */
x = f; /* 2 */
f = ch; /* 3 */
f = x; /* 4 */
}
В строке 1 левые (старшие) биты целочисленной переменной x обрубаются, оставляя в ch младшие 8 битов. Если х содержит число между 255 и 0, то ch и х будут иметь одинаковое значение. Иначе значение ch будет содержать только младший набор битов переменной х. В строке 2 х получает целую часть переменной f. В строке 3 f получает 8-битное целое число, хранящееся в ch, преобразованное к формату с плавающей точкой. В строке 4 f получает значение целочисленной переменной х, преобразованное к формату с плавающей точкой.
Когда происходит преобразование из переменной, занимающей большее количество байт в переменную с меньшим, то старшие биты будут потеряны.
Следует помнить два важных момента, которые могут повлиять на переносимость создаваемого кода:
Когда происходит преобразование из переменной, занимающей большее количество байт в переменную с меньшим, то старшие биты будут потеряны
Преобразование из int в float или из float в double и тому подобное не добавляет точности. Такого рода преобразования только изменяют формат представления значения.
Преобразование типов в выражениях. Когда операнды различных типов смешиваются в выражениях, то происходит преобразование к одному типу. Компилятор преобразует все операнды «вверх», к типу большего операнда. Ниже описываются правила преобразования типов.
1) Все переменные типа char и short int преобразуются к типу int. Все переменные типа float – к типу double.
2) Если один из пары операндов имеет тип long double, другой операнд также преобразуется к long double.
3) Если один из пары операндов имеет тип double, другой операнд (кроме long double) также преобразуется к типу double.
4) Если один из операндов имеет тип long, другой операнд также преобразуется к long.
5) Если один из операндов имеет тип unsigned, другой операнд также преобразуется к типу unsigned.
В результате применения этих правил преобразования каждая пара операндов будет иметь тип и результат каждой операции будет совпадать по типу с операндами. Рассмотрим преобразование типов, показанное на рисунке.
char ch;
int i;
float f;
double d;
result = (ch/i) + (f*d) – (f+i);
Cначала символ ch преобразуется к целому int, а вещественная переменная с одинарной точностью f преобразуется к типу double. Затем ch/i преобразуется к типу double, поскольку f*d имеет тип double. Конечный результат имеет тип double, поскольку оба операнда типа double.
Принудительные преобразования.
Имеется возможность заставить выражение принять определенный тип с помощью операции принудительных преобразований. Эта операция имеет следующие виды:
(тип) выражение
где тип – это один из стандартных типов данных языка С или определяемый пользователем тип. Например, чтобы выражение x/2 имело тип float (остаток сохранится), следует написать:
(float) 5/2;
Операция принудительных преобразований – это унарный операция, имеющая такой же приоритет, как и остальные унарные операции.
