Явные преобразования типов

Задания раздела 4.11.3
4.36. С учетом того, что i имеет тип int, а d - double, напишите выражение i*=d так, чтобы осуществлялось целочисленное умножение, а не с плавающей запятой.
4.37. Перепишите каждое из следующих приведений старого стиля так, чтобы использовался именованный оператор приведения.
int i; double d; const string *ps; char *pc; void *pv;
(a) pv=(void*)ps;
(b) i=int(*pc);
(c) pv=&d;
(d) pc=(char*)pv;
4.38. Объясните следующее выражение:
double slope=static_cast<double> (j/i);

4.11.3


Сначала немного по неявным преобразованиям: преобразование имени массива в указатель на первый элемент, преобразование в тип bool в условии, преобразование в константу, преобразование литерала в строку.

Ага, вот оно. Приведение (cast) типов - это явное преобразование.
Синтаксис: что делаю <какой хочу тип> (над чем издеваюсь)
что делаю: static_cast, dynamic_cast,  const_cast, reinterpret_cast.

static_cast. производит любое стандартное преобразование типов кроме const нижнего уровня. полезен при присвоении значения большего арифметического типа переменной меньшего.
с типом void я знакомился поверхностно. было сказано что значения типа void можно трогать, но их тип по сути неизвестен. ну так вот, static_cast полезен там, где компилятор не выполняет преобразования автоматически. Например, получить значение указателя, сохраняемого в указателе void*.
void* p=&d;
double *dp=static_cast<double*>(p);

const_cast. Изменяет только спецификатор const нижнего уровня своего операнда. При сбросе константности объекта компилятор больше не будет препятствовать записи в этот объект. Если объект первоначально не был константным, использование приведения для доступа на запись допустимо. Но применение оператора const_cast для записи в первоначальный объект непредсказуемо.

reinterpret_cast. Осуществляет низкоуровневую интерпретацию битовой схемы своих операндов.
int *ip;
char *pc=reinterpret_cast<char*>(ip);

Советуют избегать приведения типов.  Счастье то какое.

4.36. С учетом того, что i имеет тип int, а d - double, напишите выражение i*=d так, чтобы осуществлялось целочисленное умножение, а не с плавающей запятой.
#include <iostream>
int main()
{
int i=1024; double d=2.05;
i*=static_cast<int>(d);
std::cout << i;
return(0);
}

4.37. Перепишите каждое из следующих приведений старого стиля так, чтобы использовался именованный оператор приведения.
int i; double d;
const string *ps;
char *pc;
void *pv;
(a) pv=(void*)ps;
(b) i=int(*pc);
(c) pv=&d;
(d) pc=(char*)pv;

В общем моего понимания языка еще не достаточно. Нужно больше практики для такого как я чтобы основательно разобраться. Но основы я уловил.
(a) pv=(void*)ps; /* pv=const_cast<std::string*>(ps); чтобы указателю на тип void присвоить значение константного указателя на тип string надо отбросить const нижнего уровня */
(b) i=int(*pc); // i=static_cast<int>(*pc); здесь все просто
(c) pv=&d; /* что здесь от меня требуется я не особо понял. но на всякий случай привет указатель pv к типу double - static_cast<double*>(pv); */
(d) pc=(char*)pv; /* pc=reinterpret_cast<char*>(pv); просто очень похоже на пример из книжки. зачем это делать я не в курсе. просто сделал на всякий случай */
Программа для проверок всякого изврата:
#include <iostream>
#include <string>
int main()
{
int i; double d;
const std::string *ps;
char *pc;
void *pv;
pv=const_cast<std::string*>(ps);
std::cout << pv << std::endl;
i=static_cast<int>(*pc);
std::cout << i<< std::endl;
static_cast<double*>(pv);
pv=&d;
std::cout << pv << std::endl;
pc=reinterpret_cast<char*>(pv);
std::cout << pc << std::endl;
return(0);
}

4.38. Объясните следующее выражение:
double slope=static_cast<double> (j/i);

Вычисляется значение в скобках, которое приводится к типу double и присваивается переменной slope типа double.
Если переменные i и j типа double - нет никаких проблем, если типа int, как в программе ниже, будет потеря точности. Чтобы избежать этого, необходимо переписать так: double slope=static_cast<double> (j)/i;  То есть сначала преобразовывается переменная j в тип double а затем компилятор по правилам преобразования преобразовывает переменную i в больший присутствующий в выражении тип.

#include <iostream>
int main()
{
int i=1024; int j=2049;
double slope=static_cast<double> (j/i);
std::cout << slope << " "<< sizeof(static_cast<double> (j/i))*8;
return(0);
}

Добавить комментарий