位操作符和左右移操作符详解

位操作符:

(1)按位与—— &

(2)按位或—— |

(3)按位异或—— ^

注意:位操作符只能用于整数!!!

左右移操作符:

(1)左移操作符—— << 

(2)右移操作符—— >>

注意:左右移操作符只能用于整数!!!

1、按位与——&

如果比较的两个位中有一个为0则结果为0,

如:        int a=2;         a的二进位为 000000000000000000000000000000010

               int b=11;       b的二进位为 000000000000000000000000000010011

则        a&b=2;          其二进制表示为000000000000000000000000000000010

此处a&b恰好为a实属偶然

2、按位或—— |

如果比较的两个位中有一个为1则结果为1

如:        int a=2;         a的二进位为 000000000000000000000000000000010

               int b=11;       b的二进位为 000000000000000000000000000010011

则          a | b=11;         其二进制表示为000000000000000000000000000010011

此处a|b恰好为b实属偶然

3、按位异或—— ^

如果比较的两个位相同则为0,不同则为1。

如:        int a=2;         a的二进位为 000000000000000000000000000000010

               int b=11;       b的二进位为 000000000000000000000000000010011

则           a ^ b=9;         其二进制表示为000000000000000000000000000010001

4、左移操作符—— <<

左侧(最高位)丢弃,右边补0;其作用相当于 *2

如:

a 的二进制位表示为: 000000000000000000000000000000001

a<<1   

 5、右移操作符——>>

右移操作的过程有两种可能:

(1)算术右移:右边丢弃,左边补符号位

(2)逻辑右移:右边丢弃,左边补0

这两种可能是取决于编译器的,在VS中是采用算术右移的

 例如 

        a 的原码为  100000000000000000000000000000101

        a 的反码为  11111111111111111111111111111010

        a 的补码为  11111111111111111111111111111011

(对于整形在内存中的存储形式还不明白的朋友,可以查看我的上篇的博客,写的很全)

发生右移操作后

        b的补码为:11111111111111111111111111111101

        b的反码为:11111111111111111111111111111100

        b的原码为:10000000000000000000000000000000011

        因此b的值为 -3

左右移操作并不影响a本身的值!!!

6、用到按位操作符的一些编程(有点巧妙)

例题1  求一个数的二进制位中1的个数

方法一:

//方法一:
void Number1()
{
	int a,count=0,i;
	printf("求一个数二进制位中1的个数,请输入该数:");
	scanf("%d", &a);
	for (i = 0; i < 32; i++)
	{
		//a>>i不改变a的值,只有a=a>>i才会改变a的值
		if ((a >> i) & 1 == 1)
		{
			count++;
		}
	}
	printf("%d\n",count);
}

方法二:

//方法二:
//注意!!这个方法有一个关键点,就是n要为unsigned int
//当n为有符号负数,n%2要么为0要么为-1,最终count始终为0,所以要把它当成无符号整形
void Number2()
{
	int count=0;
	unsigned int n;
	printf("求一个数二进制位中1的个数,请输入该数:");
	scanf("%u", &n);
	while (n)
	{
		if (n % 2 == 1)
		{
			count++;
		}
		n = n / 2;
	}
	printf("%d\n", count);
}

方法三:

//方法三:
//非常神奇!!!
//n=n&(n-1)
// n=13   1101 - n  1100 - n-1
// 1100 - n   1011 - n-1
// 1000 - n   0111 - n-1
// 0000 - n 停止
void Number3()
{
	int count = 0,n;
	printf("求一个数二进制位中1的个数,请输入该数:");
	scanf("%d", &n);
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	printf("%d\n",count);
}

例题二   判断一个数是不是2的幂次方

//n&(n-1)的另一种应用
//用来判断n是不是2的幂次方
//如果n是2的幂次方(正数),则它的补码中只有一个1,此时n^(n-1)==0
void especial()
{
	int n;
	printf("求一个数是不是2的幂次方,请输入该数:");
	scanf("%d", &n);
	if ((n & (n - 1) )== 0)
	{
		printf("是\n");
	}
	else
		printf("不是\n");
}

例题三 求两个数中不同位的个数

方法一:

//方法一:
void Diff1()
{
	int m, n,diffcount=0,i;
	printf("求两个数二进制位不同位的个数,请输入这两个数:");
	scanf("%d%d", &m, &n);
	for (i = 0; i < 32; i++)
	{
		if (((m >> i) & 1) != ((n >> i) & 1))
		diffcount++;
	}
	printf("%d\n", diffcount);
}

 方法二:

//方法二:
//^(异或操作符),如果位相同则取0,不同取1
void Diff2()
{
	int m, n, diffcount = 0;
	printf("求两个数二进制位不同位的个数,请输入这两个数:");
	scanf("%d%d", &m, &n);
	int tmp = m ^ n;//相同则为0,不同则为1,接下来就是求tmp补码中1的个数
	while (tmp)
	{
		tmp = tmp & (tmp - 1);
		diffcount++;
	}
	printf("%d\n", diffcount);
}

例题四  不创建第三个变量就可以交换两个数的值

//不创建第三个变量就可以交换两个数的值
void Exchange()
{
	int a, b;
	printf("不需要引入第三个变量就可以交换两个数的值,请输入这两个数:");
	scanf("%d%d", &a, &b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("%d %d", a, b);
}

例题五 打印一个数二进制形式的奇数位和偶数位 

//打印一个数二进制中奇数位的数,偶数位的数,设最右边的为第一位
//如15打印的效果为:
//奇数位:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
//偶数位:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
void Printodd()
{
	int n,i;
	printf("打印一个数的奇数位和偶数位,请输入这个数:");
	scanf("%d", &n);
	printf("奇数位:");
	for (i = 30; i >= 0; i-=2)
	{
		printf("%d ", (n >> i) & 1);
	}
	printf("\n");
	printf("偶数位:");
	for (i = 31; i >= 1; i-=2)
	{
		printf("%d ", (n >> i) & 1);
	}
	printf("\n");
}

例题六 不使用乘法运算完成2的n次方功能;例如:输入2,则输出4;输入10,则输出1024

int main()
{
    int n;
    scanf("%d",&n);
    printf("%d",(1<<n));
    return 0;
}

 左右移操作符和位操作符的介绍到这里就结束啦!!!希望这篇博客对你有帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值