1

我有以下类型定义:

typedef union{
unsigned int Entry;
struct {
    unsigned char EntryType;
    unsigned char EntryOffset[3];
};
} TLineDescriptor;

我也有以下使用类型:

TLineDescriptor LineDescriptor;
LineDescriptor.Entry = 40;
LineDescriptor.EntryType = 0x81;

sizeof(LineDescriptor)表明这个变量占用了 4 个字节的内存,起初我假设它保存了 int 或 struct。

cout << LineDescriptor.Entry << " " << LineDescriptor.EntryType << endl;

但是,上面的行打印了两个不同的值,即129 ü显然LineDescriptor.Entry是指保存值 0x81 的内存位置。我不确定 40 发生了什么。但很明显我的假设是错误的。有人可以正确解释和解释类型定义吗?理解它对我使用我找到的代码至关重要。

先感谢您。

4

4 回答 4

1

以这种方式打印EntryType:

cout << "0x" << hex << (unsigned)LineDescriptor.EntryType << endl;

你会看到 ü 是 0x81。

打印这个:

cout << LineDescriptor.Entry

是未定义的行为——因为联合中只有一个元素可以在某一时刻“活动”——而您的最后一项任务是对 EntryType。

但是,假设我们可以假设这实际上并不像 C++ 所希望的那样未定义,那么 129 来自:

Entry=40- 在您的系统上是二进制格式28 00 00 00(首先是不重要的字节)。

随着LineDescriptor.EntryType = 0x81;你改变了第一个字节:81 00 00 00- 所以你的条目打印输出现在是 129。

做这个实验,你会得到其他结果:

TLineDescriptor LineDescriptor;

LineDescriptor.Entry = 256;
LineDescriptor.EntryType = 0x81;

cout << LineDescriptor.Entry << " " << unsigned(LineDescriptor.EntryType) 
     << endl;
>> 385  129
于 2012-10-28T23:54:18.113 回答
1

实际上,这些不是不同的值。129是字符的字符代码üoperator <<处理和数据类型不同,第ostream一个打印数值,后一个打印字符值。intchar

所以,你对联合类型的理解是正确的。但是,请注意,在处理联合类型时,字节序可能是一个问题。例如,在 little-endian 机器上,EntryType将保存 的最低有效字节EntryEntryOffset数组中的其他字节。但在大端机器上,EntryType将保存最高有效字节。

于 2012-10-28T23:54:27.543 回答
1

您的假设没有错,联合将持有intstruct。当您将值分配给0x81EntryType 字段时,您之前分配给的整数Entry将被覆盖,这就是为什么当您cout使用两个字段时,您会得到相同的数量出现在两个字段中,一个作为 int (129),一个作为 char ( ü)。两者都有十六进制值0x81

于 2012-10-28T23:57:59.450 回答
1

它同时持有一个int和一个,并且两者占用相同的内存空间通过访问,您将这 4 个字节解释为. 如果通过 访问它,则将其解释为 4 s。structTLineDescriptor::Entryintstructunsigned char

LineDescriptor.Entry = 40;

这会将 4 个字节的int值设置为 40。在小端系统中,这意味着第一个字节为 40,其他 3 个字节为 0。

LineDescriptor.EntryType = 0x81;

这会将第一个字节设置为值 129 (0x81)。(在小端系统中,这意味着 的值Entry现在也为 129,前提是您将其余部分设置为 0)。

关于不同的输出:当您输出 EntryType 时,它​​显示为字符而不是数字。尝试:

cout << LineDescriptor.Entry << " " << static_cast<int>(LineDescriptor.EntryType) << endl;
于 2012-10-28T23:59:03.967 回答