Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 理解联合体的记忆内容_C++_C_Memory_Memory Management_Unions - Fatal编程技术网

C++ 理解联合体的记忆内容

C++ 理解联合体的记忆内容,c++,c,memory,memory-management,unions,C++,C,Memory,Memory Management,Unions,假设我这样定义一个并集: #include <stdio.h> int main() { union u { int i; float f; }; union u tst; tst.f = 23.45; printf("%d\n", tst.i); return 0; } #包括 int main(){ 联合大学{ int i; 浮动f; }; 工会联合会; tst.f=23.45; printf

假设我这样定义一个并集:

#include <stdio.h>

int main() {
    union u {
        int i;
        float f;
    };
    union u tst;
    tst.f = 23.45;

    printf("%d\n", tst.i);

    return 0;
}
#包括
int main(){
联合大学{
int i;
浮动f;
};
工会联合会;
tst.f=23.45;
printf(“%d\n”,tst.i);
返回0;
}
有人能告诉我存储
tst
的内存是什么样子的吗


我试图理解这个程序产生的输出。

这取决于实现(编译器、操作系统等),但如果需要,您可以使用调试器实际查看内存内容

例如,在我的MSVC 2008中:

0x00415748  9a 99 bb 41
是内存内容。从左侧的LSB读取(Intel,little endian机器),这是0x41bb999a,实际上是1102813594

但是,通常情况下,整数和浮点存储在相同的字节中。根据访问union的方式,可以获得这些字节的整数或浮点解释。内存空间的大小同样取决于实现,尽管它通常是与某个固定边界对齐的最大组成部分


为什么在你(或我)的案例中会有这样的价值?您应该阅读有关浮点数表示的内容(请查阅ieee 754)

结果取决于编译器实现,但对于大多数x86编译器,浮点和int的大小相同。维基百科有一个相当不错的32位浮点布局图,可以帮助解释
1102813594

如果将int打印为十六进制值,则更容易计算

printf("%x\n", tst.i);

使用并集,两个变量从同一内存位置开始存储。浮点以IEEE格式存储(不记得标准编号,您可以查阅[编辑:如其他人所指出的,IEEE 754])。但是,它将是一个标准化的2的补码(尾数总是在0和10之间,指数可以是任何值)浮点数

您正在获取该数字的前4个字节(同样,您可以查找浮点所占用的16或32位中的哪些位,不记得了)。所以它基本上没有任何意义,作为int也没有用处。也就是说,除非你知道为什么你想做这样的事情,但是通常,float和int组合不是很有用


而且,不,我不认为它是实现定义的。我相信标准规定了浮点的格式。

在联盟中,成员将共享相同的内存。这样我们就可以得到浮点值作为整数值

浮点数格式将不同于整数存储。这样我们就可以通过联合来理解差异

例如: 如果我将12个整数值存储在(32位)中。我们可以将这个12值作为浮点格式


它将以有符号(1位)、指数(8位)和有效精度(23位)的形式存储。

我编写了一个小程序,显示将32位浮点的位模式保留为32位整数时会发生什么。它提供与您体验的输出完全相同的输出:

#include <iostream>

int main()
{
    float f = 23.45;
    int x = *reinterpret_cast<int*>(&f);

    std::cout << x; // 1102813594
}
#包括
int main()
{
浮动f=23.45;
int x=*重新解释铸件(&f);

std::cout-Hmm,而不是“最大的组成部分”,你可能指的是最严格的。@rogue:根据标准——“工会的规模足以容纳其最大的成员”iirc,来自k&r,“尽管机器各不相同,但每台机器都有一种限制性最强的类型:如果限制性最强的类型可以存储在特定的地址,则所有其他类型也可以。"但我想你是对的,因为标准总是正确的,1的方式是任意的。“无赖,你说的是对齐,所以你们两个都是对的。联盟应该正确地对齐所有成员,通常是由最严格的限制,并且它应该足够大,最大的成员。C++标准不强制IEEE-74C。符合FP表示法——但鼓励使用std::numeric_limits::is_iec559成员(相当于IEEE-754)。此外,非规范化数字也是有效的。您可能比我记得更清楚。谢谢。C也是这样吗?