Linux C-----位段类型

原创 2012年03月27日 13:47:12

1.什么是位段

在大多数的计算机系统中, 一个字节是由八个更小的, 称作为位的单位组成的。位是比字节更小的单位。位只有两个值, 10 。因此, 存储在计算机存储器中的一个字节可以看成由八个二进制数字形成的串。

例如, 一个存放值 36 的字节是八个二进制数字的串: 可以表示成 00100100。 存入值24 的字节可以表示成 00010100。

有时, 我们希望不仅对字节进行操作, 也要能对位进行操作。例如, 用布尔真或假条件表示的标志, 在计算机中可用位来表示。

但是, 说明一个用作标志的普通变量至少要用一个字节---8 位, 而在某些计算机系统中则可能是 16 位。 如果我们想在一个很大的表中存储很多标志, 那么 "被浪费" 的内存空间是很可观的。

在 C 语言中, 一种方法是用叫做位段的构造类型来定义一个压缩信息的结构。

c831.jpg (4023 bytes)什么是位段呢? 位段是 C 语言特有的数据结构, 它允许我们定义一个由位组成的段, 并可为它赋以一个名字。

 

 

 

2.位段的用法

我们已经了解什么是位段了, 现在我们继续讨论位段的使用方法。

先看一个例子: 我们需要用到五个变量。 假定, 其中三个用作标志, 称为 f1, f2 和 f3。
第四个称为 type, 取值范围为 1 至 12。 最后一个变量称为 index, 值的范围为 0 至 500。

通常, 我们用下面的语句来说明这些变量:
char f1,f2,f3;
unsigned int type;
unsigned int index;

但是, 实际上标志 f1, f2, f3 分别只需要 1 位。变量 type 只需要 4 位, 而变量 index 只需要 9 位。 总共是 16位 ---- 2 个字节。我们用两个字节就够了。

我们可这样来做:
struct packed_struct
{
    unsigned int f1 :1;
    unsigned int f2 :1;
    unsigned int f3 :1;
    unsigned int type :4;
    unsigned int index :9;
};


c832.jpg (7028 bytes)该例中, 我们定义了一个结构 packed_struct。该结构定义了五个成员。第一个成员叫做 f1, 是 unsigned int 类型的。紧跟在该成员名之后的 :1 规定了它以 1 位存放。类似地, 标志 f2 和 f3 被定义为长度只有 1 位的。定义成员 type 占有 4 位。定义成员 index 占有 9 位。C 编译器自动地把上面的位段定义压缩在一起。位段的划分如图所示。packed_struct 总共使用了 16 位。

这种方法的好处是, 定义成 packed_struct 类型的变量的位段, 可以如引用一般的结构成员一样方便地引用。同时, 使用了更少的内存单元数。

我们已经定义了一个称作为 packed_struct 的包含着位段的结构。现在, 我们象下面那样定义一个称作为 packet_data 的变量: struct packed_struct packed_data; 于是, 我们就可以用简单的语句, 把 packed_data 的 type 位段设置为 7:
packed_data.type = 7; 类似地, 我们可以用下面的语句把这个位段的值设为 n:
packed_data.type = n; 我们不必担心 n 的值太长, 以致不能放入 type 位段中, C 编译器会自动地仅取出 n 的低四位, 把它赋值给 packed_data.type。取出位段的值也自动地处理的, 因此语句 n = packed_data.type; 将从 packed_data 中取出 type 位段, 并把它的值赋给 n。

在一般的表达式中可以使用位段, 此时, 位段自动地转换成整数。因此, 表达式
i = packed_data.index/5+1; 是完全有效的。

在包含位段的结构中, 也可以包括 "通常的" 数据类型。因此, 如果我们想定义一个结构, 它包含一个 int, 一个 char, 和二个 1 位的标志, 那么, 下面的定义是有效的:
struct table_entry
{
    int     count ;
    char     c;
    unsigned int f1 :1;
    unsigned int f2 :1;
};


当位段出现在结构定义中时, 它们就被压缩成字。如果某个位段无法放入一个字中, 那么该字的剩余部分跳过不用, 该位段被放入下一个字中。

使用位段时, 必须注意下列事项:

  • 在某些机器上, 位段总是作为 unsigned 处理, 而不管它们是否被说明成 unsigned 的。
  • 大多数C 编译器都不支持超过一个字长的位段。
  • 位段不可标明维数; 即, 不能说明位段数组, 例如 flag:l[2]。
  • 最后, 不可以取位段地址。原因是, 在这种情况不, 显然没有称作为 "位段指针" 类型的变量。

这里, 我们再深入讨论一下位段。如果使用下面的结构定义:
c833.jpg (7056 bytes)struct bits
{
    unsigned int f1:1;
    int     word;
    unsigned int f3:1;
};

那么, 位段是怎样压缩的呢? 由于成员 word 出现于其间, 故 f1, f3 不会压缩在同一个字内。C 编译器不会重新安排位段定义来试图优化存储空间。

可以指定无名位段, 使得一个字中的某些位被 "跳过"。因此, 定义:
c834.jpg (6819 bytes)struct x_entry
{
    unsigned int type :4;
    unsigned int :3;
    unsigned int count :9;
};

将定义一个结构 x_entry, 它包含两个位段变量 type 和 count, 而无名位段规定了 type 和 count 间隔三位。

 

 

相关文章推荐

Linux C/C++ 区别:类型声明、struct

C有数组、结构体、指针、函数、宏 C++有命名空间、引用、默认参数、模板、函数重载、自定义操作符、内联、构造/析构、私有/保护成员、友元、异常。 一、数据类型声明 1.1 C++允许数据类型声明可以出...

LINUX C 获取文件类型 以及访问权限

#include #include #include #include #include #include #include #include #include #...

嵌入式linux C编程基础知识点二:变量类型

知识点二:变量类型 一、知识目录 1.字符型: 2.整型: 3.长整型: 4.浮点型:...
  • Dreamjz
  • Dreamjz
  • 2016年09月23日 23:54
  • 125

Linux C笔记之 变量存储类型 详解

存储类型:变量的存储类型是指存储变量值的内存类型 ;变量的存储类型决定变量何时创建、何时销毁以及它的值将保存多久 ;存储变量:普通内存、运行时堆栈、硬件寄存器;变量的缺省存储类型取决于它的声明位置;静...

Linux c — void类型变量和指针

Linux c — void类型变量和指针1.什么是void?void在英文中形容词的意思就是无效的,空的,空虚的意思,在C语言中就是空类型的意思。 在C语言中,使用void这个类型时,有如下规则:...
  • men_wen
  • men_wen
  • 2016年09月17日 21:39
  • 941

Linux C编程章节二:常用类型和预处理器

这一章简单介绍一下Linux下C常用类型和预处理器。此前记录为PDF,因此作为截图放入Blog。特此声明! 常用类型 预处理器...

linux c typeof创建结构体元素类型用法

文章转自: 最后给出我自己的一个小例子 typeof的用法   首先typeof这个东西并不是ISO/IEC 9899:1999里的,也就是说不是标准C的运算符,这是gcc的一...

c语言数据类型 之 内存对齐与位段

64位操作系统下不同类型数据所占字节数 char          : 1 字节 void *        : 8 字节 unsigned char : 1 字节 long char     : ...
  • pearl_c
  • pearl_c
  • 2016年03月02日 01:11
  • 314

位段与联合,枚举类型

1.位段与联合(union) #include union { struct { unsigned int x1 : 2; unsigned int x2 : 3; unsign...

位段类型

摘自:http://its.nbtvu.net.cn/xhyu/cai_c/c_web/c/c8/c83.htm 1.什么是位段 在前面各章中, 我们已经讨论过字节概念了。在大多数的计算机系统...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux C-----位段类型
举报原因:
原因补充:

(最多只允许输入30个字)