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

Последнее обновление: 18.05.2017

Если в арифметических операциях участвуют значения разных типов, то компилятор неявно пытается привести их к одному типу. Кроме того, когда мы присваиваем переменной какое-либо значение, это значение всегда приводится к типу переменной. Например:

char c = 6;
int d = c;

Переменной d, которая представляет тип int, присваивается значение типа char, поэтому компилятор выполняет приведение значения от типа char к типу int.

В то же время не всегда преобразования могут быть безопасными, поскольку разные типы имеют разное внутреннее представление. И просто так перейти от одного представления к другому без потери точности данных не всегда возможно.

Рассмотрим, какие преобразования применяет компилятор при арифметических операциях:

  1. Если один из операндов имеет тип long double, то второй операнд тоже будет преобразован в тип long double

  2. Если предыдущий пункт не выполняется и если один из операндов имеет тип double, то второй операнд тоже будет преобразован к типу double

  3. Если предыдущий пункт не выполняется и если один из операндов имеет тип float, то второй операнд тоже будет преобразован к типу float

  4. Если предыдущий пункт не выполняется и если один из операндов имеет тип unsigned long int, то второй операнд тоже будет преобразован к типу unsigned long int

  5. Если предыдущий пункт не выполняется и если один из операндов имеет тип long, то второй операнд тоже будет преобразован к типу long

  6. Если предыдущий пункт не выполняется и если один из операндов имеет тип unsigned, то второй операнд тоже будет преобразован к типу unsigned

  7. Если предыдущий пункт не выполняется то оба операнда приводятся к типу int

Например:

int a = 10;
#include <stdio.h>
 
int main(void)
{
    int number1 = 10;
    double number2 = 4;
    double result = number1 + number2;   // 14.000000
    printf("result = %f \n", result);     // result = 14.000000
    return 0;
}

В выражении number1 + number2 число number2 представляет тип double, поэтому число number1 будет автоматически приводиться к числу double. И результат операции сложения также будет представлять тип double.

Операция преобразования

С помощью специальной операции преобразования мы можем явным образом привести данные к нужному типу. Например:

int a = 10;
int b = 4;
int c = a / b;                     // 2
double d = a / b;				// 2.00000
double e = (double)a / (double)b;	// 2.50000
printf("c = %d \n", c);
printf("d = %f \n", d);
printf("e = %f \n", e);

В выражении int c = a / b; результат деления будет целочисленный - 2, при котором дробная часть будет отброшена, так как оба операнда операции представляют целые числа.

В выражении double d = a / b; результат деления будет представлять вещественное число - 2.00000, но так как оба операнда являются целыми числами, то опять же результат операции будет представлять целое число 2, и только поле выполнения деления произойдет присвоение результата переменной d с приведением значения 2 от типа int к типу double.

В выражении double e = (double)a / (double)b применяется явное преобразование данных к типу double, поэтому и результат деления будет представлять вещественное число - 2.50000.

Для выполнения операции приведении в скобках указывается тот тип, к которому надо привести значение:

int number = 70;
char symbol = (char) number;
printf("symbol = %c \n", symbol);			//	F
printf("symbol (int code) = %d \n", symbol);	// 70

В ряде случаев преобразования сопровождаются потерей информации, например, когда числа большей разрядности (скажем размером 4 байт) получаем число меньшей разрядности (например, в 2 байта). Без потери информации проходят следующие цепочки преобразований:

char -> short -> int -> long

unsigned char -> unsigned short -> unsigned int -> unsigned long

float -> double -> long double

При всех остальных преобразованиях, которые не входят в эти цепочки, мы можем столкнуться с потерей точности данных. Так, в примере выше преобразование от int к char не является безопасным, поэтому к таким преобразованиям следует относиться с осторожностью. Например:

#include <stdio.h>
 
int main(void)
{
    
    int number1 = 300;
    char code = number1;    // потеря точности - число number1 усекается до 1 байта
    printf("code = %d \n", code);     // code = 44
    return 0;

    short number2 = 100000;    // потеря точности - число 100000 усекается до 2 байт
    printf("number2 = %d \n", number2);     // number2 = -31072

}

Здесь две ситуации небезопасных преобразований. В первом случае число типа int, которое равно 300, присваивается переменной типа char. В итоге переменная code будет равна 44. Почему? Число 300 в двоичной системе:

0000000100101100

Оставляем только первый младший байт:

00101100

И у нас получается число 44 в десятичной системе.

Во втором случае число 100000 (которое по умолчанию представляет тип int), усекается до разрядности типа short - до двух байт.

short number = 100000;

В итоге число number в реальности будет равно -31072.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850