如何将数组添加到位域结构?

时间:2015-09-08 15:47:17

标签: c struct bit-fields

我尝试在结构中使用某些值的字段,这些值只需要一个或两个位而不是整个字节。

我的代码是:

struct s_rdata {
    signed int      p0:28; 
    signed int      p1:28; 
    signed int      p2:28; 
    unsigned int    d0:17; 
    unsigned int    d1:17; 
    unsigned int    d2:17; 
    unsigned char   data1:1; 
    unsigned char   data2:1; 
} rdata; 

因此,您可能会看到名为p0 - p2d0 - d2data1 - data2的变量。

我现在想把它们放在一个数组中。但是,这些行都不起作用:

signed int p[3]:28; 
signed int p:28[3]; 

我不能将数组添加到位域列表中,signed int数组每个条目只需28位吗?

2 个答案:

答案 0 :(得分:4)

不,您不能拥有一个位域数组,也不能拥有一个基本类型为数组类型的位域。后者甚至没有意义。前者会适得其反,因为你首先会失去通过使用位域获得的空间效率。

您可以拥有一个struct的数组,其中包含一个位域成员:

struct container {
  signed int bitfield:7;
} array[3];

但同样,您将失去与使用位域相关的任何空间效率。

您可以创建任何struct类型的数组,当然,包括具有多个位域成员的数组。在这种情况下,您可以在单个结构中实现一些内部空间效率,但是您可能会在每个结构的末尾看到填充,这会降低阵列的整体空间效率。

最终,除非您的程序的内存消耗过多,否则我强烈建议您忘记位域。它们会使你的生活变得复杂,以获得不确定的不确定性,并且这种增益可能会被性能下降(不确定的重要性和重要性)所抵消。

如果您最终确定该程序确实使用了太多内存,那么请确保测试您所做的任何更改,以了解它产生了多少改进,以及成本。

答案 1 :(得分:0)

我同意@ John对空间效率低下的评估,但尽管如此,这里有一个包含struct array中位域内容的想法:

typedef struct
{
  int A : 16;
  int B : 16;
} Struct1;

typedef struct
{
  Struct1 B;//bitfield struct
  int array[10];//combined with array (of any legal type)
}

以下是使用位结构的内容填充数组的示例:

typedef struct {
    signed int      p0:28; 
    signed int      p1:28; 
    signed int      p2:28; 
    unsigned int    d0:17; 
    unsigned int    d1:17; 
    unsigned int    d2:17; 
    unsigned char   data1:1; 
    unsigned char   data2:1; 
} RDATA; 


typedef struct {
    int A[3];
    unsigned int B[3];
    unsigned char C[2];
} ARRAY;

RDATA rdata = {//initialize instance of RDATA with data
    28,
    28,
    28,
    17,
    17,
    17,
    1,
    1
};

int WriteToArray(ARRAY *a);

int main(void)
{
    ARRAY a;
    WriteToArray(&a);//populate array with RDATA values

    //ARRAY is now populated with bitfield values;
    a.A[0];
    a.A[1];
    //and so on

    return 0;
}

WriteToArray(ARRAY *a)
{
    a->A[0]=rdata.p0;//using values initialized above
    a->A[1]=rdata.p1;
    a->A[2]=rdata.p2;
    a->B[0]=rdata.d0;
    a->B[1]=rdata.d1;
    a->B[2]=rdata.d2;
    a->C[0]=rdata.data1;
    a->C[1]=rdata.data2;
    return 0;
}

您还可以尝试使用 pragma pack 语句来查看对空间的影响,但请参阅帖子下的@ John的评论,以了解有关pragma和pragma的其他注意事项。间距。