C语言特别篇 (位运算) CSDN花神生涯


位运算符

  • 位运算的运算对象只能是整型或字符型数据,不能是实型数据

优先级:由高到低

👉~ 取反(单目运算符),0 ~ 1,1 ~ 0
→算术运算符
👉<<左移
👉>>右移
→关系运算符
👉 & 与:a&=2→a=a&2
👉 ^ 异或
👉 | 或
→逻辑运算符
复合赋值运算符 >>= . <<= . &= . ^= . |=

按位与运算 &

  • 二进制补码 按位与
  • 正数的原码,反码,补码一样
  • 和0作与运算为清零操作,和1作与运算保持不变

按位与规则
0&0=0,0&1=0
1&0=0,1&1=1

int main()
{
	char a=-3,b=-5,c;
	c=a&b;
	printf("%d\n",c);
	return 0;
}

计算过程

1.求-3的原码10000011,符号位负号为1
2.求-3的反码11111100,符号位不变,按位取反
3.求-3的补码11111101,反码+1
4.求-5的原码10000101
5.求-5的反码11111010
6.求-5的补码11111011
求按位与c=a&b
按照按位与规则相加 c=11111001(这也是补码)
按照十进制输出,已知补码求原码
1.求c的反码,11111000,也就是补码-1
2.求c的原码,10000111,符号位不变,其余位取反
3.二进制转换为十进制

程序功能如何实现将高4位清0,低4位保持不变

(与00001111(也就是0xf 十六进制的15)作与运算可以完成)

程序功能如何实现获取数据最后一位。其余位清零→可以判断这个数奇偶

(与1(00000001)作按位与运算,得0为偶数,得1为奇数)

int main()
{
	int a[10]={1,2,3,4,5,6,7,8,9,10},i;
	for(i=0;i<10;i++)
		if(a[i]&0x1==1)//判断是否为奇数
			printf("%d\n",a[i]);
	return 0;
}

按位或运算 |

  • 和1作或运算为置1操作,和0作或运算保持不变

0|0=0,0|1=1
1|0=1,1|1=1

int main()
{
	char a=060,b=017,c;
	c=a|b;
	printf("%d\n",c);
	return 0;
}

1,转换八进制a 和 b为二进制
2,作按位或运算,将得到c的补码
3,正数补码即原码,转换为十进制
(切记如果c的补码开头为1,则需要将补码转换为反码,再转换为原码)

将低四位置1,高四位不变

(和00001111(也就是0xf(16))作按位或运算)

按位取反运算 ~

int main()
{
	char a=5,b;
	b=~a;
	printf("%d\n",b);
	return 0;
}

1,取反得补码11111010
2.补码转原码10000110

int main()
{
	char c;
	c=~4&-3;
	printf("%d\n",c);
	return 0;
}

计算过程

1,解析:~4优先级较高,-3为整体,两者作按位与运算
2,将4取补码00000100
3,4的补码作按位取反11111011
4.取-3的原码,再去转换为补码
5,两者按位与运算,得补码
6,补码转原码再转十进制

按位异或运算^

  • 与0作异或运算结果不变,与1作异或运算结果取反
  • 两个相同的数异或运算,结果为0
  • 不同的数异或运算,结果为1

0 ^ 0=0,0 ^ 1=1
1 ^ 0=1,1 ^ 1=0

int main()
{
	char a=0xa,b=0x5,c;
	c=a^b;
	printf("%d\n",c);//输出15
	return 0;
}
将变量取反

(与11111111(也就是0xff)作按位异或运算)

int main()
{
	char a=0xf0;
	c=a^0xff;
	printf("%d\n",c);//输出15
	return 0;
}

计算过程

1,f0 变化为二进制11110000
2,ff 变化为二进制11111111
3,两者作按位异或运算,然后转换为十进制

将变量中间4为取反,其余位保持不变

(与00111100(也就是0x3c)作异或运算)
计算过程

十六进制3c的二进制怎么求:分开求,然后合体00110111
3的二进制0011
c的二进制0111
十六进制37的二进制:00110111
3的二进制0011
7的二进制0111

C

交换两个变量的值
int main()
{
	char a=3,b=4;
	a=a^b;
	b=b^a;
	a=a^b;
	printf("a=%d,b=%d\n",a,b);//输出15
	return 0;
}

计算过程

a:00000011
b:00000100
a= a^b:a=00000111
b=b^a:b=00000011,b已经更改为a
a=a^b:a=00000111,a已经更改为b

左移运算<<

  • 作用:将一个数的二进制数位全部左移若干位
  • 注意:对于无符号数左移后右补0,高位左移后溢出,舍弃(不论溢出1还是0,左舍右补)
  • 注意:无符号数无法表示负数
  • 左移1位,扩大2倍,左移n位,扩大2n
int main()
{
	unsigned char a,b;//unsigned是定义无符号数的关键字
	a=3<<1;//3左移一位
	b=3<<2;
	printf("a=%d,b=%d\n",a,b);//输出6,12
	return 0;
}

计算过程

1,3的二进制00000011
2,3左移1位00000110
3,3左移2位00001100

右移运算>>

  • 作用:将一个数的个二进制全部右移若干位
  • 注意:对于无符号数右移后左补0(左补右舍)
  • 注意:无符号数无法表示负数
  • 与左移运算相反,右移一位,相当于÷2,右移n位,相当于÷2n
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值