gpt4 book ai didi

c++ - union 做了什么来帮助将字节数组转换为不同的类型,例如此 c++ 代码中的单词?

转载 作者:行者123 更新时间:2023-11-28 02:41:35 58 4
gpt4 key购买 nike

我正在查看一些 C++ 代码,我想了解 union 正在做什么来帮助将字节数组转换为不同的类型,例如单词。至少那是我认为正在发生的事情。我真正想要的是弄清楚这段代码的用途,但我想我理解了一些。

我的研究让我有了一些零碎的理解,但我不确定我是否能正确看待全局。

假设我有一个定义为的 union :

typedef union _BYTE_TO_WORD {
BYTE b[2];
WORD w;
short s;
} BYTE_TO_WORD;

请注意,这里的字节是 8 位,Word 是一个无符号短整型,两个短整型(有符号和无符号)都是 16 位。

然后如果在主代码中我有一个结构会发生什么......

byte[] data = someData;

struct TWO_WORDS {
_BYTE_TO_WORD word1;
_BYTE_TO_WORD word2;
}*theWordsIWant = (struct TWO_WORDS*)&data;

我认为上面的代码将两个字节的数据放入 word1,然后将接下来的两个字节的数据放入 word2。有了关于 union 和结构的所有信息,我似乎无法确定解释这段代码的搜索。如果我在这里错了,请告诉我。

因此,如果我对此是正确的,那么 word1 或 word2 中的内容就有值(value)。所以我的研究表明 word1 中会有一个字节数组,因为它只能包含一个值。

翻译必须是我们执行此操作的代码的另一部分(我还没有找到)(假设我可以将字节转换为 WORD):

theWordsIWant.w = (WORD)theWordsIWant.b;

那么额外的问题是,当你可以简单地将它转换为一个不同的变量时,为什么要为 union 带来所有这些麻烦?

WORD w = (WORD)theWordsIWant.b;

也许真正发生的是代码将“转换到任何东西的指针”,正如这里的一个答案所暗示的那样(How to convert from byte array to word array in c)。

我很确定我遗漏了一些东西,无论是这样做的动机还是它的工作方式。但话又说回来,也许我真的明白了?我不知道。你告诉我。

最佳答案

这个声明:

theWordsIWant.w = (WORD)theWordsIWant.b;

不会产生从 b 加载两个字节的效果并将它们变成一个词。自 b是一个数组,表达式theWordsIWant.b产生指向第一个元素的指针,BYTE *指针。它的值是两个字符的地址,因此您将字节的地址转换为类型 WORD ,而不是字节本身的内容。

union 让你免于做的事情(以可移植性为代价)是这种类型的代码:

WORD w = ((WORD) b[1] << 8) | b[0];

union 会使用与此类代码非常相似的逻辑来执行此操作:

WORD w = *(WORD *) b;  // rather than: WORD w = (WORD) b;

即:将指向字节的指针转换为 WORD *指针(指向 WORD 的指针),然后取消引用它以将两个字节作为单个 WORD 同时访问.我们在这里所做的是使用指针转换来进行类型双关:我们正在创建 b[0]别名 View b[1]就好像它们是 WORD 类型的单个对象一样.

union C 和 C++ 中的类型以声明方式执行此操作。 union 类似于结构,除了所有成员都在偏移量 0 处:它们重叠。如果我们总是只访问我们最后存储在那里的那个成员, union 就有了明确定义的、可移植的行为。如果我们给 w 赋值, 然后访问 w , 行为是没有争议的。使用 union ,我们可以分配给成员 b[0]b[1]然后检索 w .然后行为是“未指定的”(在 C 中,从 C99 标准开始)。

在 C++ 中,使用 union 来进行类型双关并没有比使用指针用于相同目的更明确;这是未定义的行为。此类代码是否有效的任何方面都归功于实现。

关于c++ - union 做了什么来帮助将字节数组转换为不同的类型,例如此 c++ 代码中的单词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25797947/

58 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com