操作符(移位 、位操作符)

一.移位操作符 移动的是二进制位 操作数只能是整数

 (1)<<左移 左边抛弃 右边补0

 (2)>>右移 逻辑右移/算术右移 取决于编译器的实现,常见的编译器都是算术右移

逻辑右移 :左边补0 右边丢弃

算术右移 :左边用原符号位填充,右边丢弃

 对于移位操作符,不要移动负数位,这个是标准未定义的。

代码示例:

#include<stdio.h>
int main()
{
	int a = 6;
	int b = (a << 1);
	//00000000000000000000000000000110
	//00000000000000000000000000001100
	printf("%d\n", b);//12
	printf("%d\n", a);//6
	return 0;
}

对于负数

#include<stdio.h>
int main()
{
	int a = -6;
	int b = (a << 1);
	//10000000000000000000000000000110
	//11111111111111111111111111111001
	//11111111111111111111111111111010  -6补码
	//11111111111111111111111111110100  b中得到的补码
	// 再次转换
	//10000000000000000000000000001011
	//10000000000000000000000000001100   -12

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

复合运算

#include<stdio.h>
int main()
{
	int num = -1;
	num = num >> 1;
	num >= 1;//复合
	return 0; 
}

二.位操作符

操作数必须是整数 操作的是二进制位
& 按位与 只要有0则为0 同时为1才为1
| 按位或 只要有1则为1 两个为0才为0
^ 按位异或  相同为0 相异为1
~ 按位取反

1.按位与 &

#include<stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a & b;
	//00000000000000000000000000000011   3的补码
	
	//10000000000000000000000000000101
	//11111111111111111111111111111010
	//11111111111111111111111111111011   -5的补码

	//00000000000000000000000000000011
	//11111111111111111111111111111011
	// &
	//00000000000000000000000000000011  -补码
	printf("%d", c);//3
	return 0;
}

2.按位或 |

#include<stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a | b;
	//00000000000000000000000000000011   3的补码

	//10000000000000000000000000000101
	//11111111111111111111111111111010
	//11111111111111111111111111111011   -5的补码

	//00000000000000000000000000000011
	//11111111111111111111111111111011
	// |
	//11111111111111111111111111111011   ---补码
	//10000000000000000000000000000100
	//10000000000000000000000000000101   --原码
	printf("%d", c);//-5
	return 0;
}

3.按位异或 ^

#include<stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a ^ b;
	//00000000000000000000000000000011   3的补码
	
	//10000000000000000000000000000101
	//11111111111111111111111111111010
	//11111111111111111111111111111011   -5的补码

	//00000000000000000000000000000011
	//11111111111111111111111111111011
	//^
	//11111111111111111111111111111100
	//10000000000000000000000000000011
	//10000000000000000000000000000100
	printf("%d", c);//-8
	return 0;
}

题目拓展:不创建临时变量,实现两个整数的交换。

//a^a=0;
//0^a=a;
#include <stdio.h>
int main()
{
	int a = 3;
	int b = 5;
	printf("交换前:a=%d b=%d\n", a, b);
	a = a ^ b;
	b = a ^ b;//a^b^b--->0---->a 等价于b=a
	a = a ^ b;//a^b^a--->0----->b 等价于a=b
	printf("交换后:a=%d b=%d\n", a, b);
	return 0;
}
//异或运算不会溢出

按位取反 ~

#include<stdio.h>
int main()
{
	int a = 0;
	int b = ~a;
	//00000000000000000000000000000000
	//11111111111111111111111111111111
	//10000000000000000000000000000000
	//10000000000000000000000000000001
	printf("%d\n", b);//-1
	return 0;
}

代码练习1:求一个整数在内存中二进制中1的个数

方法1:

//针对负数有问题
#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	int count = 0;
	while (n)
	{
		if (n % 2 == 0)
			count++;
		n /= 2;
	}
	printf("%d", count);
	return 0;
}

方法2:

//进阶
#include<stdio.h>
int main()
{
	unsigned int n = 0;
	scanf("%d", &n);
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
			count++;
		n /= 2;
	}
	printf("%d\n", count);
	return 0;
}

方法3:

//按位与 移位的方法
#include<stdio.h>
int main()
{
	int n = 0;
	int count = 0;
	scanf("%d", &n);
	int i = 0;
	for (i = 0; i < 32; i++)
	{
		if (((n >> i) & 1) == 1)
			count++;
	}
	printf("%d", count); 
	
}

方法4:

//n=n&(n-1)这个表达式能将n的二进制中最右边的1去掉
#include<stdio.h>
int main()
{
	int n = 0;
	int count = 0;
	scanf("%d", &n);
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	printf("%d\n", count);
	return 0;
}

代码练习2:

如何判断一个数是否是2的次方数:2的n次方二进制中只有一个1


//00000010//2
//00000100//4
//00000101//5
//00001000//8
//00001001//9
#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	if ((n & (n - 1)) == 0)
	{
		printf("%d是2的次方数\n", n);
	}
	else 
	{
		printf("%d不是2的次方数\n", n);
	}
	return 0;
}

代码练习3: 将13二进制序列的第五位修改为1,然后再改回0。

#include <stdio.h>
int main()
{
	int n = 13;
	//把第五位改成1
	n |= (1 << 4);
	printf("%d\n", n);
	//改成0
	n &= (~(1 << 4));
	printf("%d\n", n);
	return 0;
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值