联盟中的概念问题

Joe*_*oel 8 c c++ unions

我的代码是这样的

// using_a_union.cpp
#include <stdio.h>

union NumericType
{
    int         iValue;
    long        lValue;  
    double      dValue;  
};

int main()
{
    union NumericType Values = { 10 };   // iValue = 10
    printf("%d\n", Values.iValue);
    Values.dValue = 3.1416;
    printf("%d\n", Values.iValue); // garbage value
}
Run Code Online (Sandbox Code Playgroud)

在我尝试打印Values.iValue后,为什么会获得垃圾值Values.dValue = 3.1416?我以为内存布局会像这样.会发生什么Values.iValue,并 Values.lValue;当我给你的东西Values.dValue

Jam*_*lis 9

在a中union,所有数据成员重叠.您一次只能使用一个联合的一个数据成员.

iValue,lValuedValue所有占据相同的空间.

一旦你写信dValue,iValuelValue成员就不再可用:只有dValue可用.


编辑: 要解决以下注释:您不能写入联合的一个数据成员,然后从另一个数据成员读取.这样做会导致未定义的行为.(有一个重要的例外:您可以将C和C++中的任何对象重新解释为数组char.还有其他一些小的例外,例如能够将有符号整数重新解释为无符号整数.)您可以在C标准中找到更多(C99 6.5/6-7)和C++标准(C++ 03 3.10,如果我没记错的话).

有可能在某些时候在实践中"工作"吗?是.但除非你的编译器明确声明这种重新解释能够保证正常工作并指定它所保证的行为,否则你不能依赖它.

  • @drachstern:维基百科是正确的:使用联合进行对象重新解释是一种"常见的C编程习语".就C和C++语言而言,这样做也是错误的.写入联合的一个成员然后从另一个成员读取会导致_undefined behavior._您可以在C标准(C99 6.5/6-7和C++ 03 3.10)中阅读更多内容. (7认同)
  • @Ed Swangren:绝对错误.在C和C++中,读取union的任何组件显然是非法的,除了最后分配的组件.重复你所声称的是合法的很多次都不会成真.C和C++中的联合是"内存时间共享"的工具,而不是内存重新解释,即使它们经常被错误地用于后一目的. (3认同)
  • 我将引用维基百科.一个常见的C编程习惯用联盟来执行C++调用reinterpret_cast,通过分配一个联合的一个字段并从另一个字段读取,就像代码中所做的那样,它取决于值的原始表示. ......价值确实可用.这是使用`union`的主要优势之一. (2认同)

Ed *_* S. 7

因为浮点数的表示方式与整数不同.

所有这些变量占据相同的内存区域(双重占用更明显).如果您尝试将该双精度的前四个字节读作int,那么您将无法获得您的想法.您正在处理原始内存布局,您需要知道这些类型的表示方式.


编辑:我也应该添加(正如詹姆斯已经指出的那样)写入一个联合中的一个变量然后从另一个变量读取会调用未定义的行为并且应该避免(除非你将数据重新解释为一个char数组) ).