Преобразование типов в С++ достаточно древняя, или точнее классическая операция. Если вкратце и по-русски: Преобразование типа – это указание компьютеру считать некий набор байтов целым или вещественным. Или указателем на определенный класс.
Вообще, чтобы понять преобразование типов нужно учитывать механизм и структуру переменных. К примеру, переменных целого типа несколько: короткий INT, int, долго INT, не считая беззнаковые. И компьютер размещает для них разное количество ячеек памяти (байт): 1, 2 и 4 соответственно. Преобразование в рамках таких типов одного класса называется стандартным преобразованием. в:
1 2 3 | int a = 1; short int b = 2; b = a; |
Сделает следующее: возьмет два младших байта из переменной «а», и просто пересадит их в два байта переменной «b». Поскольку значение в а (единица) вполне себе помещается в эти два байта, программа даст правильный результат, а С++ не будет против такого преобразования.
Почему нужно учитывать размер переменной при преобразовании?
Что будет если поместить в переменную «а» число 123456789? Оно прекрасно уместится в 4 байта типа int, но в 2 байта типа короткий INT оно уже не попадает. Слишком большое. С , как и полагается, просто обрежет это длинное число, взяв из него только хвост, и поместит в переменную «b». Получим естественно ерунду. Причем с минусом, если вывести ее на экран. Преобразование из переменной, которая занимает большее количество байт в памяти не будет правильным. Если преобразовывать наоборот из short в long к примеру таких проблем не будет, поскольку байтов в переменной-получателе больше, и места для данных которые хранитshort вполне хватает.
Это нужно знать. Преподаватели частенько ловят студентов на таком фокусе, специально давая в методичке подобный подводный камень с переменными плохо совместимыми друг с другом по размеру.
Что касается преобразования типов вещественного, этим занимается математический сопроцессор. Тут уже не просто байты перегоняются из ячеек в ячейку, а выполняются специальные команды, которые конвертируют целое в тип вещественного с мантиссой и экспонентой, как полагается, и возвращают значение. Это нельзя назвать преобразованием, это именно конвертация.В любом случае, этим будет заниматься сам процессор.
1 2 3 4 5 | int a = 123; float b = 25.14; a = b; b = a; cout << a << ' ' << b << endl; |
В данном примере математический сопроцессор преобразует вещественное в целое, и загонит в переменную, а потом сделает обратную операцию: загонит целое в свой специальный регистр (называется ST), и уже после из него достанет вещественное с целой частью, равной той, что в переменной “а”.
Если же нужно преобразовать из вещественного double (8 байт) в float (4 байта), то тут таких проблем, как с целыми не будет. Математический сопроцессор просто округлит вещественное до значения, умещающегося в 4 байта, что не приведет к неправильному значению:
1 2 3 4 | float a; double b = 1234567891234565555.25; a = b; cout << a << '\n' << b; |
Результатом все равно будет число 1.234568e+18, что означает 1.2-с хвостиком в 18-й степени. Другое дело, что в “a” уже будет округленное число до 6-го знака после запятой, а не 1.234567891234566e+18. В целом для неточных вычислений это не мешает, но рекомендуется в программе использовать вещественные одного типа, чтоб не происходило такого вот округления.
Помимо преобразования типа есть такое понятие как приведение типа.
Наглядность приведения типа можно показать таким примером:
1 2 3 4 | int a; float b = 25.14; a = (int)b; cout << a << ' ' << b; |
Если преобразование – это решение С++ (а точнее компилятора), в какой тип приводить, то приведение использует тип, жестко указанный программистом. В данном примере программист говорит компилятору, что нужно преобразовывать именно в int, а не в short int. Ведь 25 помещается и в int и в short, что выберет компилятор программист может и не знать.
В быту такие преобразования типов вообще-то редкие. Да и не нужные. Идеология программирования в бытовых условиях намекает избегать таких выкрутасов, поскольку они могут оказаться граблями (как в примере выше при преобразовании целых), поэтому приведение типов в С++ не стоит использовать повсеместно.
:) Спасибо за эту статью её автору Stilet – супер модератору форума программистов ProgrammersForum.
Этот урок совсем не понятный, переписать бы эту статейку на более понятный язык:(
Более понятный в каком плане?
Преобразование типов ведь работает на низком уровне и вообще зависит очень сильно от оптимизации компилятора.
Более того преобразование типов очень обширная область и зависит (может зависеть) от самих задач, где применяется преобразование.
> Преобразование типов ведь работает на низком уровне
1. Преобразования типов вообще не “работают” – никаких действий не производится, мы просто указываем рассматривать элемент данных в формате какого-то из типов данных.
> вообще зависит очень сильно от оптимизации компилятора.
2. Никак не зависит вообще от компилятора. Типизация – это сугубо синтаксическое понятие C++ – для контроля и проверок в тексте. После компиляции вся информация о типах полностью теряется.
Тип объекта данных (это как существительное в языке) определяет какие действия (глагол в языке) можно применять к объекту.
Например, тип – “яблоко”, его можно: съесть, засушить и т.д.
Но если вы преобразуете его в тип “мяч”, то ним можно играть в футбол … но его уже нельзя съесть.
Это ложное утверждение, поскольку после приведения типа значение своих свойств не меняет.
Впрочем не вижу смысла спорить – Отладчик все рассудит, кто захочет с его помошью вполне узнает истину.
> поскольку после приведения типа значение своих свойств не меняет.
Вы пишете ерунду, не смущайте юношество…
unsigned long ul = 1234;
– преобразуем:
char *pc = ++(char*)ul;
сколько станет? … правильно ;-) = 1235
– преобразуем:
short *ps = ++(short*)ul;
сколько станет? … правильно ;-) = 1236
– преобразуем:
uint32_t* pi = ++(uint32_t*)ul;
сколько станет? … правильно ;-) = 1238
и т.д.
1) Преобразование типов на примере целого и вещественного может работать на уровне процессора и его математического модуля.
2) Типизация это не просто “понятие”, и уж точно не только для контроля, которого в Си как кот наплакал. И даже если информация о типах не хранится в экзешнике, само значение, обрабатываемое процессором однозначно указывает на его тип будь то указатель на ASCIIZ или вещественное, или указатель на интерфейс.
А как допустим мне конвертировать число указанное в типе данных char в int?
Например:
int a;
char b = ‘7’;
a = (int)b;
cout << a;
У меня выводит число 55 почему-то
Я посмотрел видео про таблицу ASCII и понял откуда эти числа появляются при конвертации из char в int