【C语言】位运算

本文详细介绍了C语言中的位逻辑运算符(包括按位取反、按位与、按位或、按位异或)以及移位运算符(左移和右移),并提供了示例代码和应用场景。
摘要由CSDN通过智能技术生成

【C语言】位运算



前言

可以使用C对变量中的个别位进行操作。您可能对人们想这样做的原因感到奇怪。这种能力有时确实是必须的,或者至少是有用的。C提供位的逻辑运算符和移位运算符。在以下例子中,我们将使用二进制计数法写出值,以便您可以了解对位发生的操作。在一个实际程序中,您可以使用一般的形式的整数变量或常量。例如不适用00011001的形式,而写为25或者031或者0x19。


一、位逻辑运算符

4个位运算符用于整型数据,包括char.将这些位运算符成为位运算的原因是它们对每位进行操作,而不影响左右两侧的位。请不要将这些运算符与常规的逻辑运算符(&& 、||和!)相混淆,常规的位的逻辑运算符对整个值进行操作。

1.按位取反: ~

一元运算符~将每个1变为0,将每个0变为1

例如:~(10010110)
01101001

//按位取反 ~
void test01()
{
	int num = 2;

	//00000000 00000000 00000000 00000010	
	//~按位取反后得到源码:11111111 11111111 11111111 11111101
	//计算机用补码方式存数据 负数的补码=源码符号位不变其余按位取反在加一
	//补码:10000000 00000000 00000000 00000011	//-3
	printf("~num = %d\n", ~num);	//-3
}

2.按位与(AND): &

二进制运算符&通过对两个操作数逐位进行比较产生一个新值。对于每个位,只有两个操作数的对应位都是1时结果才为1。否则为0。

例如:(10010011)&(01010010)=00010010

C也有一个组合的位与-赋值运算符:&=。下面两个将产生相同的结果:

val &= 0377
val = val & 0377

//按位与 &
void test02()
{
	//判断奇偶数
	int num = 123;
	if ((num & 1) == 1)
	{
		printf("num为奇数\n");

	}
	else
	{
		printf("num为偶数\n");
	}
}

3.按位或(OR): |

二进制运算符|通过对两个操作数逐位进行比较产生一个新值。对于每个位,如果其中任意操作数中对应的位为1,那么结果位就为1.

例如: (10010011)&(01010010)= 11010011

C也有组合位或-赋值运算符: |=

val |= 0377
val = val | 0377

//按位或 |
void test03()
{
	int num1 = 5;	//00000000 00000000 00000000 000000110
	int num2 = 3;	//00000000 00000000 00000000 000000011
	printf("num1 | num2=%d\n", num1 | num2);	//00000000 00000000 0000000 00000111   //7

}

4.按位异或:^

二进制运算符^对两个操作数逐位进行比较。对于每个位,如果操作数中的对应位有一个是1(但不是都是1),那么结果是1.如果都是0或者都是1则结果位0.(相同为0,不同为1)

例如:(10010011)^(01010010)=11000001

C也有一个组合的位异或-赋值运算符: ^=

val ^= 0377
val = val ^ 0377

交换两个数不需要临时变量,原理:

(10010011) //a
^(00100110) //b
=(10110101) //c

(10110101) //c
^(00100110)//b
10010011//a


//按位异或 ^
void test04()
{
	int num1 = 5;
	int num2 = 9;

	//数据交换

	/*(法一)
		int temo=num1;
		num1=num2;
		num2=temp;
	*/

	//(法二)
	num1 = num1 ^ num2;
	num2 = num1 ^ num2;
	num1 = num1 ^ num2;

	/*(法三)
		num1=num1+num2;
		num2=num1-num2;
		num1=numq-num2;
	*/
}

用法:

已知:10011010

  • 打开位

将位2打开
flag | 10011010
(10011010)
|(00000100)
=(10011110)

将所有位打开
flag | ~flag
(10011010)
|(01100101)
=(11111111)

  • 关闭位

flag & ~flag
(10011010)
&(01100101)
=(00000000)

  • 转置位
    转置(toggling)一个位表示如果该位打开,则关闭该位;如果该位关闭,则打开。您可以使用位异或运算符来转置。其思想是如果b是一个位(1或0),那么如果b为1则b^ 1为0,如果b为0,则1^ b为1。无论b的值是0还是1,0^b为b.

flag ^ 0xff
(10010011)
^(11111111)
=(01101100)


二、移位运算符

现在让我们了解一下C的移位运算符。移位运算符将位向左或向右移动。同样,我们仍将明确地使用二进制形式来说明该机制的工作原理。

1、左移: <<

左移运算符<<将其左侧操作数的值的每位向左移动,移动的位数由其右侧操作数指定。空出来的位用0填充,并且丢弃移出左侧操作数末端的位。在下面例子中,每位向左移动两个位置。

例如:(10001010) << 2
(00101000)

该操作将产生一个新位置,但是不改变其操作数。

1 << 1 = 2;
2 << 1 = 4;
4 << 1 = 8;
8 << 2 = 32

左移一位相当于原值*2.

//左移运算 <<
void test05()
{
	int num = 20;	//20*2^2;
	printf("%d\n", num <<= 2);	//80
}

2、右移: >>

右移运算符>>将其左侧的操作数的值每位向右移动,移动的位数由其右侧的操作数指定。丢弃移出左侧操作数有段的位。对于unsigned类型,使用0填充左端空出的位。对于有符号类型,结果依赖于机器。空出的位可能用0填充,或者使用符号(最左端)位的副本填充

//有符号值
(10001010) >> 2
(00100010) //在某些系统上的结果值

(10001010) >> 2
(11100010) //在另一些系统上的结果

//无符号值
(10001010) >> 2
(00100010) //所有系统上的结果值

void test06()
{
	int num = 20;	//  20/2
	printf("%d\n", num >>= 1);	//	10
}


用法:

移位运算符能够提供快捷、高效(依赖于硬件)对2的幂的乘法和除法

number << n number乘以2的n次幂
number >> n 如果number非负,则用number除以2的n次幂


总结

到这里这篇文章的内容就结束了,谢谢大家的观看,如果有好的建议可以留言喔,谢谢大家啦!

  • 34
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值