为什么要强制转换为指针然后取消引用? [英] Why cast to a pointer then dereference?
问题描述
我正在看这个示例,该示例具有一个输出十六进制位模式以表示任意浮点的函数。
I was going through this example which has a function outputting a hex bit pattern to represent an arbitrary float.
void ExamineFloat(float fValue)
{
printf("%08lx\n", *(unsigned long *)&fValue);
}
为什么要使用fValue的地址,将其转换为无符号长指针,然后取消引用?不是所有的工作都等同于直接转换为无符号long吗?
Why take the address of fValue, cast to unsigned long pointer, then dereference? Isn't all that work just equivalent to a direct cast to unsigned long?
printf("%08lx\n", (unsigned long)fValue);
我尝试过,答案不一样,所以很困惑。
I tried it and the answer isn't the same, so confused.
推荐答案
(unsigned long)fValue
这会将 float
的值转换为 unsigned long $ c
This converts the float
value to an unsigned long
value, according to the "usual arithmetic conversions".
*(unsigned long *)&fValue
此处的目的是获取 fValue
的地址存储,假装此地址中没有 float
而是 unsigned long
,然后读取该无符号长
。目的是检查用于在内存中存储 float
的位模式。
The intention here is to take the address at which fValue
is stored, pretend that there is not a float
but an unsigned long
at this address, and to then read that unsigned long
. The purpose is to examine the bit pattern which is used to store the float
in memory.
原因:您可能无法通过指向与该对象的不兼容类型的指针来访问该对象类型。例如,兼容类型是( unsigned
) char
以及其他所有类型,或共享相同初始成员的结构(在这里谈到C)。有关详细信息,请参见6.5.7 N1570 (C11)列表(请注意,我对 compatible的使用与所引用的文本相比有所不同-范围更广。)
Reason: You may not access an object through a pointer to a type that is not "compatible" to the object's type. "Compatible" types are for example (unsigned
) char
and every other type, or structures that share the same initial members (speaking of C here). See §6.5/7 N1570 for the detailed (C11) list (Note that my use of "compatible" is different - more broad - than in the referenced text.)
解决方案:强制转换为 unsigned char *
,访问对象的各个字节,并从其中组合一个 unsigned long
:
Solution: Cast to unsigned char *
, access the individual bytes of the object and assemble an unsigned long
out of them:
unsigned long pattern = 0;
unsigned char * access = (unsigned char *)&fValue;
for (size_t i = 0; i < sizeof(float); ++i) {
pattern |= *access;
pattern <<= CHAR_BIT;
++access;
}
请注意(如@CodesInChaos所指出的),上述内容处理浮点值作为存储时,其最高有效字节在前(大端)。如果您的系统对浮点值使用不同的字节顺序,则需要对此进行调整(或重新排列 unsigned long
以上的字节,这对您来说更实际)。
Note that (as @CodesInChaos pointed out) the above treats the floating point value as being stored with its most significant byte first ("big endian"). If your system uses a different byte order for floating point values you'd need to adjust to that (or rearrange the bytes of above unsigned long
, whatever's more practical to you).
这篇关于为什么要强制转换为指针然后取消引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!