在c,bitfield struct或macro set中定义Flag并获取

时间:2015-12-29 11:40:08

标签: c

我使用嵌入式应用中的旧代码。我看到了两种不同的方法来设置标志位:

1-

#define BIT_0       0x1
#define BIT_1       0x2
#define BIT_2       0x4
#define BIT_3       0x8
#define Curr        BIT_0
#define Ready       BIT_1
#define Sleep       BIT_2
#define Wait        BIT_3

#define SET_BIT(var,bits) ((var) |= (bits))
#define CLEAR_BIT(var,bits) ((var) &= (~(bits)))

2-

struct PROCESS_FLAG
{
unsigned long Curr          :1;
unsigned long Ready         :1;
unsigned long Sleep         :1;
unsigned long Wait          :1;
};

union STATE_FLAG_REG
{
    unsigned long       All;
    struct STATE_FLAG   bit; 
}

在第一个定义用于获取和设置标志的宏中,我可以设置任何标志变量,如unsigned long flag并使用SET_BIT(flag,3)设置。

在第二个中,定义一个位域结构。

我有一些问题:

  1. 节省内存方面最好的方法是什么?
  2. CPU使用率方面的最佳方法是什么?
  3. 定义什么更合适?
  4. 注意:如果还有其他好方法,我很乐意了解更多。

2 个答案:

答案 0 :(得分:3)

  

1-节省内存方面最好的方法是什么?

没有一种最好的方法。这取决于您的使用情况。如果您的要求是在紧凑的内存系统上运行,您可以使用以下方式(或探索不同的方式):

一个。检查结构填充和对齐,重新排列构件以减小尺寸。 湾尽可能使用比特防范(如示例所示)。

或者您可以重新架构应用程序以尽可能少地使用内存。

  

2- CPU使用率方面的最佳方法是什么?

我认为通过CPU使用率意味着更少的CPU周期来读取结构。为此,保持结构与其填充的自然边界对齐。对于64位成员,它必须与64位内存对齐。

有关http://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/

的详细信息,请参阅结构填充和对齐
  

3-什么更适合定义?

无论编译器独立的方式,还是所有编译器或至少在您所针对的编译器中都可用的方式。

答案 1 :(得分:2)

  

节省记忆的最佳方法是什么?

没有区别:如果在基元内需要相同数量的位,则两种方法都会导致使用相同数量的内存。如果在struct中使用的位数多于拟合,int可能会使用额外的内存:如果在32位系统上需要40位,则struct可能大于5个字节

  

CPU使用率方面的最佳方法是什么?

这两者之间应该没有区别:没有神奇的方法来设置字节中的位,因此编译器会生成与宏完全相同的代码。

  

定义什么更合适?

由于位字段不能控制每个组件使用的确切位,因此只有当您必须访问特殊存储单元中硬件寄存器内的位时,才能使用第一种方法。在所有其他情况下,由于编码风格,决定取决于您。