0

前几天(今天)我读到了关于工会的文章,并尝试了它们附带的示例函数。很容易,但结果是清晰而彻底的垃圾。

第一个例子是:

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++ 不能有未命名的结构,在当时,很明显,位于开头和结尾的字节就是命名它的东西。除了不,这不是我猜的全部答案。之后怎么样了?

4

2 回答 2

3

哔哔声和奇怪的符号是因为您正在尝试打印十进制数字的字符表示,在这种情况下是ASCII 控制字符。在您的第一个示例(哔声)中,您正在打印 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内存中这些值的十进制表示。

不同的原因是 , 的类型cout对于各种基本类型basic_ostream有多个重载。operator<<

对于您的最后一个问题,您遇到了什么编译器错误?使用 VS2008 时,这两个结构定义对我来说都编译得很好。

于 2010-05-16T21:38:57.313 回答
2

请注意,从技术上讲,从最后写入的成员以外的联合成员中读取会导致未定义的行为,因此,如果您最后将值分配给Int,则无法从中读取值Bytes(在 StackOverflow 上有对此的一些讨论,例如,在这个对另一个问题的回答中)。

Chris Schmich 很好地解释了为什么您会听到哔哔声并看到控制字符,所以我不会重复。

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

struct BytesType {};
BytesType Bytes;

除了你不能参考BytesType其他地方。 struct Bytes {};定义了一个名为Bytes但没有声明它的实例的结构。

于 2010-05-16T21:45:50.607 回答