Приведение типа указателя к другому типу данных

#c #pointers #casting

#c #указатели #Кастинг

Вопрос:

что (float*) специально делается в случае g. Если я напишу, g = *amp;i; то вывод будет нормальным, т.Е. g = f, но если g = *(float*)amp;i; , то почему g = 0.0000???

 #include <stdio.h>

int main()
{

int i = 37;
int *p;
p = amp;i;
float f = i;
printf("%dn", i);
printf("%dn", p);
printf("%dn", *p);
float g = *(float*) amp;i;
printf("i = %d   f = %f   g = %f", i, f, g);
}
  

Ответ №1:

g = *amp;i то же самое, что g = i и является присвоением значения int в значение с плавающей точкой. Компилятор выполняет преобразование с помощью = оператора:

  1. Загрузите целое число, 2. преобразуйте в формат с плавающей запятой, 3. сохраните в формате float. Отлично работает помимо проблем с округлением.

Другая конструкция заключается в переосмыслении целочисленного указателя на указатель с плавающей точкой. Поскольку форматы данных различны для чисел с плавающей точкой (float обычно использует некоторые биты для мантиссы и некоторые биты для экспоненты) и для целых чисел (целые числа просто сериализуются в память 8 бит на 8 бит), компилятор просто копирует данные из источника в пункт назначения без какого-либо дополнительного преобразования, и вы не получаете то, что хотите.

Комментарии:

1. что такое «переосмысление целочисленного указателя на указатель с плавающей точкой» и чем это отличается от «присвоения int в float»

2. int float присвоение может потерять значение, если int значение >= 2**24.

3. отредактировано с более подробной информацией. @WeatherVane хорошо (я понимаю 24 лучше, чем 16).

4. Я отредактировал комментарий, первоначально сказал 16 бит, потому что не существует AFAIK 24-битного int типа.

5. вы имеете в виду: знак мантиссы равен 24 битам, показатель степени равен 8 битам: потеря точности имеет смысл.

Ответ №2:

В строке:

 g = *amp;i;
  

операторы * и amp; отменяют друг друга, поэтому результат такой, как если бы код был:

 g = i;
  

Строка:

 float g = *(float*) amp;i;
  

вызывает неопределенное поведение, поскольку типы int и float несовместимы.

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

Приведение к указателю — неправильный способ интерпретации битов другого типа.