我前几天(今天)阅读了工会,并尝试了随附的示例功能。很容易,但结果是清楚和完全垃圾。
第一个例子是:
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 ++不能具有未命名的结构,因此当时看起来非常明显的是,位于开头和结尾的字节是命名它的东西。除了否,这不是我猜的全部答案。之后怎么样了?
答案 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
值的十进制表示。
区别的原因是cout
,basic_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;
除了你不能在其他地方引用BytesType
。 struct Bytes {};
定义了一个名为Bytes
的结构,但没有声明它的实例。