C语言【初阶】--移位和位操作符详解

目录

 移位操作符

   1.整数的二进制表示形式 

   2.原码 、反码和补码

原码

反码

 补码

 左移和右移操作符

   1.左移过程

   2.右移过程

位操作符 

    1.&  按(二进制位)与操作

   2.|   按(二进制位)或操作 

   3.^   按(二进制位)异或操作


 移位操作符

   1.整数的二进制表示形式 

整数的二进制表示形式有3种:原码反码补码 

一个整数是4个字节也就是32bit位,所以一个整数写成二进制序列就是32个bit位

而对于有符号的整数来说,最高位(从左边数第一个)的那1位是符号位:

符号位是1,表示为负数

符号位是0,表示为正数。 

但对于无符号整数来说,没有符号位一说,所有位都是有效位。(无符号嘛,只能表示正数)

对于正的整数来说, 原码、反码、补码相同,无需计算。

对于负的整数来说,原码、反码、补码是需要计算的。

下面我们来谈谈原码、反码和补码。

   2.原码 、反码和补码

  • 原码

概念:按照数值的正负,直接写出的二进制序列就是原码。 

举个列子:

  • 反码

概念:原码的符号位保持不变,其他位按位取反 

如下:

  •  补码

概念:反码的二进制序列+1,得到的即为补码 

如下:

 注:整数在内存中存储的都是其补码的二进制序列。

        整数在计算的时候也是使用的补码。(很重要)

 左移和右移操作符

//左移
int main()
{
	int m = 7;
	int n = m << 1;
	printf("%d\n", n);
	printf("%d\n",m);
	return 0;
}

 这里我们来解析下左移的过程。

   1.左移过程

运算规则:左边丢弃,右边补0

 

 这里通过代码运行结果也可验证:

这里m只是参与运算,所以其本身的值并不会改变。

而通过最终的结果可以看到,左移一位相当于原来的值乘2

下面看负数左移的过程

int main()
{
	int m = -7;
	int n = m << 1;
	printf("%d\n", n);
	printf("%d\n",m);
	return 0;
}

 

结果:

   

   2.右移过程

两种右移方式:

  1. 算术右移
  2. 逻辑右移 
int main()
{
	int a = -10;
	int b = a >> 1;
	printf("a=%d\n", a);
	printf("b=%d\n", b);
}

运行结果:

 可知,编译器采用的为算术右移。这里注意:不同的编译器可能选择不同的右移方式。

位操作符 

&  按位与

|    按位或

^   按位异或 

注意:它们的操作数只能是整数

    1.&  按(二进制位)与操作

运算规则:1&1=1;1&0=0;0&1=0;0&0=0

int main()
{
	int a = 3;
	int b = -5;
	int c = a & b;
	//00000000000000000000000000000011--3的补码
	//11111111111111111111111111111011-- -5的补码
	//00000000000000000000000000000011--按位与操作后
	printf("%d\n", c);
}

 可知c的结果为:3

  • 获取最低位的方法
int main()
{
	int a = 3;
	int ch = a & 1;
	//如此可得最低位的数字是什么
	printf("%d\n", ch);
	return 0;
}

 由此可知3的二进制序列最低位是:1

   2.|   按(二进制位)或操作 

运算规则:0 | 0= 0 , 1 | 0= 1 , 0 | 1= 1 , 1 | 1= 1  

int main()
{
	int a = 3;
	int b = -5;
	int c = a | b;
//00000000000000000000000000000011--3的补码
//11111111111111111111111111111011-- -5的补码
//11111111111111111111111111111011--按位或操作后所得补码
//10000000000000000000000000000101--转为了原码
	printf("%d\n", c);
	return 0;
}

 可知c的结果为:-5

   3.^   按(二进制位)异或操作

运算规则:两数相同为0,相异为1 

int main()
{
	int a = 3;
	int b = -5;
	int c = a ^ b;
// 00000000000000000000000000000011--3的补码
// 11111111111111111111111111111011-- -5的补码
// 11111111111111111111111111111000--按位异或后所得补码
// 10000000000000000000000000001000--转为了原码
	printf("%d\n", c);
	return 0;
}

 可知c的结果为:-8

 总结:学习这部分知识时,建议大家先提前了解下10进制与2进制间的相互转换,这样学这部分内容时理解的会更深刻。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡闹的猫.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值