C语言 第七章 高级数据类型(3):位运算符和位域

 

四、位域

3.1 位运算符

       所有的数据在计算机内都是用位序列来表达的,每一位的值为0或为1。如值6553511111111 1111111125500000000 11111111。大多数系统,连续的8位构成一个字节。字节(byte)是一个char类型变量的标准存储单位。位运算符用来操作整数操作数的位,整数操作数的类型包括有符号(signed)和无符号(unsigned)的charshortintlong类型。位运算符通常用于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指定位域的类型,必须是intsignedunsignedC99还允许_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. SchildtThe C: Complete ReferenceFourth Edition(王子恢等译,电子,2001.09
H.M. Deitel
P.J. DeitelC How To programSecond Edition(薛万鹏等译,机工,2000.07
/*******************************************************************
|  mailto:yesaidu@126.com                                                                               |
|  http://blog.163.com/yesaidu@126                                                                   |
|  2008-05-26                                                                                                 |
*******************************************************************/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值