四、位域
3.1 位运算符
所有的数据在计算机内都是用位序列来表达的,每一位的值为0或为1。如值65535即11111111 11111111;255即00000000 11111111。大多数系统,连续的8位构成一个字节。字节(byte)是一个char类型变量的标准存储单位。位运算符用来操作整数操作数的位,整数操作数的类型包括有符号(signed)和无符号(unsigned)的char、short、int和long类型。位运算符通常用于unsigned类型的整数。
位 运 算 符 | 描 述 |
& (按位与) | 如果两个操作数的相应位都为1,结果中的相应位设置为1 |
| (按位或) | 如果两个操作数的相应位有一个为1,结果中的相应位设置为1 |
^ (按位异或) | 如果两个操作数的相应位只有一个为1,结果中的相应位设置为1 |
<< (左移位) | 把第一个/左操作数的位向左移动第二个/右操作数指定的位数,右边空出的位补0,从左边移出的位值丢失了 |
>> (右移位) | 把左操作数的位向右移动右操作数指定的位数,填补左边空出的方法与机器有关(补0还是补1),从右边移出的位值丢失了 |
~ (按位取反) | 所有0位设置为1,所有1位设置为0 |
注意,移位操作中,右操作数是负值或者右操作数大于左操作数存储的位数,则其结果是不确定的。
按位与运算符
位1 | 位2 | 位1&位2 |
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
按位或运算符
位1 | 位2 | 位1|位2 |
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 1 |
按位异或运算符
位1 | 位2 | 位1&位2 |
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 0 |
位赋值运算符
位 赋 值 运算符 | 描 述 |
&= | 按位与赋值运算符 |
|= | 按位或赋值运算符 |
^= | 按位异或赋值运算符 |
<<= | 左移位赋值运算符 |
>>= | 右移位赋值运算符 |
运算符优先级和结合性
运 算 符 | 结 合 性 | 类型 |
() [] . -> | 从左到右 | 最高优先级 |
+ - ++ -- !(type) & * ~ sizeof | 从右到左 | 单目运算符 |
* / % | 从左到右 | 乘法运算符 |
+ - | 从左到右 | 加法运算符 |
<< >> | 从左到右 | 移位运算符 |
< <= > >= | 从左到右 | 关系运算符 |
== != | 从左到右 | 相等测试运算符 |
& | 从左到右 | 按位与运算符 |
^ | 从左到右 | 按位异或运算符 |
| | 从左到右 | 按位或运算符 |
&& | 从左到右 | 逻辑与运算符 |
|| | 从左到右 | 逻辑或运算符 |
?: | 从右到左 | 条件运算符 |
= += -= *= /= %= &= |= ^= <<= >>= | 从右到左 | 赋值运算符 |
, | 从左到右 | 逗号运算符 |
3.2 位域
字节操作是C语言十分强大的内设机制。通过位运算符就可以完成位操作。但使用位域(bit-field)也可以访问单个的位,并且增强代码结构,也可能更高效。位域是指定了存储位数的结构或联合中的成员。其定义形式如下:
type name : length;
type指定位域的类型,必须是int、signed或unsigned(C99还允许_BOOL类型); length指定位域的位数。
struct employee
{
float pay;
unsigned lay_off: 1; /* 员工状态 */
unsigned hourly: 1; /* 薪酬方式 */
unsigned deductions: 3; /* 受教育情况 */
};
成员的位数是根据成员所需的范围确定的。这里用一个字节就存储了三段信息:员工状态、薪酬方式、手教育情况。如果不用位域,则得要3个字节。
struct employee
{
float pay;
unsigned: 1; /* 无名位段*/
unsigned lay_off: 1; /* 员工状态 */
unsigned hourly: 1; /* 薪酬方式 */
unsigned deductions: 3; /* 受教育情况 */
};
无名位段就是无用位,即不存储任何内容。它用来跳过无用位,到达有用位。有时如果无名位段占用4位,在4位字长的计算机上,紧接着的成员lay_off就被存储到另一个存储单元中。如果无名位段的宽度为0,表示使下一个位段从新存储单位的起始位置开始存储,上一个存储单元剩下的位被跳过。
操作位域时,要注意位域是没有地址的,所以对它不能使用取地址运算符&。另外,使用位域,虽然节省了内存,但编译器将产生执行速度慢的机器语言代码。
参考书籍:
H. Schildt:The C: Complete Reference,Fourth Edition(王子恢等译,电子,2001.09)
H.M. Deitel,P.J. Deitel:C How To program,Second Edition(薛万鹏等译,机工,2000.07)
/*******************************************************************
| mailto:yesaidu@126.com |
| http://blog.163.com/yesaidu@126 |
| 2008-05-26 |
*******************************************************************/