Бесплатный курс по C++. Зарегистрируйтесь для отслеживания прогресса →

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

Как мы уже поняли разные типы данных по-разному хранятся в памяти компьютера. Например, целочисленное значение 3 может быть сохранено как двоичное 0000 0000 0000 0000 0000 0000 0000 0011, тогда как значение с плавающей запятой 3.0 может быть сохранено как двоичное 0100 0000 0100 0000 0000 0000 0000 0000.

Так что же происходит когда мы инициализируем переменную типа float целым числом.

float f_age { 18 };

А произойдет следующее: поскольку компилятор не может просто сохранить целое число в переменную с плавающей точкой, он преобразует это число в эквивалентное, но типа float.

Процесс преобразования значения из одного типа данных в другой тип данных называется преобразованием типа.

Преобразования типов могут быть неявные - по решению компилятора и явные по решению программиста.

Неявное преобразование типа выполняется компилятором автоматически, когда требуется один тип данных, но предоставляется другой тип. Подавляющее большинство преобразований типов в C++ являются неявными преобразованиями типов.

Неявное преобразование может происходить в следующих случаях:

  • если мы делаем арифметическую операцию двух разных типoв. Преобразование идет в тот тип который шире.
double d_result { 4.2 / 3 } // 3 будет пеобразованна в double
  • если происходит инициализация переменной другого типа. Тут уже может быть, что мы например сохраним число типа long в переменную типа int и тут уже зависит от способа инициализации переменной.
double d_num { 3 }; // 3 будет преобразованна в double
int num = 3.14; // будет потерянна вещевственная часть
int num = { 3.14 }; // ошибка компиляции
  • Забегая вперед. При использовании небулевого значения в инструкции if
if (5) { } // 5 будет преобразованно в true

Но явное всегда лучше, чем неявное. В C++ существует 5 различных видов приведений типа: приведения в стиле C, статические приведения, константные приведения, динамические приведения и реинтерпретирующие приведения. Последние четыре иногда называют именованными приведениями.

Здесь мы рассмотрим приведение в стиле С и статическое приведение.

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

int main() {
  int x { 5 };
  int y { 4 };
  double d_result { (double)x / y }; // x преобразуется в тип double
}

В приведенном выше коде мы явно указали компилятору чтобы он преобразовал int x в double.

C++ также позволяет вам использовать приведение в стиле C с синтаксисом, более похожим на вызов функций:

double d_result { double(x) / y };

Это работает идентично предыдущему примеру, но тут преимущество в том, что преобразуемое значение заключено в скобки - это упрощает определение того, что конвертируется.

Приведение в стиле С не рекомендуется использовать поскольку под капотом он может выполнять множество различных преобразований в зависимости от контекста и даже убирать константность.

В C++ появился оператор приведения типов static_cast, который можно использовать для преобразования значения одного типа в значение другого типа. Этот способ наиболее безопасен и рекомендован в С++.

int main() {
  int x { 5 };
  int y { 4 };
  double d_result { static_cast<double>(x) / y };
}

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

Задание

В прошлом модуле мы писали программу, которая переводила евро в доллары, а доллары в рубли. На тот момент мы не знали типов данных с плавающей точкой и использовали автоматический вывод типов с помощью auto. Отрефакторите ее используя новые знания, используйте явное приведение типов.

Напишите программу, которая берет исходное количество евро, записанное в переменную euros_count, переводит евро в доллары и выводит на экран. Затем полученное значение переводит в рубли и выводит на новой строчке.

Пример вывода для 100 евро:

125.0
7500.0

Считаем, что:

  • 1 евро = 1.65 долларов
  • 1 доллар = 60 рублей
Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

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

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя 🤔

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

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно 🙄

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

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

Полезное


Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе