复习c语言深度剖析(16)—位运算符分析

1.C语言中的位运算符

位运算符直接对bit位进行操作,其效率最高

2. 左移和右移注意点

左操作数必须为整型类型:char和short被隐式转换为int后进行移位操作
右操作数的范围必须为:[0,31],其他值属未定义行为,不同编译器处理不同。
左移运算符 << 将运算数的二进制位左移:规则为高位丢弃,低位补0
右移运算符 >> 把运算数的二进制位右移:规则为高位补符号(0或者1),低位丢弃
有符号整数,算术右移,高位补符号位;
无符号整数,逻辑右移,高位补0;
3. 有趣的问题:0x1 << 2 + 3 的值会是什么?

A:先算0x1<<2再把中间结果加3 ,最终为7。 
B:我觉得先算2 + 3 ,所以结果为32。// 10 0000
C:可以这么混合计算吗? 
#include <stdio.h>
#include <stdlib.h>

int main()
{
printf("%d\n", 3 << 2); // 3<<2 ===> 0x11<<2 ===>1100,即12
printf("%d\n", 3 >> 1); // 0x11<<1, 即1
printf("%d\n", -1 >> 1); // 0x1111 >> 1 ,即0x1111,仍为1
printf("%d\n", 0x01 << 2 + 3); // 相当于0x01<<(2+3),即32

printf("%d\n", 3 << -1); // oops!右操作数必须为[0,31],不同编译器处理方式不同

system("pause");

return 0;

}
运行结果:
4. 小贴士——防错准则

避免位运算符、逻辑运算符和数学运算符同时出现在一个表达式中
当位运算符,逻辑运算符和数学运算符需要同时参与运算时,尽量使用括号()表达达计算次序。
小技巧
左移n位相当于乘以2的n次方,但效率比数学运算符高
右移n位相当于除以2的n次方,但效率比数学运算符高
5.编程实验

交换两个整型变量的值
#include <stdio.h>
#include <stdlib.h>

// 利用中间变量交换
#define SWAP1(a, b)
{
int t = a;
a = b;
b = t;
}

// 利用部分和来交换
#define SWAP2(a, b)
{
a = a + b;
b = a - b;
a = a - b;
}

// 利用异或运算
#define SWAP3(a, b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}

int main()
{
int a = 1;
int b = 2;

printf("a = %d\n", a);
printf("b = %d\n", b);

SWAP3(a, b);

printf("a = %d\n", a);
printf("b = %d\n", b);

system("pause");

return 0;

}
运行结果:
6. 位运算与逻辑运算不同

位运算没有短路规则,每个操作数都参与运算
位运算的结果为整数,而不是0或1
位运算符优先级高于逻辑运算优先级
7.编程实验

混淆概念的判断条件
#include <stdio.h>

int main()
{
int i = 0;
int j = 0;
int k = 0;

// 注意位运算,不会短路
if( ++i | ++j & ++k )
{
    printf("Run here...\n");
}

printf("i = %d\n", i); // 1
printf("j = %d\n", j); // 1
printf("k = %d\n", k); // 1

return 0;

}
#include<stdio.h>

int main()
{
int i = 0;
int j = 0;
int k = 0;

// 注意是逻辑运算,短路
if (++i || ++j && ++k) // &&优先高于||
{
    printf("Run here...\n");
}

printf("i = %d\n", i); // 1
printf("j = %d\n", j); // 0
printf("k = %d\n", k); // 0

return 0;

}
8. 小结

位运算符只能用于整数类型
左移和右移运算符的右操作数范围必须为[0,31]
位运算的没有短路规则,所有操作数均会求值。
位运算的效率高于四则运算和逻辑运算
运算优先级:四则运算 > 位运算 > 逻辑运算
————————————————
版权声明:本文为CSDN博主「小虾米_2018」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_22847457/article/details/98845457

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值