c - 在位域中声明不同的数据类型有什么用?

标签 c bit-fields

位域的一个典型用途是声明一个小于 8 位的节省空间的变量。我不明白的是将这些位声明为 short、int、long、bool 等的值(value)。例如

typedef struct{
    int first:3,
    short second:3,
    char third:3
    } somestruct;

在上面的例子中,所有 3 个变量,即 first、second 和 third 都是 3 位长。将变量首先声明为 int,第二个声明为 short,第三个声明为 char 的值是什么?

或者,为什么连数据类型都需要?我应该能够将以上声明为

typedef struct{
    first:3,
    second:3,
    third:3
    } modifiedstruct;

修改后的结构假定变量 first、second 和 third 没有数据类型。将 3 位解释为字符、数字或 float 的责任应该由其他某事负责。

linux 上的 gcc 和 g++ 都允许上述行为。

最佳答案

实际上,C 标准只允许位域是 signed int 或 unsigned int 类型(以及 C99 中的 _Bool)。如果您可以在其中输入 short、long 或 char,那就是编译器扩展。

至于为什么,主要是签名。考虑:

struct {
   int s: 3;
   unsigned u: 3;
} bf;

bf.s = 7;
bf.u = 7;

这两个位域都是一。但是,C 保留符号,因此:

(int)bf.s == -1    // Because signed conversions preserve the sign bit
bf.s >> 1 == -1    // So do right shifts on signed values

同时:

(int)bf.u == 7     // Because the source is unsigned and so just a series of bits
bf.u >> 1 == 3     // Unsigned right shifts are just moving bits around as well

对于允许使用 char 的编译器,可能也是同样的想法。 char 的默认符号是实现定义的,因此如果您希望位域的符号与编译器的 char 的符号相匹配,您可以将其定义为 char。

关于c - 在位域中声明不同的数据类型有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9213622/

相关文章:

c - 用什么代替 C 中的魔数(Magic Number)

c - 如何纠正代码中的错误以查找 Euler's Totient。有人可以纠正我出错的部分吗?

从 C 中的字符串中剪切子字符串

char 数组和指针——有人可以解释以下输出吗?

C - 位矩阵的位字段

c++ - 正则表达式查找所有用位字段定义的结构

有人可以将这些 C 代码翻译成 mips 汇编代码吗

c - 接受位域值的函数 arg 使用什么类型

c++ - 游戏 map 对象属性的位域与多态性

c++ - 枚举位域和聚合初始化