С++: int* / float* to char*, зачем получать другой результат, используя reinterpret_cast?

  • #P1# <блочная цитата> #P2#
  • float* в char* :

    float* pFloat = new float[1];
    pFloat[0] = 57; //assign the same value as before
    char* pChar = reinterpret_cast< char* >(pFloat);

Результат: pChar[0] = 'а';

Почему я получаю два разных результата?

Спасибо за вашу помощь.


person xtluo    schedule 12.10.2016    source источник
comment
потому что биты float и int означают разные вещи   -  person davidhigh    schedule 12.10.2016


Ответы (2)


И float, и int являются типами данных, которые (обычно) представлены четырьмя байтами:

b1 b2 b3 b4

Однако эти байты интерпретируются совершенно по-разному в двух типах - если бы они не интерпретировались, вряд ли были бы нужны два типа.

Теперь, если вы переинтерпретируете указатели на указатели на символы, результат указывает только на первый байт, так как это длина char:

b1 b2 b3 b4
^^
your char* points to here

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


Применение к вашему примеру:

Число 57 в формате с плавающей запятой (IEEE754 с одинарной точностью, 32 бита) представлено в битах как

01000010 01100100 00000000 00000000

Напротив, представление в 32-битном целочисленном формате

00000000 00000000 00000000 00111001

Здесь число, кажется, представлено в формате «с прямым порядком байтов», где самый важный байт (тот, который больше всего меняет значение int) идет первым. Как упомянул @Jean-FrançoisFabre, на вашем ПК все наоборот, но неважно. Для обоих преобразований я использовал этот сайт.

Теперь ваши указатели char* указывают на первый из этих 8-битных блоков соответственно. И очевидно, что они разные.

person davidhigh    schedule 12.10.2016

У вас есть это, потому что значения с плавающей запятой не используют ту же кодировку, что и целые значения (кодирование IEEE с мантисса + экспонента или что-то в этом роде)

Кроме того, я полагаю, что вы используете процессор с прямым порядком байтов, иначе ваш первый тест дал бы 0 (я имею в виду '\0').

person Jean-François Fabre    schedule 12.10.2016