Union struct生成垃圾和关于结构命名的一般问题

时间:2010-05-16 21:25:10

标签: c++ syntax struct unions

我前几天(今天)阅读了工会,并尝试了随附的示例功能。很容易,但结果是清楚和完全垃圾。

第一个例子是:

union Test
{ 
    int Int;

    struct
    {
        char byte1;
        char byte2;
        char byte3;
        char byte4;
    } Bytes;
};

其中假设int为32位。在我设置值Test t; t.Int = 7;然后cout

之后

cout << t.Bytes.byte1 << etc...

单个字节,没有任何显示,但我的电脑发出哔哔声。我觉得这很奇怪。

第二个例子给了我更糟糕的结果。

union SwitchEndian
{
    unsigned short word;

    struct
    {
        unsigned char hi;
        unsigned char lo;
    } data;
} Switcher; 

在我看来,看起来有点不稳定。无论如何,从它所描述的描述中,当我设置像

这样的值时,这应该自动将结果存储为高/小端格式。

Switcher.word = 7656;并使用cout << Switcher.data.hi << endl

进行通话

结果是ASCII图表中甚至没有定义的符号。不知道为什么那些人出现了。

最后,当我尝试更正示例时,我遇到了错误,而不是将Bytes放在结构的末尾,将其放在它旁边。而不是

struct {} Bytes;

我想写

struct Bytes {};

这给我一个很大的错误。这些有什么区别?由于C ++不能具有未命名的结构,因此当时看起来非常明显的是,位于开头和结尾的字节是命名它的东西。除了否,这不是我猜的全部答案。之后怎么样了?

2 个答案:

答案 0 :(得分:3)

哔哔声和奇怪的符号是因为您试图打印十进制数字的字符表示,在本例中为ASCII control characters。在您的第一个示例(哔哔声)中,您正在打印ASCII 7,即bell character

您可以将数据转换为int以打印出实际的十进制表示,例如:

cout << (int)t.Bytes.byte1 << endl << (int)t.Bytes.byte2 << endl << (int)t.Bytes.byte3 << endl << (int)t.Bytes.byte4 << endl;

您可以为第二个示例执行类似操作,以查看内存中这些unsigned char值的十进制表示。

区别的原因是coutbasic_ostream的类型对于各种基本类型都有operator<<的多次重载。

对于上一期,你得到了什么编译器错误?使用VS2008时,两个结构定义都可以正常编译。

答案 1 :(得分:2)

请注意,从技术上讲,从上次写入的成员以外的联合成员读取会导致未定义的行为,因此,如果您上次为Int分配了值,则无法从Bytes读取值{1}}(在StackOverflow上对此进行了一些讨论,例如,in this answer to another question)。

Chris Schmich gives a good explanation为什么你会听到哔哔声并看到控制角色,所以我不再重复了。

对于最后一个问题,struct {} Bytes;声明了一个名为Bytes的未命名结构的实例。它类似于说:

struct BytesType {};
BytesType Bytes;

除了你不能在其他地方引用BytesTypestruct Bytes {};定义了一个名为Bytes的结构,但没有声明它的实例。