#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 в значение с плавающей точкой. Компилятор выполняет преобразование с помощью =
оператора:
- Загрузите целое число, 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.
Приведение к указателю — неправильный способ интерпретации битов другого типа.