1. 基础知识
运算符 含义 运算符 含义
& 按位与 ~ 取反
| 按位或 << 左移
∧ 按位异或 >> 右移
注意:
(1)位运算符中除~以外,均为二目(元)运算符,即要求两侧各有一个运算量。
(2)运算量只能是整型或字符型的数据,不能为实型数据。
按位与的使用技巧:
(1)清0. 若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其满足原来数中为1的位,新数中相应位为0.然后让二者进行&运算。
(2)取指定位。如取整数a(2个字节)的底8位,只需要将a与8个1按位与即可。
按位或使用技巧。
(1)用来对一个数据的某些位定值为1.
按位异或使用技巧。
(1)与1异或,特定位翻转。设有01111010,想使其低4位翻转,即1变为0,0变为1。可以将它与00001111进行∧运算。
(2)与0异或,保留原值。
(2)不用临时变量,交换两个值。
例如:a=3,b=4。
想将a和b的值互换,可以用以下赋值语句实现:
a=a∧b;
b=b∧a;
a=a∧b;
左移使用技巧。
(1)左移1位相当于该数乘以2,左移2位相当于该数乘以4,15<<2=60,即乘了4。但此结论只适用于该数左移时被溢出舍弃的高位中不包含1的情况。
右移使用技巧。
(1)右移相当于数除以2(算术右移).
(2)对无符号数,右移时左边高位移入0;对于有符号的值,如果原来符号位为0(该数为正),则左边也是移入0。如果符号位原来为1(即负数),则左边移入0还是1,要取决于所用的计算机系统。有的系统移入0,有的系统移入1。移入0的称为“逻辑右移”,即简单右移;移入1的称为“算术右移”。
2. 例题
例1, 取一个整数a从右端开始的4-7位。(假设a是16位整数)
解答:
#include <stdio.h>
void main()
{ unsigned a,b,c,d;
scanf(“%o”,&a);
b=a>>4;
c=~(~0<<4);
d=b&c;
printf(“%o,%d/n%o,%d/n”,a,a,d,d);
}
例2,对一个整数a实现循环右移。
解答:
#include <stdio.h>
void main()
{ unsigned a,b,c;
int n;
scanf(“a=%o,n=%d”,&a,&n);
b=a<<(16-n);
c=a>>n;
c=c|b;
printf(“%o/n%o”,a,c);
}
应用:
考虑一个IP地址用unsigned long表示,那么该如何得到这个IP地址呢?或者
给定一个IP地址,如何用unsigned long 表示出来呢?
解答:
(1.1)
unsigned long ip;
unsigned short int first,second,third,fourth;
scanf("%l",&ip);
first=(ip>>24)& ~(~0 << 8);
second=(ip>>16)& ~(~0 << 8);
third=(ip>>8)& ~(~0 << 8);
fourth=ip& ~(~0 << 8);
(1.2)
unsigned long ip;
unsigned short int first,second,third,fourth;
scanf("%l",&ip);
char *p;
p=(char *)&ip;
first=(unsigned short int)p[0];
second=(unsigned short int)p[1];
third=(unsigned short int)p[2];
fourth=(unsigned short int)p[3];
(2)
unsigned long ip=0;
ip|=first;
ip<<=8;
ip|=second;
ip<<=8;
ip|=third;
ip<<=8;
ip|=fourth;
printf("the ip can be represented by unsigned long as:%l",ip);