我需要编写一个使用Union结构来设置int的位的C程序

时间:2017-09-28 20:39:10

标签: c bit-manipulation

以下是说明:

为uint16_t整数定义联合数据结构WORD_T,以便可以通过三种方式将值分配给WORD_T整数: (1)要将值分配给整数的每个位, (2)将值分配给整数的每个字节, (3)直接将值赋给整数。

我知道我需要对第一个结构做一些不同的事情,但总的来说我很丢失。这就是我所拥有的:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>

#define BIT(n) (1 << n)
#define BIT_SET(var, mask) (n |= (mask) )
#define BIT_CLEAR(var, mask) (n &= ~(mask) )
#define BIT_FLIP(var, mask) (n ^= (mask) )

union WORD_T{
    struct{
        uint16_t integerVar:16

    };
    struct{
        unsigned bit1:0;
        unsigned bit2:0;
        unsigned bit3:0;
        unsigned bit4:0;
        unsigned bit5:0;
        unsigned bit6:0;
        unsigned bit7:0;
        unsigned bit8:0;
        unsigned bit9:0;
        unsigned bit10:0;
        unsigned bit11:0;
        unsigned bit12:0;
        unsigned bit13:0;
        unsigned bit14:0;
        unsigned bit15:0;
        unsigned bit16:0;
    };

    void setIndividualBit(unsigned value, int bit) {
        mask = BIT(value) | BIT(bit);
        BIT_SET(n, mask);
    }
};

2 个答案:

答案 0 :(得分:3)

最明显的问题是:0表示&#34;零位的位域&#34;这没有任何意义。您应该将其更改为1,然后您可以通过the_union.the_struct.bit1 = 1;等代码分配单个位。

此格式是您编写的位集/清除宏的替代方法。

你的工会应该是这样的:

typedef union
{
  uint16_t word;
  uint8_t  byte[2];
  struct{
     uint16_t bit1:1;
  ...

<强> 然而 即可。这是一个非常糟糕的主意,你的老师应该知道比提供这样的任务更好。 C中的位字段是一堆蠕虫 - 它们的标准很难指定。问题:

  • 您无法知道哪个位是MSB,但未定义。
  • 您无法知道某处是否存在填充位/字节。
  • 您甚至无法使用uint16_tuint8_t,因为位字段仅指定用于int

等等。此外,您必须处理字节顺序和对齐。见Why bit endianness is an issue in bitfields?

基本上,使用这样的位字段的代码将严重依赖于特定的编译器。它将是完全不可携带的。

可以通过删除位字段并在uint16_t上使用按位运算符来避免这些问题的所有,就像在宏中一样。仅使用按位运算符,您的代码将变为确定性且100%可移植。您甚至可以通过使用位移来使用它们来躲避结束。

答案 1 :(得分:2)

这是工会定义:

union WORD_T
{
    uint16_t word;

    struct
    {
        uint8_t byte0;
        uint8_t byte1;
    };

    struct
    {
        uint8_t bit0:1;
        uint8_t bit1:1;
        uint8_t bit2:1;
        uint8_t bit3:1;
        uint8_t bit4:1;
        uint8_t bit5:1;
        uint8_t bit6:1;
        uint8_t bit7:1;
        uint8_t bit8:1;
        uint8_t bit9:1;
        uint8_t bit10:1;
        uint8_t bit11:1;
        uint8_t bit12:1;
        uint8_t bit13:1;
        uint8_t bit14:1;
        uint8_t bit15:1;
    };
};

要分配给各个组件,请执行以下类似操作:

union WORD_T data;

data.word = 0xF0F0; // (3) Assign to entire word

data.byte0 = 0xAA; // (2) Assign to individual byte

data.bit0 = 0; // (1) Assign to individual bits
data.bit1 = 1;
data.bit2 = 1;
data.bit2 = 0;