为什么位域必须是整数?

时间:2013-09-10 23:38:09

标签: c integer bit-fields

我搜索的每本书,互联网上的每个教程以及SO上的每个q& a都说,位域必须是整数类型。这是为什么?

4 个答案:

答案 0 :(得分:4)

让我们问一下相反的问题:

  • 除了整数类型以外的哪些类型可以是位字段?

让我们回顾一下选项:

  1. void:不是价值 - 不会有用。
  2. 指针:但机器上的指针是固定大小的;你不能使用13位指针并期望它意味着什么。
  3. 结构,工会:但是你不是在处理简单的领域。
  4. 留下floatdouble,但这些都是精心设计的格式,您不能简单地使用double(或float)中的13位并期望它意味着什么。
  5. 因此,在您完成选项后,您将获得各种类型的整数:charshortintlong,{{ 1}}(以有符号和无符号形式)和long long。在这些选项中,标准指定您可以使用_Bool_Boolunsigned int和“普通”signed int

      

    ISO / IEC 9899:2011§6.7.2.1结构和联合类型说明符

         

    ¶5位字段的类型应为int_Boolsigned int或其他实现定义类型的限定或非限定版本。它是   实现 - 定义是否允许原子类型。

    'plain'unsigned int的行为是实现定义的:它可以是有符号或无符号的(大致类似'plain'int可以是有符号或无符号的)。因此,jxh的评论是正确的;我粗心地引用了太多类型(但我已经改写了一些东西,所以它没有那么误导)。

    请注意,位域的大多数行为都是实现定义的;除了符号之外,标准所指定的内容很少。

答案 1 :(得分:3)

整数是一组简单的加权位。他们很安静,不张扬,并且很容易被操纵。

几乎所有其他数据类型都受到某种解释:浮点数有两个部分,一个尾数和一个指数;字符串是......好吧,字节串(或Unicode值)。结构或指向数组的指针几乎可以代表任何东西。

作为一个例子,我可以轻松地将32位存储在一个整数中,并像这样检索它们(类似c的伪代码):

int GetBit(int field, int position)
{
    return field & 1 << position;
}

返回值为1或0时,存储在整数中。

字节(8位)是计算机系统中最低的公分母;计算机不允许您直接检索小于该数量的位数,并且现在大多数计算机以多字节数量检索位。 32位计算机检索......好,一次32位;一个32位整数,这是我们谈话开始的地方。

答案 2 :(得分:1)

语言中几乎存在所有其他类型(即非整数),主要是因为它们(或可以)由底层硬件直接支持。例如,这适用于指针类型和浮点算术类型。底层硬件立即对该类型的对象表示施加严格的格式和位大小要求。无法更改类型的位大小,并且仍然可以通过硬件直接支持它。

为了实现非整数类型的位字段这样的功能,实现必须为这些类型的位域版本提供软件级支持,即它必须模拟支持这种类型。这将是相当复杂和低效的,因此语言标准不将此作为特征包括在内。同时,对于整数类型,这并不难以高效实现。

答案 3 :(得分:0)

只是如何定义位字段,它们只能采用(某些)整数类型并被解释为整数值。

C.11§6.7.2.1¶5:

  

比特字段的类型应为_Boolsigned intunsigned int或其他实现定义类型的合格或不合格版本。它是实现 - 定义是否允许原子类型。

C.11§6.7.2.1¶10:

  

位字段被解释为具有由指定位数组成的有符号或无符号整数类型。如果将值0或1存储到类型为_Bool的非零宽度位字段中,则该字段的值应等于存储的值; _Bool比特字段的语义为_Bool

如果您想知道如何使用位字段,则通常使用位字段来创建比它所基于的更小的类型。而且,顾名思义,预计该类型的“变量”对于位操作很有用。并且位操作传统上和直观地使用整数类型执行。