12-bit_operation
来源:互联网 发布:java实战项目视频 编辑:程序博客网 时间:2024/04/29 19:44
位运算符
在C语言中的位运算符
& 按位与
| 按位或
^ 按位亦或
<< 左移
>> 右移
~ 按位取反(单目运算符)
结合律 a&b&c <=> (a&b)&c <=> a&(b&c)
交换律 a&b <=> b&a
左移和右移注意点
左移运算符<<将运算数的二进制位左移,高位丢弃,低位补0;
右移运算符>>把运算数的二进制位右移,高位补符号位,低位丢弃;
0x1 << 2 + 3 的值会是什么
实际上+-运算的优先级高于移位操作
防错准则:
避免位运算符/逻辑运算符和数学运算符同时出现在一个表达式中;
当位运算符/逻辑运算符和数学运算符同时参与运算时,尽量使用()来表达计算次序;
如何交换两个变量的值
#include <stdio.h>
#define SWAP1(a,b) \
{ \
int temp = a; \
a = b; \
b = temp; \
} //需要使用额外的变量才可以完成
#define SWAP2(a,b) \
{ \
a = a + b; \
b = a - b; \
a = a - b; \
} //a和b很大的时候a+b会溢出
#define SWAP3(a,b) \
{ \
a ^= b; \
b ^= b; \
a ^= b; \
}
/*
* a ^= b; => (a^b)
* b ^= a; => b^(a^b) => a^(b^b) => a^0 => a
* a ^= b; => (a^b)^(a) => a^a^b => 0^b =>b
* 该方法不用借助其他变量,也不会溢出
* 而且运算效率高于普通的数学运算
*/
int main() {
int a = 1;
int b = 2;
SWAP1(a,b);
SWAP2(a,b);
SWAP3(a,b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
练习:
假设有一数列A,其中的自然数都是出现偶数次,只有一个自然数出现的次数为奇数次,编程找出这个自然数;
方法1:
1.排序
2.遍历查找
//缺点,排序太耗时
方法2:
1.遍历,找出最大值max
2.申请array[max]
3.遍历,将array[A[i]]++;
4.判断哪个下标对应的数值是奇数
方法3;
考虑到亦或位操作及交换律,将所有元素亦或操作即可得到该自然数
#include <stdio.h>
int main() {
int a[] = {2, 3, 3, 5, 7, 2, 2, 2, 5, 7, 1, 1, 9};
int find = 0;
int i = 0;
for (i = 0; i < sizeof(a)/sizeof(*a); i++) {
find ^= a[i];
}
printf("find = %d\n", find);
return 0;
}
思考:
&&,||,!与&,|,~的意义是否相同?它们可以在条件表达式中交替使用码?
//不同,一种是逻辑操作,一种是位操作;
1<<32的结果是什么?1<<-1的结果又是什么?//0,0
在C语言中的位运算符
& 按位与
| 按位或
^ 按位亦或
<< 左移
>> 右移
~ 按位取反(单目运算符)
结合律 a&b&c <=> (a&b)&c <=> a&(b&c)
交换律 a&b <=> b&a
左移和右移注意点
左移运算符<<将运算数的二进制位左移,高位丢弃,低位补0;
右移运算符>>把运算数的二进制位右移,高位补符号位,低位丢弃;
0x1 << 2 + 3 的值会是什么
实际上+-运算的优先级高于移位操作
防错准则:
避免位运算符/逻辑运算符和数学运算符同时出现在一个表达式中;
当位运算符/逻辑运算符和数学运算符同时参与运算时,尽量使用()来表达计算次序;
如何交换两个变量的值
#include <stdio.h>
#define SWAP1(a,b) \
{ \
int temp = a; \
a = b; \
b = temp; \
} //需要使用额外的变量才可以完成
#define SWAP2(a,b) \
{ \
a = a + b; \
b = a - b; \
a = a - b; \
} //a和b很大的时候a+b会溢出
#define SWAP3(a,b) \
{ \
a ^= b; \
b ^= b; \
a ^= b; \
}
/*
* a ^= b; => (a^b)
* b ^= a; => b^(a^b) => a^(b^b) => a^0 => a
* a ^= b; => (a^b)^(a) => a^a^b => 0^b =>b
* 该方法不用借助其他变量,也不会溢出
* 而且运算效率高于普通的数学运算
*/
int main() {
int a = 1;
int b = 2;
SWAP1(a,b);
SWAP2(a,b);
SWAP3(a,b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
练习:
假设有一数列A,其中的自然数都是出现偶数次,只有一个自然数出现的次数为奇数次,编程找出这个自然数;
方法1:
1.排序
2.遍历查找
//缺点,排序太耗时
方法2:
1.遍历,找出最大值max
2.申请array[max]
3.遍历,将array[A[i]]++;
4.判断哪个下标对应的数值是奇数
方法3;
考虑到亦或位操作及交换律,将所有元素亦或操作即可得到该自然数
#include <stdio.h>
int main() {
int a[] = {2, 3, 3, 5, 7, 2, 2, 2, 5, 7, 1, 1, 9};
int find = 0;
int i = 0;
for (i = 0; i < sizeof(a)/sizeof(*a); i++) {
find ^= a[i];
}
printf("find = %d\n", find);
return 0;
}
思考:
&&,||,!与&,|,~的意义是否相同?它们可以在条件表达式中交替使用码?
//不同,一种是逻辑操作,一种是位操作;
1<<32的结果是什么?1<<-1的结果又是什么?//0,0
0 0
- 12-bit_operation
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 12
- 11-logical_operation_symbol
- 如何将大硬盘对拷到小硬盘
- echarts+extjs3.x结合
- [菜鸟实录]Python进行RSA加密
- strace
- 12-bit_operation
- Linux电源管理_Wakeup events framework--(二)
- android ActivityManagerService 源码分析----Activity管理(二)
- Windows Phone 8.1中绑定数据转换
- 汇编第一操作数&第二操作数的区别
- CMake学习(1)---简单程序与库
- android 学习随笔(屏幕的横屏和竖屏)
- java.lang.NullPointerException at org.hibernate.type.LongType.next(LongType.java
- Oracle开发专题之:%TYPE 和 %ROWTYPE(转)