前言
在了解C语言位操作符之前,我们必须要有以下前导知识:
①正码,反码,补码具体介绍
②为什么会有正、反、补码
③正码,补码的直接互换
①正码,反码,补码具体介绍
正码:根据数据的正负(二进制数第一位为符号位,0为正,1为负)直接写出的二进制数就是原码。
反码:原码符号位不变,其它按位取反(0变1,1变0)。
补码:在反码基础上加上一个1。
//注意:正数的反码、补码都是原码。
②为什么会有正、反、补码
首先在计算机中存储整数的都是按照补码来存储的,使用补码计算有很多优点,如能够统一符号位(正数补码与原码一致,符号位不变,负数的补码符号位会改变,改为正),加减法统一(CPU只能进行加法运算)。
③正码,补码的直接互换
当在进行位运算时,经常会涉及到正码与补码的直接互换,分三步还原比较麻烦,有一种直接转换的方法就是,补码——>取反+1——>正码,直接得到补码。
位运算
C语言的位运算符号主要是以下5个:
①&——按位与
②|——按位或
③^——按位异或
④~——按位取反
⑤<<——左移位
⑥>>——右移位
①&——按位与
双目操作符,两个二进制数字从头到尾一一对应,同时为1,才为1。
示例:
#include<stdio.h>
int main() {
int a = 20;
int b = 30;
int c = a & b;
//a=00010100
//b=00011110
//c=00010100,同时为1,才为1
printf("%d",c);
return;
}
运行结果:20
②|——按位或
双目操作符,两个二进制数字从头到尾一一对应,有一个为1,就为1。
示例:
int main() {
int a = 20;
int b = 30;
int c = a | b;
//a=00010100
//b=00011110
//c=00011110,有一个为1,就为1
printf("%d",c);
return;
}
运行结果:30
③^——按位异或
双目操作符,两个二进制数字从头到尾一一对应,相同为0,相异为1。
示例:
#include<stdio.h>
int main() {
int a = 20;
int b = 30;
int c = a ^ b;
//a=00010100
//b=00011110
//c=00001010,相同为0,相异为1
printf("%d",c);
return;
}
运行结果:10
④~——按位取反
单目操作符,将1个二进制数字从头到尾一一取反。
这里有个简单公式~x=-(x+1)。
示例:
#include<stdio.h>
int main() {
int a = 20;
int b = 30;
int c = ~a ;
//a=00010100,正数原码,反码,补码一致
// 11101011//取反,但这是负数的补码,要还原成原码
// 10010100//还原取反
// 10010101//+1,最后结果为-21
printf("%d",c);
return;
}
运行结果:-21
⑤<<——左移位
双目运算符,一个需要被移位的数值,另一个移位的个数,原则左边抛弃,右边补0。
示例:
#include<stdio.h>
int main() {
int a = 20;
int b = a << 1;
//a=00010100
//b=00101000
printf("%d", b);
return;
}
运行结果:40
⑥>>——右移位
双目运算符,一个需要被移位的数值,另一个移位的个数,原则有两种情况,1.逻辑右移,左边用0填充,右边丢弃。2,算数右移,左边用原符号位补齐,右边丢弃。
在不同的编译器可能会有不同的情况,但是一般情况是算数右移。
示例:
#include<stdio.h>
int main() {
int a = 20;
int b = a >> 1;
//a=00010100
//b=00101000
printf("%d", b);
return;
}
运行结果:10
Respect!