Программирование на C и C++

Онлайн справочник программиста на C и C++

Преобразование типов при присваивании

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

int х;
char ch;
float f;

void func(void)
{
ch = х; /*    1    */
х = f;    /*    2    */
f = ch;  /*    3    */
f = x;    /*    4    */
}

В строке 1 левые, старшие, биты целочисленной переменной х обрубаются, оставляя в ch младшие 8 битов. Если х содержит число между 256 и 0, то ch и х будут иметь одинаковое значение Иначе значение ch будет содержать только младший набор битов переменной х. В строке 2 х получает целую часть переменной f. В строке 3 f получает 8-битное целое число, хранящееся в ch преобразованное к формату с плавающей точкой. В строке 4 f получает значение целочисленной переменной х, преобразованное к формату с плавающей точкой.

Когда происходит преобразование из целого числа к символу, из длинного целого — к целому и из целого — к короткому целому, то старшие биты будут потеряны. Когда используется 16-битное целое, это означает, что 8 бит будут потеряны при преобразовании от целого к символу и 16 бит будут потеряны при преобразовании от длинного целого к целому.

Таблица содержит все преобразования типов. Следует помнить два важных момента, которые могут повлиять на переносимость создаваемого кода:

Таблица: Обычные результаты преобразования типов
Целевой тип Исходный тип Возможные потери информации
signed char unsigned char Если значение > 127, то результат станет отрицательным числом
char short int Старшие 8 бит
char int (16 бит) Старшие 8 бит
char int (32 бита) Старшие 24 бита
short int int (16 бит) Нет
short int int (32 бита) Старшие 16 бит
int (16 бит) long int Старшие 16 бит
int (32 бита) long int Нет
float double Точность, результат округляется
double long double Точность, результат округляется

  1.  Преобразование из int в float или из float в double и тому подобное не добавляет точности. Такого рода преобразования только изменяют формат представления значения.
  2. Некоторые компиляторы С (и процессоры) всегда трактуют переменные типа char как положительные, независимо от того, какое значение было при преобразовании к целому или плавающему типам. Другие компиляторы могут трактовать переменную типа char как знаковую, где числа, большие, чем 127, трактуются как отрицательные (как делает Borland С++). В целом следует использовать переменные типа char для символов, a int, short int или signed char когда необходимо избежать проблем с переносимостью.

Для получения преобразования, не указанного в таблице, надо просто пошагово преобразовывать типы, пока не получится нужный тип. Например, для преобразования из double в int сначала следует преобразовать double в float, а затем float в int.

При использовании компьютерного языка типа Паскаль, где запрещено автоматическое преобразование типов, можно подумать, что С — слишком скользкий язык. Следует помнить, что С разрабатывался для облегчения жизни программистов, предоставляя возможность работать на нем, а не на ассемблере. С этой целью С позволяет осуществлять такие преобразования типов.