在这个例子中,我有一个由16位整数组成的结构。我将这些整数的某些部分读取到8位整数结构的组件中。然后我操纵8位整数,我想重新加载16位整数。下面的代码解释得更好一点。有什么想法吗?
struct SIXTEEN
{
uint16_t COMPONENT[8];
};
struct EIGHT
{
uint8_t COMP1;
uint8_t COMP2;
uint8_t COMP3;
};
void main()
{
//For the purposes of this example, assume *S is a pointer to
// this array
// 0000 AABB CC00 0000
struct SIXTEEN *S;
struct EIGHT E;
E.COMP1 = S -> COMPONENT[2]; //AA
E.COMP2 = S -> COMPONENT[3]; //BB
E.COMP3 = S -> COMPONENT[4]; //CC
//Let's manipulate these a little
struct EIGHT HOLD;
HOLD.COMP1 = E.COMP3; //HOLD.COMP1 has CC
E.COMP3 = E.COMP1; //E.COMP3 has AA
E.COMP2 = HOLD.COMP1; //E.COMP2 has CC
E.COMP1 = E.COMP2; //E.COMP1 has BB
//Now I want to pass the components of E into their new
//places in S so the array in S becomes:
// 0000 BBCC AA00 0000
//
// No idea, this certainly doesn't work:
// S -> COMPONENT[2] = E.COMP1;
}
这是一个较大项目中的一个问题,所以我没有摆脱指针S.
答案 0 :(得分:0)
至少有两种方法可以做你想要的,在这两种方式中你必须知道CPU的字节顺序。鉴于你基本上有两个结构:
struct SIXTEEN {uint16_t COMPONENT [8]; };
struct EIGHT {uint8_t COMP1 COMP2 COMP3};
您可以使用union
创建一种可以通过任何方式访问的类型,方法是复制该联合中的源数据,或者使用指针和类型转换。但我认为使用指针更简单。使用您的数据:
struct SIXTEEN * S; //指向" 0000 AABB CC00 0000"
struct EIGHT E;
做
E.COMP1 = S -> COMPONENT[2]; //AA
你没有获得AA,你得到第三元素的8个低位,即CC或CC旁边的00。
尝试改为:
uint8_t* ptr;
ptr = (uint8_t *) & S -> COMPONENT[1]; // points to AABB
E.COMP1 = *(ptr +0); // you get AA or BB
E.COMP2 = *(ptr +1); // you get the other one
E.COMP3 = *(ptr +2); // you get CC or 00
这种方式易于理解且易于修改,只需使用+ 0,+ 1等即可。完成对E.COMPx的操作后,您可以以相同的方式写回数据:
*(ptr +0) = E.COMP1;
您也可以使用数组表示法[];使用指针算法对我来说似乎更自我解释,但它的品味和最终结果可能完全相同。
答案 1 :(得分:-1)
看起来你想要用8位值覆盖16位int的一半。你可以这样做:
S->COMPONENT[2] = (S->COMPONENT[2] & 0xFF00) | E.COMP1;
使用您的变量名称是:
S->COMPONENT[2] = (S->COMPONENT[2] & 0x00FF) | E.COMP1 << 8;
或
{{1}}
取决于您是否要替换第一个或第二个字节。