【C语言】/*移位操作符和位操作符*/

本文详细介绍了C语言中的移位操作符和位操作符,包括左移、右移、按位与、按位或、按位异或、按位取反等操作符的使用方法及规则,并通过实例展示了如何利用位操作进行整数交换、计算二进制中1的个数以及修改特定二进制位。

温馨提示:含"位"的操作符,操作数只能是整型,操作时用的是整型的补码

一、移位操作符:<<、>>

1. << 左移操作符,>> 右移操作符。(双目操作符)

2. 注1:移位操作符的操作数只能是整型

    注2 :对于移位运算符,不要移动负数位,这个是标准未定义的

4.1 左移操作符

1. 移位规则:左边丢弃、右边补0 (不管高位是什么该丢的丢)

#include <stdio.h>
int main()
{
	int m = 10;
	int n = m << 1;//m向左移动一位后赋值给n
	printf("m = %d\n", m);//10
	printf("n = %d\n", n);//20
	return 0;
}

2.  上面代码解析:

     正整数10的原码、反码、补码均相同,为 00000000 00000000 00000000 00001010

     

     因此n被赋值为20。

4.2 右移操作符

1. 移位规则:

    右移运算分两种:(采用哪种规则,取决于编译器的实现,大部分编译器上采用算术右移)

    ① 逻辑右移:右边丢弃,左边⽤0填充

    ② 算术右移:右边丢弃,左边⽤原该值的符号位填充

2. 警告:对于移位运算符,不要移动负数位,这个是标准未定义的

    例如: int num = 10;

                num>>-1;//err

#include <stdio.h>
int main()
{
	int num = -10;
	int n = num >> 1;
	printf("num = %d\n", num);//-10
	printf("n = %d\n", n);//-5
	return 0;
}

 3.  上面代码解析(在VS中采用的是算术右移):

       负整数10的原码、反码、补码均不同,

       原码 10000000 00000000 00000000 00001010

       反码 111111111 111111111 111111111  11110101

       补码 111111111 111111111 111111111  11110110

       

       补码转为原码:10000000 00000000 00000000 00000101

       因此n被赋值为-5。

二、位操作符:&、|、^、~

1. 位操作符有:(双目操作符)

    &      //按位与:有0则0

     |      //按位或:有1则1

    ^      //按位异或:相同为0,相异为1

    ~      //按位取反:全部取反

2. 注:位操作符的操作数只能是整型

3. 按位异或操作符的特点:a ^ a = 0,a ^ 0 = a,即按位异或自己为0,按位异或0为自己。

#include <stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	printf("%d\n", a & b);//3
	printf("%d\n", a | b);//-5
	printf("%d\n", a ^ b);//-8
	printf("%d\n", ~0);//-1
	return 0;
}

上面代码解析:

三、应用举例

3.1 例题1

//不能创建临时变量(第三个变量),实现两个整数的交换
#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	a = a ^ b;
	b = a ^ b;//a ^ b ^ b == a ^ 0 == a
	a = a ^ b;//a ^ b ^ a == b ^ 0 == b 
	printf("a = %d b = %d\n", a, b);//20 10
	return 0;
}

3.2 例题2

//求⼀个整数存储在内存中的⼆进制中1的个数
//方法一:
#include <stdio.h>
int main()
{
	int num = 10;
	int count = 0;//计数
	while (num)
	{
		if (num % 2 == 1)
			count++;
		num = num / 2;
	}
	printf("⼆进制中1的个数 = %d\n", count);
	return 0;
}

//方法二:(重点掌握方法二即可!!!)
//思路:① 如果要求整数15二进制表示形式中二进制位1的个数
//      让15的二进制按位与上1的二进制,根据有0则0的特点
//      只要被求数的二进制的最低位为1则,表达式返回的结果就为1
//      ② 我们可以通过移位操作符来操纵被求数的二进制的最低位,
//      或1的二进制位来达到最终目的
// 00000000 00000000 00000000 00001111 -- 10的补码
// 00000000 00000000 00000000 00000001 -- 1的补码
// 00000000 00000000 00000000 00000001 -- 10 & 1,由于符号位为0则-> 1
#include <stdio.h>
int main()
{
	int num = -1;
	int i = 0;
	int count = 0;//计数
	for (i = 0; i < 32; i++)
	{
		if (num & (1 << i))//只要不为0就count++
			count++;
	}
	printf("⼆进制中1的个数 = %d\n", count);
	return 0;
}

//方法三:
#include <stdio.h>
int main()
{
	int num = -1;
	int i = 0;
	int count = 0;//计数
	while (num)
	{
		count++;
		num = num & (num - 1);
	}
	printf("⼆进制中1的个数 = %d\n", count);
	return 0;
}

3.3 例题3

//编写代码将13⼆进制序列的第5位修改为1,然后再改回0

//13的2进制序列: 00000000000000000000000000001101
//将第5位置为1后:00000000000000000000000000011101
//将第5位再置为0:00000000000000000000000000001101

// 00000000000000000000000000001101 -- 13
// 00000000000000000000000000010000 -- 1<<4
// 00000000000000000000000000011101 -- a | (1 << 4),有1则1
// 11111111111111111111111111101111 -- ~(1 << 4)
// 00000000000000000000000000001101 -- a & ~(1 << 4),有0则0

#include <stdio.h>
int main()
{
	int a = 13;
	a = a | (1 << 4);
	printf("a = %d\n", a);
	a = a & ~(1 << 4);
	printf("a = %d\n", a);
	return 0;
}

   本篇文章已完结,谢谢支持哟 ^^ !!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值