当前位置:网站首页>【C语言基础】15 位运算
【C语言基础】15 位运算
2022-07-23 03:15:00 【一苇以航fp】
一、移位运算
| 运算符 | 含义 |
|---|---|
<< | 左移 |
>> | 右移 |
1.1 << 左移
- i << j
- 将 i 中的所有位向左移动 j 个位置,右边补 0;
- 所有小于 int 的类型,移位以 int 的方式来做,结果是 int 类型。
- x << 1 等价于 x *= 2
- x << n 等价于 x *= xn
- 一个数**每左移1位,等价于乘2**
1.2 >> 右移
- i >> j
- 将 i 中的所有位向左移动 j 个位置,右边补 0;
- 所有小于 int 的类型,移位以 int 的方式来做,结果是 int 类型。
- 对于 unsigned 类型,左边补 0;
- 对于 signed 类型,左边补原来的最高位数字(0或1,保持符号不变)
- x >> 1 等价于 x /= 2
- x >> n 等价于 x /= xn
- 一个数**每右移1位,等价于除2**
int a = 0x80000000;
unsigned int b = 0x80000000;
printf(" a = %d\n", a);
printf(" b = %u\n", b);
printf("a>>16 = %d\n", a>>16);
printf("b>>16 = %u\n", b>>16);
输出结果:
1.3 注意
左移或右移的位数不要设置为负数,否则将导致未定义行为。
二、按位运算
按位运算符:
| 运算符 | 含义 |
|---|---|
& | 按位与 |
| ` | ` |
~ | 按位取反 |
^ | 按位异或 |
2.1 &按位与
- 如果(x)i == 1 且 (y)i == 1,则 (x & y)i = 1。否则 (x & y)i = 0;
- 有0必为0,同是1才为1
- 和 0 相与 必为 0,和 1 相与 则不变
举例:
0101 1010 & 10001 100 = 0000 1000(5A & 8C = 08)
按位与常见应用:
- 让某一位或某些位为0:x & 0xFE(让x最低位为0)
- 取一个数中的一段: x & 0xFF(取x最低的1个字节,其余为0)
举例:
1010 0101 & 0xFE = A5 & FE = A4
1010 1010 1010 1010 & 0xFF = AAAA & FF = AA(125252 & FF = 252)
2.2 |按位或
- 如果(x)i == 1 且 (y)i == 1,则 (x | y)i = 1。否则 (x | y)i = 0;
- 有1必为1,同是0才为0
- 和 1 相或 必为 1,和 0 相或 则不变
按位与常见应用:
- 使得一位或几个位为1:x | 0x01(让x最低位为1)
- 把两个数拼接起来:0x00FF | 0xFF00 = 0xFFFF
2.3 ~按位取反
- ( ~x )i = 1 - ( x )i
- 01互换。
举例:
~1010 1010 = 0101 0101(~AA = 55)
按位取反与求补码不同:
- 按位取反是将各个位上的01翻转;
- ~1010 1010 = 0101 0101
- 求补码:
- 正数的补码等于原码;
- 负数的补码,符号位不变,其余位取反后加1.
2.4 ^按位异或
- 如果 ( x )i == ( y )i,那么( x ^ y )i = 0,否则为1;
- 相同为0,相异为1
- 对一个变量用同一个值异或两次,等于什么也没做。 x ^ y ^ y = x
2.5 逻辑运算和按位运算
逻辑运算与按位运算是不同的,不可混淆,但可以将逻辑运算视为将所有非0值变成1,再进行按位运算。
- 5 & 4 = 4 而 5 && 4 ——> 1 & 1 = 1
- 5 | 4 = 5 而 5 || 4 ——> 1 | 1 = 1
- ~4 = 3 而 !4 ——> !1 = 0
三、位运算举例
3.1 输出一个数的二进制数
int number;
scanf("%d", &number);
unsigned mask = 1u<<31; //unsigned与变量之间省略类型,默认是unsigned int类型
//1u表示为unsigned int类型的1
//1u<<31 = 10000...00(31个0)
for(; mask; mask>>=1){
//mask右移,始终每次只有一个1
printf("%d", number & mask ? 1 : 0);
}
printf("\n");
3.2 控制一个数的特定位
const unsigned int SBS = 1u<<2; //SBS = 00...0100
const unsigned int PE = 1u<<3; //PE = 00...01000
U0LCR |= SBS | PE; //让U0LCR的第2位和第3位为1,其余位不变(SBS|PE = 00...01100)
U0LCR &= ~(SBS | PE); //让U0LCR的第2位和第3位为0,其余位不变
四、位段
4.1 说明
- 把一个 int 的若干位组合成一个结构,特定的位形成一个位段,如下例的struct,通过结构内的成员来控制特定位。
struct{
unsigned int leading : 3; //成员后的冒号:后的数是该成员所占比特数
unsigned int FLAG1 : 1;
unsigned int FLAG2 : 1;
int trailing : 11;
};
4.2 举例
void prtBin(unsigned int number);
struct U0{
unsigned int leading : 3; //成员后的冒号:后的数是该成员所占比特数,从低位开始
unsigned int FLAG1 : 1;
unsigned int FLAG2 : 1;
int trailing : 27; //保证总共占32位,unsigned int所占位数
};
int main(){
struct U0 uu;
uu.leading = 2;
uu.FLAG1 = 0;
uu.FLAG2 = 1;
uu.trailing = 0;
printf("sizeof(uu)=%lu\n", sizeof(uu));
prtBin(*(int*)&uu); //将uu内的数据强制转换为int类型(本来是struct U0类型)
return 0;
}
void prtBin(unsigned int number)
{
unsigned mask = 1u<<31;
for(; mask; mask >>=1){
printf("%d", number & mask ? 1:0);
}
printf("\n");
}
输出结果:
说明:
- 最低的3位为uu.leading = 2,其次为 uu.FLAG1 = 0,uu.FLAG2 = 1。其余为 uu.trailing = 0。
- 若结构定义里 trailing 改为占据28位,则总结构位数超过32位,编译器会增加一个 int,输出的 sizeof(uu) = 8 。
4.3 注意
- 将特定位组合成位段之后,可直接位段的成员名称来访问。比移位、与、或更方便
- 编辑器会安排其中的位的排列,不具有可移植性,例如某些编辑器从最右端的位开始,有些从最左端开始。
- 当所需的位超过一个 int 时,会采用多个 int。
边栏推荐
- 开源进销存系统,10分钟搞定,建议收藏!
- non-Boost Asio 笔记: UDP UART SocketCAN Multicast UDS
- 利用反射对修饰符为final的成员变量进行修改
- 卡特兰数---
- 数学向量基本知识
- 清华、AIR、腾讯 | 3D等变分子图预训练
- [notes on the practice of node middle tier (I)] -- building the project framework
- Excel简单使用宏
- Hide the PHP version information in the response header of the website server
- 《nlp入门+实战:第一章:深度学习和神经网络》
猜你喜欢
随机推荐
31岁才转行程序员,目前34了,我来说说我的经历和一些感受吧...
实现多层级条件查询(类似京东多层级添加查询)
Multi-UA V Cooperative Exploringfor the Unknown Indoor EnvironmentBased on Dynamic Target Tracking翻译
PHP 将 ASCII 码转为字符串,字符串转换 ASCII 码
PHP 脚本对 txt 内容进行分页案例
The gospel of small and medium-sized enterprises is coming! Jnpf is becoming popular, helping business digital upgrading
spark分区算子partitionBy、coalesce、repartition
华泰证券可以网上开户吗安全吗
华泰证券开户安全吗是真的吗,是正规的吧
技术分享 | 大事务阻塞 show master status
这个工具,补齐了 JMeter性能分析最后一公里短板
Can Huatai Securities open an account by itself? Is it safe? How long will it take to finish
软件质量管理实践全面总结
开源进销存系统,10分钟搞定,建议收藏!
PHP RSA generates public key and private key PSA2 encryption and decryption
软考 系统架构设计师 简明教程 | 逆向工程
枚举类的使用和实现
Kill a process on Linux
Baidu map eagle eye track service
1.赋值语句









