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
", *(unsigned long *)&fValue);
}
为什么取 fValue 的地址,转换为无符号长指针,然后解引用?所有这些工作不都等同于直接转换为 unsigned 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
", (unsigned long)fValue);
我试过了,答案不一样,很困惑.
I tried it and the answer isn't the same, so confused.
推荐答案
(unsigned long)fValue
根据通常的算术转换",这会将 float
值转换为 unsigned long
值.
This converts the float
value to an unsigned long
value, according to the "usual arithmetic conversions".
*(unsigned long *)&fValue
这里的目的是取fValue
存储的地址,假设没有float
而是unsigned long
这个地址,然后读取那个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) 列表(请注意,我对兼容"的使用与引用文本中的不同 - 更广泛.)
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).
这篇关于为什么转换为指针然后取消引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么转换为指针然后取消引用?
基础教程推荐
- 从 std::cin 读取密码 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01