数据是以二进制数存储在计算机里的,位运算就是直接对整数在内存中的二进制位进行操作。
&按位与,两个操作数对应的位必须同时为1,结果才为1 ,否则位0为0
void and(void)
{
unsigned int num01=65535;
unsigned int num02=1;
unsigned ret=0;
ret=num01&num02;
printf("%d",ret);
}
结果为1,为什么是1呢?通过制作一个类似数据存储的表格来认识一下,可以看到果两个相应的二进制位都为1,则该位的结果值为1.
| 按位或,两个操作数对应的位只要有一个为1,结果为1
void or(void)
{
unsigned int num01=15;
unsigned int num02=241;
unsigned ret=0;
ret=(num01|num02);
printf("%d",ret);
}
结果为255,通过表格来看一下。
^按位异或,两个操作数对应的位不相同,结果为1 ,相同则为0.
void xor(void)
{
unsigned int num01=139;
unsigned int num02=199;
unsigned ret=0;
ret=num01^num02;
printf("%d",ret);
}
结果为76,
~按位取反,对一个二进制数进行取反,0变1,1变0.
比较:逻辑取反:如:a = !0,0变为1; b = !10 ,非0数值转换为0。
void not(void)
{
int num01=21845;
num01=~num01;
printf("~num01=%d",num01);
}
这里的21845二进制数为:101 0101 0101 0101
取反后: 1010 1010 1010 1010,最前面的1为符号位,为负数,前面都是1;由于计算机需要以补码表示,需要对该值获取补码才能获得最终结果
取反码:1101 0101 0101 0101 (符号位不变,其余各位求反)
取补码:1101 0101 0101 0110 (反码+1)
所以值为-21946,运行一下程序:
<<左移,>>右移,左移是把数扩大了,右移是减小
通过代码认识一下
void fun(void)
{
unsigned int num01=88;
int ret;
ret=num01>>1;
printf("%d\n",ret);//输出44
num01>>=4;//num01=num01>>4
printf("%d\n",num01);//输出5
}
定义一个无符号整型num01为88,先将它右移一位,输出44,缩小了原来的两倍,然后88向右移动4位,输出5.
应用:无符号数左移移位相当于该数乘以2,编写一个函数,接收两个整型变量num和pow作为实参,被掉函数使用移位运算计算num*2\^pow的结果。然后分别以整型和二进制形式输出
void fun01(int num, int pow)
{
num=num<<1;
num=num*pow;
unsigned int mask=0x1<<31;
int i;
for(i=0;i<32;i++)
{
num&mask ? putchar('1') : putchar('0');
num=num<<1;
if(i%8==0)
putchar(' ');
}
}
int main()
{
// fun();
unsigned int num,pow;
printf("请输入两个无符号整数\n");
scanf("%d %d",&num,&pow);
fun01(num,pow);
return 0;
}