C语言是为描述系统而设计的,因此它应当具有汇编语言所能完成的一些功能。C语言既具有高级语言的特点,又具有低级语言的功能,因而具有广泛的用途和很强的生命力。本章将介绍的位运算就很适合于编写系统软件的需要,是 C语言的重要特色。在计算机用于检测和控制领域中要用到位运算的知识。
所谓位运算是指进行二进制位的运算。在系统软件中,常要处理二进位的问题。例如,将一个存储单元中的各二进位左移或右移一位,两个数按位相加等。C语言提供位运算的功能,与其他高级语言(如PASCAL)相比,它显然具有很大的优越性。
1位运算符和位运算
C语言提供如表12.1所列出的位运算符。
说明:
- 位运算符中除~以外,均为二目(元)运算符,即要求两侧各有一个运算量。
- 运算量只能是整型或字符型的数据,不能为实型数据。
下面对各运算符分别介绍如下:
1.1 “按位与”运算符(&)
参加运算的两个数据,按二进位进行“与”运算。如果两个相应的二进位都为1,则该位的结果值为1.否则为0。即
0&0=0,0&1=0,18.0=0,1&1=1.
例如:3&5并不等于8,应该是按位与。
00000011 (3)
(&) 00000101 (5)
00000001 (1)
因此,3&5的值得1.如果参加&.运算的是负数(如-3&-5),则以补码形式表示为二进制数,然后按位进行“与”运算。
按位与有一些特殊的用途;
(1)清零。如果想将一个单元清零,即使其全部二进位为0,只要找一个二进制数,其中各个位符合以下条件:原来的数中为1的位.新数中相应位为0.然后使二者进行&运算,即可达到清零目的。
如:原有数为00101011.另找一个数,设它为10010100,它符合以上条件,即在原数为1的位置上,它的位值均为0,将两个数进行&运算:
00101011
(&) 10010100
00000000
其道理是显然的。当然也可以不用10010100这个数而用其他数(如01000100)也可以.只要符合上述条件即可。
(2)取一个数中某些指定位。如有一个整数a(2个字节),想要其中的低字节,只需将:与(377),按位与即可。见图12.1。
c=a&b,b为八进制数的377,运算后c只保留a的低字节,高字节为0。
如果想取两个字节中的高字节,只需c=a&.0177400(0177400表示八进制数的177400)。见图12.2。
(3)要想将哪一位保留下来,就与一个数进行&.运算,此数在该位取1.如:有一数01010100,想把其中左面第3、4、5、7、8位保留下来,可以这样运算:
01010100 (十进制数84)
(&) 00111011 (十进制数59)
00010000 (十进制数16)
即a=84,b=59,c=a&b=16.
1.2 按位或运算符(|)
两个相应的二进位中只要有一个为1,该位的结果值为1.即0|0=0,0|1=1,1|0=1,1|1=1。
例如:
060|017
将八进制数 60与八进制数17进行按位或运算。
00110000
(|) 00001111
00111111
低4位全为1。如果想使一个数a的低4位改为1,只需将a与017进行按位或运算即可。
按位或运算常用来对一个数据的某些位定值为1。如:a是一个整数(16位),有表达式a|0377
则低8位全置为1。高8位保留原样。
1.3“异或”运算符(∧)
异或运算符∧也称XOR运算符。它的规则是若参加运算的两个二进位同号,则结果为0(假);异号则为1(真)。即0∧0=0,0∧1=1,1∧0=1,1∧1=0。如:
00111001(十进制数57,八进制数071)
(∧) 00101010(十进制数42,八进制数052)
00010011(十进制数19,八进制数023)
即071∧052,结果为023(八进制数)。
“异或”的意思是判断两个相应的位值是否为“异”,为“异”(值不同)就取真(1),否则为假(0)。
下面举例说明∧运算符的应用:
(1)使特定位翻转
假设有01111010,想使其低4位翻转,即1变为0,0变为1。可以将它与00001111进行人运算,即
01111010
(∧) 00001111
01110101
结果值的低4位正好是原数低4位的翻转。要使哪几位翻转就将与其进行A运算的该几位置为1即可。这是因为原数中值为1的位与1进行人运算得0,原数中的位值0与1进行人运算的结果得1。
- 与0相∧,保留原值
如 012/00=012
00001010
(∧) 00000000
00001010
因为原数中的1与0进行人运算得1,0∧0得0,故保留原数。
(3)交换两个值,不用临时变量
假如a=3,b=4。想将a和b的值互换,可以用以下赋值语句实现:
a=a∧b;
b=b∧a;
a=a∧b;
可以用下面的竖式来说明:
a=011
(∧) b=100
a=111 (a∧b的结果,a已变成7)
(∧) b=100
b=011 (b∧a的结果,b已变成3)
(∧) a=111
a=100 (a∧b的结果,a变成4)
即等效于以下两步:
执行前两个赋值语句:“a=a∧b;”和“b=b∧a;”相当于b=b∧(a∧b).而b∧aΛ b等于aΛb∧b。b∧b的结果为0,因为同一个数与本身相人,结果必为0。因此b的值等于aΛ0,即a,其值为 3.
②再执行第三个赋值语句:a=a∧b。由于a的值等于(a∧b),b的值等于(b∧a∧ b),因此,相当于a=a∧b∧b∧a∧b,即a的值等于a∧a∧b∧b∧b,等于b。
a得到b原来的值。