Основы программирования на С++ для начинающих

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

Преобразование типов в С++ достаточно древняя, или точнее классическая операция. Если вкратце и по-русски: Преобразование типа – это указание компьютеру считать некий набор байтов целым или вещественным. Или указателем на определенный класс.

Вообще, чтобы понять преобразование типов нужно учитывать механизм и структуру переменных. К примеру, переменных целого типа несколько: короткий INT, intдолго INT, не считая беззнаковые. И компьютер размещает для них разное количество ячеек памяти (байт): 1, 2 и 4 соответственно. Преобразование в рамках таких типов одного класса называется стандартным преобразованием.  в:

Сделает следующее: возьмет два младших байта из переменной «а», и просто пересадит их в два байта переменной «b». Поскольку значение в а (единица) вполне себе помещается в эти два байта, программа даст правильный результат, а С++ не будет против такого преобразования.

Почему нужно учитывать размер переменной при преобразовании?

Что будет если поместить в переменную «а» число 123456789? Оно прекрасно уместится в 4 байта типа int, но в 2 байта типа короткий INT оно уже не попадает. Слишком большое. С , как и полагается, просто обрежет это длинное число, взяв из него только хвост, и поместит в переменную «b». Получим естественно ерунду. Причем с минусом, если вывести ее на экран. Преобразование из переменной, которая занимает большее количество байт в памяти не будет правильным. Если преобразовывать наоборот из short в long к примеру таких проблем не будет, поскольку байтов в переменной-получателе больше, и места для данных которые хранитshort вполне хватает.

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

Что касается преобразования типов вещественного, этим занимается математический сопроцессор. Тут уже не просто байты перегоняются из ячеек в ячейку, а выполняются специальные команды, которые конвертируют целое в тип вещественного с мантиссой и экспонентой, как полагается, и возвращают значение. Это нельзя назвать преобразованием, это именно конвертация.В любом случае, этим будет заниматься сам процессор.

В данном примере математический сопроцессор преобразует вещественное в целое, и загонит в переменную, а потом сделает обратную операцию: загонит целое в свой специальный регистр (называется ST), и уже после из него достанет вещественное с целой частью, равной той, что в переменной “а”.

Если же нужно преобразовать из вещественного double (8 байт) в float (4 байта), то тут таких проблем, как с целыми не будет. Математический сопроцессор просто округлит вещественное до значения, умещающегося в 4 байта, что не приведет к неправильному значению:

Результатом все равно будет число  1.234568e+18, что означает 1.2-с хвостиком в 18-й степени. Другое дело, что в “a” уже будет округленное число до 6-го знака после запятой, а не 1.234567891234566e+18. В целом для неточных вычислений это не мешает, но рекомендуется в программе использовать вещественные одного типа, чтоб не происходило такого вот округления.

Помимо преобразования типа есть такое понятие как приведение типа.

Наглядность приведения типа можно показать таким примером:

Если преобразование – это решение С++ (а точнее компилятора), в какой тип приводить, то приведение использует тип, жестко указанный программистом. В данном примере программист говорит компилятору, что нужно преобразовывать именно в int, а не в short int. Ведь 25 помещается и в int и в short, что выберет компилятор программист может и не знать.

В быту такие преобразования типов вообще-то редкие. Да и не нужные. Идеология программирования в бытовых условиях намекает избегать таких выкрутасов, поскольку они могут оказаться граблями (как в примере выше при преобразовании целых), поэтому приведение типов в С++ не стоит использовать повсеместно.

:) Спасибо за эту статью её автору Stilet – супер модератору форума программистов ProgrammersForum.

7 thoughts on “Преобразование типов

  1. Этот урок совсем не понятный, переписать бы эту статейку на более понятный язык:(

    1. Более понятный в каком плане?
      Преобразование типов ведь работает на низком уровне и вообще зависит очень сильно от оптимизации компилятора.
      Более того преобразование типов очень обширная область и зависит (может зависеть) от самих задач, где применяется преобразование.

      1. > Преобразование типов ведь работает на низком уровне
        1. Преобразования типов вообще не “работают” – никаких действий не производится, мы просто указываем рассматривать элемент данных в формате какого-то из типов данных.

        > вообще зависит очень сильно от оптимизации компилятора.
        2. Никак не зависит вообще от компилятора. Типизация – это сугубо синтаксическое понятие C++ – для контроля и проверок в тексте. После компиляции вся информация о типах полностью теряется.

  2. Тип объекта данных (это как существительное в языке) определяет какие действия (глагол в языке) можно применять к объекту.
    Например, тип – “яблоко”, его можно: съесть, засушить и т.д.
    Но если вы преобразуете его в тип “мяч”, то ним можно играть в футбол … но его уже нельзя съесть.

    1. Это ложное утверждение, поскольку после приведения типа значение своих свойств не меняет.

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

      1. > поскольку после приведения типа значение своих свойств не меняет.

        Вы пишете ерунду, не смущайте юношество…
        unsigned long ul = 1234;
        – преобразуем:
        char *pc = ++(char*)ul;
        сколько станет? … правильно ;-) = 1235
        – преобразуем:
        short *ps = ++(short*)ul;
        сколько станет? … правильно ;-) = 1236
        – преобразуем:
        uint32_t* pi = ++(uint32_t*)ul;
        сколько станет? … правильно ;-) = 1238
        и т.д.

  3. 1) Преобразование типов на примере целого и вещественного может работать на уровне процессора и его математического модуля.

    2) Типизация это не просто “понятие”, и уж точно не только для контроля, которого в Си как кот наплакал. И даже если информация о типах не хранится в экзешнике, само значение, обрабатываемое процессором однозначно указывает на его тип будь то указатель на ASCIIZ или вещественное, или указатель на интерфейс.

Добавить комментарий для Olej Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *