Результат сложения двух чисел типа double тоже имеет тип double. Значение равно 6.541. Теперь его нужно присвоить переменной ival. Типы переменной и результата 6.541 не совпадают, следовательно, тип этого значения приводится к типу переменной слева от знака равенства. В нашем случае это int. Преобразование double в int производится автоматически, отбрасыванием дробной части (а не округлением). Таким образом, 6.541 превращается в 6, и этот результат присваивается переменной ival. Поскольку при таком преобразовании может быть потеряна точность, большинство компиляторов выдают предупреждение.

Так как компилятор не округляет числа при преобразовании double в int, при необходимости мы должны позаботиться об этом сами. Например:

double dva1 = 8.6;

int iva1 = 5;

ival += dva1 + 0.5; // преобразование с округлением

При желании мы можем произвести явное преобразование типов:

// инструкция компилятору привести double к int

ival = static_cast int ( 3.541 ) + 3;

В этом примере мы явно даем указание компилятору привести величину 3.541 к типу int, а не следовать правилам по умолчанию.

В этом разделе мы детально обсудим вопросы и неявного (как в первом примере), и явного преобразования типов (как во втором).

<p>4.14.1. Неявное преобразование типов</p>

Язык определяет набор стандартных преобразований между объектами встроенного типа, неявно выполняющихся компилятором в следующих случаях:

арифметическое выражение с операндами разных типов: все операнды приводятся к наибольшему типу из встретившихся. Это называется арифметическим преобразованием. Например:

int ival = 3;

double dva1 = 3.14159;

// ival преобразуется в double: 3.0

ival + dva1;

*

присваивание значения выражения одного типа объекту другого типа. В этом случае результирующим является тип объекта, которому значение присваивается. Так, в первом примере литерал 0 типа int присваивается указателю типа int*, значением которого будет 0. Во втором примере double преобразуется в int.

// 0 преобразуется в нулевой указатель типа int*

int *pi = 0;

// dva1 преобразуется в int: 3

ivat = dva1;

*

передача функции аргумента, тип которого отличается от типа соответствующего формального параметра. Тип фактического аргумента приводится к типу параметра:

extern double sqrt( double );

// 2 преобразуется в double: 2.0

cout "Квадратный корень из 2: " sqrt( 2 )

endt;

*

возврат из функции значения, тип которого не совпадает с типом возвращаемого результата, заданным в объявлении функции. Тип фактически возвращаемого значения приводится к объявленному. Например:

double difference( int ivati, int iva12 )

{

// результат преобразуется в double

return ivati - iva12;

}

*

<p>4.14.2. Арифметические преобразования типов</p>

Арифметические преобразования приводят оба операнда бинарного арифметического выражения к одному типу, который и будет типом результата выражения. Два общих правила таковы:

* типы всегда приводятся к тому из типов, который способен обеспечить наибольший диапазон значений при наибольшей точности. Это помогает уменьшить потери точности при преобразовании;

* любое арифметическое выражение, включающее в себя целые операнды типов, меньших чем int, перед вычислением всегда преобразует их в int.

* Мы рассмотрим иерархию правил преобразований, начиная с наибольшего типа long double.

Если один из операндов имеет тип long double, второй приводится к этому же типу в любом случае. Например, в следующем выражении символьная константа 'a' трансформируется в long double (значение 97 для представления ASCII) и затем прибавляется к литералу того же типа:

3.14159L + 'a'.

Если в выражении нет операндов long double, но есть операнд double, все преобразуется к этому типу. Например:

int iva1;

float fval;

double dval;

// fva1 и iva1 преобразуются к double перед сложением

dval + fva1 + ival;

В том случае, если нет операндов типа double и long double, но есть операнд float, тип остальных операндов меняется на float:

char cvat;

int iva1;

float fva1;

// iva1 и cval преобразуются к float перед сложением

cvat + fva1 + iva1;

Перейти на страницу:

Похожие книги