1.什么是位运算符?
C语言中的位运算符是专门用于计算整型的二进制
2.C语言中有哪些位运算符?
与:&(按位与)
格式:数值1 & 数值2
它会将数值1的二进制和数值2的二进制的每一位进行运算
规律:一假则假
4&6
0100
&0110
-----------
0100
2.2 或:|(按位或)
格式:数值1|数值2
它会将数值1的二进制和数值2的二进制的每一位进行运算
规律:一真则真
4|6
0100
| 0110
--------------
0110
2.3 异或:^(按位异或)
格式:数值1 ^ 数值2
它会将数值1的二进制和数值2的二进制的每一位进行的运算
规律:相同为假,不同为真
4^6
0100
^ 0110
----------
0010
2.4 非:~(按位取反)
格式:~ 数值(单目运算符)
规律:真变假,假变真
~4
~0100
-----------
1011 //补码
1010 //转化成反码
1101//得到原码(-5)
左移:<<
右移:>>
1.按位与的运算特点
二进制中的每一位按位与上1,结果还是那一位
9 & 15
1001
&1111
----------
1001
2.按位异或的运算特点(相同是0,不同是1)
2.1 二进制中一个数按位异或上自己,结果等于0
2.2 二进制中一个数按位异或上0,结果等于自己
2.3 二进制中一个数按位异或上另一个数两次,那么结果还是自己(简单的加密)
9^9
1001
^1001
------------
0000
6^0
0110
^0000
----------
0110
6^9^9
0110
^1001
-----------
1111
^1001
-----------
0110
密码加密
1.按位左移 <<
运算的步骤:将二进制的所有位都往左边移动,移出去的部分删除,在最后添加0
规律:左移多少位就是2的多少次幂
注意点:左移运算可能会改变数值的正负性
9 << 1 -----> 9*2=18
0000 0000 0000 0000 0000 0000 0000 0000(参照物)
000 0000 0000 0000 0000 0000 0000 10010 --->18
9 << 2 ----> 9*2^2=9*4=36
0000 0000 0000 0000 0000 0000 0000 0000(参照物)
00 0000 0000 0000 0000 0000 0000 100100(36)
2.按位右移 >>
运算的步骤:将二进制除了符号位以外的所有都向右移动,移出去的部分删除,在最高位补0
规律:右移多少位除以2的多少次幂
9 >> 1 -----> 9/2(1) ----> 9/2 ----> 4
9 >> 1
0000 0000 0000 0000 0000 0000 0000 0000(参照物)
0000 0000 0000 0000 0000 0000 0000 1001(9)
9>>1:
00000 0000 0000 0000 0000 0000 0000 100(9)
9>>2 --> 9/2(2)-->9/4 ---> 2
9>>2:
0000 0000 0000 0000 0000 0000 0000 0000(参照物)
000000 0000 0000 0000 0000 0000 0000 10
位运算练习
需求:要求判断一个整数是偶数还是奇数,是偶数输出YES,是奇数输出NO
第一种实现方式:三目运算符
第二种实现方式: if else
第三种实现方式:利用位运算符号(利用最低位)
(NUM&1)==0
8 --->二进制
1000
&0001
----------
9--->二进制
1001
&0001
6--->二进制
0110
&0001
7--->二进制
0111
&0001
位运算练习二
需求:交换两个变量的值
第一种方式:利用临时变量
第二种方式:算数运算符
a=a+b;//a=10+20=30
b=a-b;//b=30-20=10
a=a-b;//a=30-10=20
第三种方式:利用位运算
一个数异或另一个数两次(a=a^a^b=b),结果就等于这一个数。
位运算符练习三
需求:要求输出一个整数的二进制的每一位
直接输出十进制: %d %i
直接输出八进制: %o
直接输出十六进制:%x
#include <stdio.h>
#include <stdlib.h>
void printfBinary(int value);
int main()
{
/* 让(9&1)就可以取出最低位,然后右移一位,重复以上操作
* 0000 0000 0000 0000 0000 0000 0000 0000 0000 1001
* &0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
* ------------------------------------------------------
* 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 --> 1
*
* 00000 0000 0000 0000 0000 0000 0000 0000 0000 100
* &0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
* ------------------------------------------------------
* 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 --> 0
*
* 000000 0000 0000 0000 0000 0000 0000 0000 0000 10
* &0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
* ------------------------------------------------------
* 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 --> 0
*
* 0000000 0000 0000 0000 0000 0000 0000 0000 0000 1
* &0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
* ------------------------------------------------------
* 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 --> 1
*
*/
printfBinary(9);
return 0;
}
void printfBinary(int value)
{
//1.定义一个变量记录右移的位数
int offset = 31;
//2.通过循环不断右移
while(offset >=0)
{
int res = (value >> offset) & 1;//先输出最高位,然后往下递减
printf("%i",res);
offset--;
}
}