关于Bit Fields的两篇资料

《Imperfect C++中文版》——1.2 编译期契约:约束 本节书摘来自异步社区出版社《Imperfect C++中文版》一书中的第1章,第1.2节,作者: 【美】Matthew Wilson,更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.2 编译期契约:约束 Imperfect C++中文版本章讲述编译期强制,通常它也被称为“约束(constraints)”。遗憾的是,C++并不直接支持约束。 Im... 阅读详情

C++ Language Reference

 

C++ Bit Fields

See Also

Classes, Structures, and Unions

Classes and structures can contain members that occupy less storage than an integral type. These members are specified as bit fields. The syntax for bit-field member-declarator specification follows:

declaratoropt  : constant-expression

The declarator is the name by which the member is accessed in the program. It must be an integral type (including enumerated types). The constant-expression specifies the number of bits the member occupies in the structure. Anonymous bit fields — that is, bit-field members with no identifier — can be used for padding.

Note   An unnamed bit field of width 0 forces alignment of the next bit field to the next type boundary, where type is the type of the member.

The following example declares a structure that contains bit fields:

// bit_fields1.cpp

struct Date

{

   unsigned nWeekDay  : 3;    // 0..7   (3 bits)

   unsigned nMonthDay : 6;    // 0..31  (6 bits)

   unsigned nMonth    : 5;    // 0..12  (5 bits)

   unsigned nYear     : 8;    // 0..100 (8 bits)

};

 

int main()

{

}

The conceptual memory layout of an object of type Date is shown in the following figure.

Memory Layout of Date Object

 

Note that nYear is 8 bits long and would overflow the word boundary of the declared type, unsigned int. Therefore, it is begun at the beginning of a new unsigned int. It is not necessary that all bit fields fit in one object of the underlying type; new units of storage are allocated, according to the number of bits requested in the declaration.

Microsoft Specific

The ordering of data declared as bit fields is from low to high bit, as shown in the figure above.

END Microsoft Specific

If the declaration of a structure includes an unnamed field of length 0, as shown in the following example,

// bit_fields2.cpp

struct Date

{

   unsigned nWeekDay  : 3;    // 0..7   (3 bits)

   unsigned nMonthDay : 6;    // 0..31  (6 bits)

   unsigned           : 0;    // Force alignment to next boundary.

   unsigned nMonth    : 5;    // 0..12  (5 bits)

   unsigned nYear     : 8;    // 0..100 (8 bits)

};

 

int main()

{

}

the memory layout is as shown in the following figure.

Layout of Date Object with Zero-Length Bit Field

The underlying type of a bit field must be an integral type, as described in Fundamental Types.

© Microsoft Corporation. All rights reserved.

以上摘自MSDN Library for Visual Studio .Net 2003

 

 

位域(bit-field):一种压缩空间的成员

这两天在看公司里关于MPEG -2 流结构的代码,发现师傅写关于那些结构的代码的时候出现了如下类似的代码(这里的载自C++ Prime)。

typedef unsigned int Bit;

class File {

public:

Bit mode           : 2;

Bit modified      : 1;

Bit prot_owner : 3;

Bit prot_group   : 3;

Bit prot_world   : 3;

// ...

};

    刚开始觉得有些怪怪的,虽然从结构中大概知道是什么意思,但是具体的却不怎么知道。可能是C/C++的知识有些遗漏,实践比较少吧。于是查找资料,得知:

这是一种被称为位域bit-field 特殊的类数据成员。它可以被声明用来存放特定数目的位,位域必须是有序数据类型,它可以有符号也可以无符号例如:

class File {

// ...

unsigned int modified : 1; // 位域 (bit-field)

};

位域标识符后面跟有一个冒号,然后是一个常量表达式指定位数,例如,modified 是一个只有一位构成的位域。

在类体中相邻定义的位域,如果可能的话,它们会被放在同一个整数的连续位中,并以此提供空间压缩。例如,在下列声明中,5 个位域被存储在单个unsigned int 中,它首先与位域mode 相关联

typedef unsigned int Bit;

class File {

public:

Bit mode: 2;

Bit modified: 1;

Bit prot_owner: 3;

Bit prot_group: 3;

Bit prot_world: 3;

// ...

};

对于位域的访问方式与其他类数据成员相同。例如,类的私有位域只能在类的成员函数和友元中被访问:

void File::write()

{

modified = 1;

// ...

}

void File::close()

{

if ( modified )

// ... 内容从略

}

下面的例子说明了怎样使用大于1 位的位域。

enum { READ = 01, WRITE = 02 }; // 文件模式

int main() {

File myFile;

myFile.mode |= READ;

if ( myFile.mode & READ )

cout << "myFile.mode is set to READ/n";

}

通常情况下我们会定义一组inline 成员函数,来测试每个位域成员的值。例如,类File可以定义成员isRead()isWrite()

inline int File::isRead() { return mode & READ; }

inline int File::isWrite() { return mode & WRITE; }

 

if ( myFile.isRead() ) /* ... */

有了这些成员函数,现在位域可以被声明为类File 的私有成员。

由于取地址操作符& 不能被应用在位域上,所以也没有能指向类的位域的指针位域也不能是类的静态成员

C++标准库提供了一个bitset 类模板,它可以辅助操纵位的集合。在可能的情况下,应尽可能使用它来取代位域。要是你对标准库还没没有什么概念,那你只好用这个了。

之前所说的位域都在类中体现的,那么结构体中呢?

定义位域结构的格式为:

    struct <结构体类型名>

     {

<类型1> <位域名1>:<位数>;

        <类型2> <位域名2>:<位数>;

        …

        <类型n> <位域名n>:<位数>;

     };

其中,<类型>必须是unsignedsignedint类型;<位域名>是用户命名的标识符;

<位数>表示该位域所占的二进制位数,是一个正整数。

    例如:

    struct bit8253

     {

      unsigned bcd:1;

      unsigned m:3;

      unsigned rl:2;

      unsigned sc:2;

      unsigned black:24;

     };

    说明:

    1)对于各个位域必须依次从低到高进行定义;

    2)位数为1的位域只能用unsigned类型;

    3)每个位域的位数应小于计算机的字长,但各个位域的总长度则可以大于一个字长,超过字长的部分放在下一个存储单元中。

对于这些说明只是针对结构体的呢?还是对于类中的位域一样有适用,还是部分适用呢?有待考证,但是这些都是比较细节的东西了,编程中如果遇到,要是出了错误往这里想就好了。正如福尔摩斯大致所说:除去那些不可能的,就是这些可能的了。

       了,我个人觉得位域还是比较有用的。比如在码流结构某些传输协议结构中都有一些字段小于计算机的字长,但是他们某几段的总长度又是比如4个字 节。还有就是有人提出现在的内存都是那么大的了,没有必要那么抠门了吧。但是,有人说过:程序员是为程序服务的,而机器不是。这句话的意思显然了 吧。好了,关于位域就说到此了,希望能使你也能有所收获。

 

 

参考:C++Prime

           潭浩强:C++程序设计

以上摘自:http://blog.csdn.net/Adrian_Bu/archive/2006/08/03/1015318.aspx

wave注:

(此文内容基本翻译自C++ Primer)

或者另外参见《C++ Primer

 
[工作积累] bitfield ISO/IEC 14882:2003: 9.6 Bit-fields[class.bit] A member-declarator of the form identifieropt : constant-expression specifies a bit-field; its length is set off from the bit-field name by a colon. T... 阅读详情

相关推荐

GCC-3.4.6源代码学习笔记(139-续2)

<br /><br />在类节点的TYPE_FIELDS中,一个FIELD_DECL被用来代表一个非静态的数据成员,一个VAR_DECL被用来代表一个静态数据成员,而一个TYPE_DECL用来代表一个类型。用于一个枚举类型的CONST_DECL也会出现在TYPE_FIELDS链表中,如果该枚举类型声明在该类里。<br />4691至4707行的代码处理非静态成员以外的实体。注意静态成员的类型在类定义中可以是未完成的,因为它不占用类对象的空间。这也显示了C++语言的哲学思想——尽可能灵活。<br /> <br

wuhui_gdnt的专栏 1295

字节对齐(强制对齐以及自然对齐)

struct {}node; 32为的x86,window下VC下sizeof(node)的值为1,而linux的gcc下值为0; 一、WINDOWS下(VC--其实GCC和其原理基本一样,象这种问题,一般要查具体的编译器设置)字节对齐的规则: 1、一般设置的对齐方式为1,2,4字节对齐方式,VC一般默认为4字节(最大为8字节)。结构的首地址必须是结构内最宽类型的整数倍地址;另外,结构体...

weixin_34355559的博客 508

关于位域bit fields

(摘自网络)Q: I came across some structure declarations with colons and numbers next to certain fields, like this: struct record { char *name; int refcount : 4; unsigned dirty : 1;};What

hi 3770

C++ Bit Fields

See AlsoClasses, Structures, and UnionsClasses and structures can contain members that occupy less storage than an integral type. These members are specified as bit fields. The synta

尼莫的寂寞旅程. 1467

bit-fields 生成macros

Bit-fields macros是在C或C++语言中,‌利用宏定义(‌macros)‌来方便地创建和操作位字段(‌bit-fields)‌的一种方式。

李肖遥的专栏 681

C - Bit Fields

bit field

huixizhu的专栏 235

C语言中结构体的位域(bit-fields)

C语言中结构体的位域(bit-fields) 转自:http://blog.sina.com.cn/s/blog_6240b5980100tcba.html 有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“...

weiqiwuli的博客 2669

C语言中结构体的位域(bit-fields

C语言中结构体的位域(bit-fields) 转自:http://blog.sina.com.cn/s/blog_6240b5980100tcba.html   有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空...

Melody1994的博客 483

C Bit Fields

转载自MSDN:    https://msdn.microsoft.com/en-us/library/yszfawxh.aspx In addition to declarators for members of a structure or union, a structure declarator can also be a specified number of bit

han7741的专栏 587

C语言的“内存魔术师”—— 揭秘位域(Bit-fields

文章摘要:本文介绍了C语言中的位域(Bit-fields)技术,它能有效节省内存空间。通过对比普通结构体和位域结构体的存储方式,展示了位域如何将多个布尔值压缩到一个整型变量中。以"设备状态"和"智能LED灯"为案例,详细说明了位域的语法(:1表示1bit)和实际应用,包括处理模式、亮度等需要多个bit的场景。文章还测试了位域溢出的情况,并强调了这项技术在嵌入式系统开发中的重要性,帮助初学者理解C语言底层的位级操作能力。

wudu_123456的博客 863

C/C++位域(Bit-fields)

转载: 很早想说说这个问题了,经常也会有很多公司拿位域出来考人,呵呵要真的想弄清楚还要一点点的分析。 这里先看看网宿的一道笔试题目,这道题目我之前是复制网上的,结果不对,修改了一下,可以正确运行了,谢谢(imafish_i )提醒: //假设硬件平台是intel x86(little endian) typedef unsigned int uint32_t; void ine

逆水行舟,不进则退 473

位域(Bit-fields)分析

位域(Bit-fields)分析      位域是c++和c里面都有的一个概念,但是位域有一点要注意的有很多问题我们一样样的看: 一、大端和小端字节序 实际就是起始点该怎么确定。 先看一个程序: 1: union { 2: struct 3: { 4: unsigned char a1:2;

luoye7422的专栏 1215

Joy of Programming: Understanding Bit-fields in C

转:http://www.linuxforu.com/2012/01/joy-of-programming-understanding-bit-fields-c/ ByS.G. Ganeshon January 30, 2012 inCoding,Columns·2 Comments One important feature that distinguishes C a...

pengdonglin137的专栏 76

c++ 位域(bit-fields)和 volatile 关键字

/ 结构体中的位域// 占用 1 位// 占用 3 位// 未命名位域,填充 4 位// 占用 8 位// 二进制值:1// 二进制值:101// 二进制值:01111111// 输出:4 bytes(假设 unsigned int 为 4 字节)// 错误:无法取位域成员的地址return 0;

曾经也曾立志 1214

C/C++ 字节序/位域(Bit-fields)之我见

前言很早想说说这个问题了,经常也会有很多公司拿位域出来考人,呵呵要真的想弄清楚还要一点点的分析。这里先看看网宿的一道笔试题目,这道题目我之前是复制网上的,结果不对,修改了一下,可以正确运行了,谢谢(imafish_i )提醒://假设硬件平台是intel x86(little endian) typedef unsigned int uint32_t; void inet_ntoa(uin

大周辞寒的专栏 2万+
上一篇: How to implement a singleton class in Symbian OS
下一篇: 诺基亚发布适用于S60终端的Open C SDK插件
WaveDHW
博客等级 码龄19年 455粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值