用8位整数替换16位整数的一部分

时间:2017-03-19 02:38:33

标签: c pointers struct integer

在这个例子中,我有一个由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.

2 个答案:

答案 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}}

取决于您是否要替换第一个或第二个字节。