当前位置:网站首页>【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。
边栏推荐
- [introduction to node basics] - node middle layer does interface forwarding to realize cross domain requests
- 南京银行提前批金融科技岗
- 七大排序--万字详解
- Comprehensive summary of software quality management practice
- 十年磨一剑,云原生分布式数据库PolarDB-X的核心技术演化
- 九张图纵观加密市场周期规律
- 亿级流量下的分布式锁优化方案!太好用了~
- 软考 系统架构设计师 简明教程 | 需求工程
- 分库分表真的适合你的系统吗?聊聊分库分表和NewSQL如何选择
- 中信期货是正规的期货公司吗,开户是否安全?
猜你喜欢

Distributed lock optimization scheme under 100 million traffic! It works so well~

幻核即将关闭?数字藏品还有未来吗?

用现代化的开发方法和思维,打跑遗留系统“拦路虎”

软件质量管理实践全面总结

数组中的逆序对

组合数。。。。

笔记——记录一个dynamic-datasource please check the setting of primary 问题解决

Liunx上杀死一进程

Visual full link log tracking

Hide the PHP version information in the response header of the website server
随机推荐
系统安全测试要怎么做,详细来说说
网络通信原理与IP地址的分配原理,网络七层由下往上分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层
【VSCODE】当前工作目录非当前文件夹/pathlib打印cwd路径错误
ES6 related interview question 3
1.赋值语句
幻核即将关闭?数字藏品还有未来吗?
隐藏网站服务器响应头中 PHP 版本信息
non-Boost Asio 笔记: UDP UART SocketCAN Multicast UDS
华泰证券开户安全吗是真的吗,是正规的吧
60 open-ended test questions, recite them and get a pay rise directly
php 中实现页面跳转的方法
PHP 将 ASCII 码转为字符串,字符串转换 ASCII 码
PHP 脚本对 txt 内容进行分页案例
Qt::WA_TransparentForMouseEvents 了解一下
BGP reflector, federal, routing rules
剑指 Offer II 031. 最近最少使用缓存
九张图纵观加密市场周期规律
Transfer software testing salary 10K | there is food in the hand and a bottom in the heart, which is the truth at all times
What are you doing at two in the morning?
Spark 内存管理机制 新版