关于位域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 gives?

A: Those are bit-fields; the number gives the exact size of the field, in bits. (See any complete book on C for the details.) Bit-fields can be used to save space in structures having several binary flags or other small fields, and they can also be used in an attempt to conform to externally-imposed storage layouts. (Their success at the latter task is mitigated by the fact that bit-fields are assigned left-to-right on some machines and right-to-left on others). //从而导致不可移植

Note that the colon notation for specifying the size of a field in bits is only valid in structures (and in unions); you cannot use this mechanism to specify the size of arbitrary variables. (See questions 1.2 and 1.3.)

 

References: K&R1 Sec. 6.7 pp. 136-8
K&R2 Sec. 6.9 pp. 149-50
ISO Sec. 6.5.2.1
H&S Sec. 5.6.5 pp. 136-8


 

这是C语言位域问题

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:

struct 位域结构名
{ 位域列表 };

其中位域列表的形式为: 类型说明符 位域名:位域长度

例如:

位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:

说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明:

1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:

在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。

2. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如: 

从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。

 

Declaring and Using Bit Fields in Structures

http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/topic/com.ibm.vacpp7l.doc/language/ref/clrc03defbitf.htm

 

Both C and C++ allow integer members to be stored into memory spaces smaller than the compiler would ordinarily allow. These space-saving structure members are called bit fields, and their width in bits can be explicitly declared. Bit fields are used in programs that must force a data structure to correspond to a fixed hardware representation and are unlikely to be portable.

The syntax for declaring a bit field is as follows:

>>-type_specifier--+------------+--:--constant_expression--;---><
                   '-declarator-'
 
 

A bit field declaration contains a type specifier followed by an optional declarator, a colon, a constant integer expression that indicates the field width in bits, and a semicolon. A bit field declaration may not use either of the type qualifiers, const or volatile.

C The C99 standard requires the allowable data types for a bit field to include qualified and unqualified _Bool, signed int, and unsigned int. In addition, this implementation supports the following types.

  • int
  • short, signed short, unsigned short
  • char, signed char, unsigned char
  • long, signed long, unsigned long
  • long long, signed long long, unsigned long long

In all implementations, the default integer type for a bit field is unsigned.

C++ C++ extends the list of allowable types for bit fields to include any integral type or enumeration type.

In either language, when you assign a value that is out of range to a bit field, the low-order bit pattern is preserved and the appropriate bits are assigned.

Bit fields with a length of 0 must be unnamed. Unnamed bit fields cannot be referenced or initialized. A zero-width bit field can cause the next field to be aligned on the next container boundary where the container is the same size as the underlying type of the bit field.

Bit fields are also subject to the align compiler option. Each of the align suboptions gives a different set of alignment properties to the bit fields. For a full discussion of the align compiler option and the #pragmas affecting alignment, see XL C/C++ Compiler Reference.

AIX Linux C The maximum bit field length is 64 bits. For portability, do not use bit fields greater than 32 bits in size.

AIX Linux C++ The C++ Standard does not limit the length of a bit field in a declaration. However, any bits in excess of the size of the underlying type behave as padding.

The following restrictions apply to bit fields. You cannot:

  • Define an array of bit fields     定义位域数组
  • Take the address of a bit field 取一个位域的地址
  • Have a pointer to a bit field     用一个指针指向一个位域
  • Have a reference to a bit field 引用一个位域

The following structure has three bit-field members kingdom, phylum, and genus, occupying 12, 6, and 2 bits respectively:

struct taxonomy {
     int kingdom : 12;
     int phylum : 6;
     int genus : 2;
     };

Alignment of Bit Fields

If a series of bit fields does not add up to the size of an int, padding can take place. The amount of padding is determined by the alignment characteristics of the members of the structure.

The following example demonstrates padding. Suppose that an int occupies 4 bytes. The example declares the identifier kitchen to be of type struct on_off:

struct on_off {
                  unsigned light : 1;
                  unsigned toaster : 1;
                  int count;            /* 4 bytes */
                  unsigned ac : 4;
                  unsigned : 4;
                  unsigned clock : 1;
                  unsigned : 0;
                  unsigned flag : 1;
                 } kitchen ;

The structure kitchen contains eight members totalling 16 bytes. The following table describes the storage that each member occupies:

Member Name Storage Occupied
light 1 bit
toaster 1 bit
(padding -- 30 bits) To the next int boundary
count The size of an int (4 bytes)
ac 4 bits
(unnamed field) 4 bits
clock 1 bit
(padding -- 23 bits) To the next int boundary (unnamed field)
flag 1 bit
(padding -- 31 bits) To the next int boundary

All references to structure fields must be fully qualified. For instance, you cannot reference the second field by toaster. You must reference this field by kitchen.toaster.

The following expression sets the light field to 1:

  kitchen.light = 1;

When you assign to a bit field a value that is out of its range, the bit pattern is preserved and the appropriate bits are assigned. The following expression sets the toaster field of the kitchen structure to 0 because only the least significant bit is assigned to the toaster field:

  kitchen.toaster = 2;
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值