ANSI C是否支持有符号/无符号位字段?

时间:2008-09-29 17:53:26

标签: c struct bit-fields

将位字段限定为有符号/无符号是否有意义?

9 个答案:

答案 0 :(得分:14)

标准的相关部分(ISO / IEC 9899:1999)是6.7.2.1#4:

  

位字段应具有合格或不合格的类型   _Bool的版本,signed int,unsigned int或其他一些实现定义的   类型。

答案 1 :(得分:8)

是。来自here的示例:

struct {
  /* field 4 bits wide */
  unsigned field1 :4;
  /*
   * unnamed 3 bit field
   * unnamed fields allow for padding
   */
  unsigned        :3;
  /*
   * one-bit field
   * can only be 0 or -1 in two's complement!
   */
  signed field2   :1;
  /* align next field on a storage unit */
  unsigned        :0;
  unsigned field3 :6;
}full_of_fields;

只有你知道你的项目是否有意义;通常情况下,它适用于具有多个位的字段,如果该字段可以有意义地为负数。

答案 2 :(得分:7)

将变量限定为有符号或无符号非常重要。编译器需要知道在比较和转换过程中如何处理变量。检查此代码的输出:

#include <stdio.h>

typedef struct
{
    signed s : 1;
    unsigned u : 1;
} BitStruct;

int main(void)
{
    BitStruct x;

    x.s = 1;
    x.u = 1;

    printf("s: %d \t u: %d\r\n", x.s, x.u);
    printf("s>0: %d \t u>0: %d\r\n", x.s > 0, x.u > 0);

    return 0;
}

输出:

s: -1    u: 1
s>0: 0   u>0: 1

编译器使用单个位1或0存储变量。对于有符号变量,最高有效位确定符号(高值被视为负值)。因此,签名变量在以二进制形式存储为1时,会被解释为负数。

扩展此主题,无符号两位数的范围为0到3,而带符号的两位数的范围为-2到1.

答案 3 :(得分:2)

我不认为安德鲁正在谈论单比特位字段。例如,4位字段:3位数字信息,1位用于符号。这完全有道理,但我承认我无法想出这样的情况。

更新:我不是说我不能想到多比特位字段的使用(在2400bps调制解调器时间里一直使用它们来尽可能地压缩数据进行传输),但我可以我想到了对有符号位字段的使用,尤其不是一个古怪的,明显的,对于读者来说是一个“aha”时刻。

答案 4 :(得分:2)

大多数情况下,ANSI-C提供有符号和无符号位字段。这是必需的。这也是编写IEEE-754浮点类型[[1] [5] [10]],[[1] [8] [23]]和[[1] [10] [53]的调试器覆盖的一部分。 ]。这在此类数据的机器类型或网络转换中非常有用,或者在通过链接(如视频卡纹理)发送之前将转换双倍(64位用于数学运算)转换为半精度(16位用于压缩)。

// Fields need to be reordered based on machine/compiler endian orientation

typedef union _DebugFloat {
   float f;
   unsigned long u;
   struct _Fields {
        signed   s :  1;
        unsigned e :  8;
        unsigned m : 23;
      } fields; 
   } DebugFloat;

埃里克

答案 5 :(得分:1)

是的,它可以。 C位字段基本上只是有限范围的整数。通常硬件接口将位组合在一起,以至于某些控制可以从例如-8到7,在这种情况下你需要一个有符号的位字段,或者从0到15,在这种情况下你需要一个无符号位 - 字段。

答案 6 :(得分:0)

答案 7 :(得分:0)

比特掩码签名类型因平台硬件和平台硬件而异,因为它可以处理来自移位等的溢出。

任何一半好的QA工具都会故意警告这种用法。

答案 8 :(得分:-4)

如果'bit'被签名,那么你有一个-1,0,1的范围,然后它变成一个三进制数字。我不认为这个标准缩写在这里是合适的,但可以进行有趣的对话:)