移位操作符详解

必要理解

在了解移位操作符之前先了解一下一个整数的原码 反码 补码

那原码 反码 补码怎么写呢?接下来我们给出定义

按照一个数的正负 直接写出他的二进制形式就得到了他的原码
正数的原码 反码 补码 都是相同的
负数的原码 反码 补码 都是需要计算的
负数的反码就是符号位(第一位1代表负数0代表正数)不变 其他的按位取反 就是反码
补码是反码+1
一个整型占四个字节也就是三十二的比特位

图示理解↓

b490abd1d0a54e829bed4834a29890cf.png

#include<stdio.h>
int main()
{
	int a = 10;
	//00000000000000000000000000001010 原码 32位
	//00000000000000000000000000001010 反码
	//00000000000000000000000000001010 补码
	int b = -10;
	//10000000000000000000000000001010 原码
	//11111111111111111111111111110101 反码
	//11111111111111111111111111110110 补码

	return 0;
}

在了解完原码 反码 补码之后 我们就正式讲解移位符↓

1 什么是移位符呢?

移位符就是对一个整数的二进制形式进行左右移位

左移操作符就是 左边丢弃右边补0

右移操作符包括算数右移操作符和逻辑右移操作符(不常见取决于编译器)

算数右移就是右边丢弃 左边补充原来的符号位

逻辑右移就是右边丢弃 左边直接补充0

2 左移位讲解↓

#include<stdio.h>
int main()
{
	int a = 10;
	//00000000000000000000000000001010 原码 32位
	//00000000000000000000000000001010 反码
	//00000000000000000000000000001010 补码
	int b = -10;
	//10000000000000000000000000001010 原码
	//11111111111111111111111111110101 反码
	//11111111111111111111111111110110 补码

	int c = a << 1;
	int d = b << 1;
	printf("a=%d\n", a);
	printf("c=%d\n", c);
	printf("b=%d\n", b);
	printf("d=%d\n", d);
	return 0;
}

看看运行结果↓

6098b5c69b9741b5a8eb3b12bfb26587.png

移位的本质是什么呢?接下来讲解以别-10为例子

其实在电脑内存中存储的都是补码 移位也是补码在移位 但是打印出来确实原码的数值

来看本质↓

b2c0cdb618984efcad0d1bad843a66a0.png

补码写出来了 根据图1的逆向求原码

原码为

100000000000000000000000000010100

十进制结果就是-20


2 右移位(这里只讲解算数右移)

#include<stdio.h>
int main()
{
	int e = -10;
	//10000000000000000000000000001010 原码
	//11111111111111111111111111110101 反码
	//11111111111111111111111111110110 补码
	int f = -10 >> 1;
	printf("e=%d\n", e);
	printf("f=%d\n", f);
	return 0;
}

运行结果↓

c00d25f45a6f480d8af0e267c1b72878.png

来看看本质↓

56cb32cd90dd442798f392605d631a4c.png

 

经过计算结果就是-5

以上就是移位操作符的讲解

补充:>>x 中的x必须是正整数 

而所需移位的数字是整数

下面是全部代码↓

//移位操作符
#include<stdio.h>
int main()
{
	//按照一个数的正负 直接写出他的二进制形式就得到了他的原码
	//正数的原码 反码 补码 都是相同的
	//负数的原码 反码 补码 都是需要计算的
	//负数的反码就是符号位不变 其他的按位取反 就是反码
	//补码是反码+1
	//一个整型占四个字节也就是三十二的比特位
	int a = 10;
	//00000000000000000000000000001010 原码
	//00000000000000000000000000001010 反码
	//00000000000000000000000000001010 补码
	int b = -10;
	//10000000000000000000000000001010 原码
	//11111111111111111111111111110101 反码
	//11111111111111111111111111110110 补码

	//11111111111111111111111111110110 补码
	//10000000000000000000000000001001 ----*不是反码
	//10000000000000000000000000001010 原码

	//左移位
	int c = a << 1;
	int d = b << 1;
	//右移位  
	//逻辑右移(一般不见):右边丢弃 左边直接补0
	//算数右移(常见):右边丢弃 左边补充原来的符号位
	int e = -10;
	//10000000000000000000000000001010 原码
	//11111111111111111111111111110101 反码
	//11111111111111111111111111110110 补码
	int f = -10 >> 1;
	printf("a=%d\n", a);
	printf("c=%d\n", c);
	printf("b=%d\n", b);
	printf("d=%d\n", d);
	printf("e=%d\n", e);
	printf("f=%d\n", f);
	return 0;
}

78a86c11d26743c9a1e064f669323115.png

看完理解了可以去找一些练习去做做


 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值