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 рублей
Упражнение не проходит проверку — что делать? 😶
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя 🤔
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно 🙄
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.