16.运算符-位运算符
16.1 知识点
位运算符是什么
位运算符主要用数值类型进行计算。它将数值转换为二进制,再进行位运算。
位与(&)
基本规则
- 连接两个数值进行位计算,将数值转为二进制。
- 对位运算,有 0 则 0。
short a = 1; // 001
short b = 5; // 101
short result = a & b;
cout << result << endl; // 1
// 001
//& 101
// 001 = 1
a = 3; // 011
b = 19; // 10011
result = a & b;
cout << result << endl; // 3
// 00011
//& 10011
// 00011 = 3
多个数值进行位运算
没有括号时,从左到右依次计算。
a = 1; // 00001
b = 5; // 00101
short c = 19; // 10011
result = a & b & c;
cout << result << endl; // 1
// 00001
//& 00101
// 00001 = 1
//& 10011
// 00001 = 1
位或(|)
基本规则
- 连接两个数值进行位计算,将数值转为二进制。
- 对位运算,有 1 则 1。
- 多个数值连续计算规则相同。
a = 1; // 001
b = 5; // 101
result = a | b;
cout << result << endl; // 5
// 001
//| 101
// 101 = 5
a = 5; // 00101
b = 10; // 01010
c = 20; // 10100
result = a | b | c;
cout << result << endl; // 31
// 00101
//| 01010
// 01111
//| 10100
// 11111 = 1 + 2 + 4 + 8 + 16 = 31
异或(^)
基本规则
- 连接两个数值进行位计算,将数值转为二进制。
- 对位运算,相同为 0,不同为 1。
a = 5; // 00101
b = 10; // 01010
result = a ^ b;
cout << result << endl; // 15
// 00101
//^ 01010
// 01111 = 15
a = 10; // 1010
b = 11; // 1011
c = 4; // 0100
result = a ^ b ^ c;
cout << result << endl; // 5
// 1010
//^ 1011
// 0001
//^ 0100
// 0101 = 5
位取反(~)
基本规则
- 写在数值前面,将数值转为二进制。
- 对位运算,0 变 1,1 变 0。
a = 5; // 0000 0000 0000 0101
// 取反得到:1111 1111 1111 1010 是补码。
// 补码转换成源码二进制后,再转为十进制即为最终值。
a = ~a; // 1111 1111 1111 1010 - 1 = 1111 1111 1111 1001 = 1000 0000 0000 0110 = -6
cout << a << endl; // -6
左移(<<)和右移(>>)
左移规则
让一个数的二进制数进行左移,右侧加 0。
a = 5; // 0000 0000 0000 0101
result = a << 5;
// 1 位 1010
// 2 位 10100
// 3 位 101000
// 4 位 1010000
// 5 位 10100000 = 32 + 128 = 160
cout << result << endl; // 160
a = 128; // 0000 0000 1000 0000
// 如果左移时将某位为 1 的数移出范围,会直接丢弃。
result = a << 15;
cout << result << endl; // 0
右移规则
右移几位,右侧去掉相应的位数。
a = 5; // 101
// 1 位 10
// 2 位 1
result = a >> 2;
cout << result << endl; // 1
位运算符支持复合运算符
支持 &=
、|=
、^=
、<<=
、>>=
等复合运算符。
a = 5;
a &= 1;
// 101
// 001
// 001
cout << a << endl; // 1
位运算符的优先级
运算符本身的优先级
- 位取反(~)
- 左移、右移(<<、>>)
- 位与(&)
- 位异或(^)
- 位或(|)
int i = 1 | 2 ^ 3 & 2 << 1;
cout << i << endl; // 3
// 2 << 1 => 10 << 1 = 100
// 3 & 100 => 011 & 100 = 000 = 0
// 2 ^ 000 => 10 ^ 00 = 10
// 1 | 10 => 01 | 10 = 11 = 3
与其他运算符的优先级比较
从高到低排列:
- 算术运算符。
- 位运算符。
- 关系运算符。
- 逻辑运算符。
注意:cout 中的 << 被重新定义,不再是左移功能,而是用于控制台打印。
它的优先级仍基于位运算符,因此需要注意优先级问题。
// <<优先级高于||,先执行cout << false,输出0并返回cout对象,
// 再与true做||运算,结果未体现,只看到0输出
cout << false || true;//0
// 括号改变优先级,先算括号里false || true,结果为true,
// 再由cout输出,true转整数1输出,所以看到1
cout << (false || true);//1
16.2 知识点代码
Lesson16_运算符_位运算符.cpp
#include <iostream>
using namespace std;
int main()
{
std::cout << "位运算符\n";
#pragma region 知识点一 位运算符是什么
//位运算符 主要用数值类型进行计算的
//将数值转换为2进制 再进行位运算
#pragma endregion
#pragma region 知识点二 位与 &
// 1.基本规则
// 连接两个数值进行位计算 将数值转为2进制
// 对位运算 有0则0
short a = 1;//001
short b = 5;//101
short result = a & b;
cout << result << endl;//1
// 001
//& 101
// 001 = 1
a = 3; //011
b = 19; //10011
result = a & b;
cout << result << endl;//3
// 00011
//& 10011
// 00011 = 3
// 2.多个数值进行位运算
// 没有括号时 从左到右 依次计算
a = 1; // 00001
b = 5; // 00101
short c = 19;// 10011
result = a & b & c;
cout << result << endl;//1
// 00001
//& 00101
// 00001 = 1
//& 10011
// 00001 = 1
#pragma endregion
#pragma region 知识点三 位或 |
// 基本规则
// 连接两个数值进行位计算 将数值转为2进制
// 对位运算 有1则1
// 多个数值连续计算和之前规则相同
a = 1;//001
b = 5;//101
result = a | b;
cout << result << endl;//5
// 001
//| 101
// 101 = 5
a = 5; //00101
b = 10; //01010
c = 20; //10100
result = a | b | c;
cout << result << endl;//31
// 00101
//| 01010
// 01111
//| 10100
// 11111 = 1 + 2 + 4 + 8 + 16 = 31
#pragma endregion
#pragma region 知识点四 异或 ^
// 基本规则
// 连接两个数值进行位计算 将数值转为2进制
// 对位运算 相同为0 不同为1
a = 5; //00101
b = 10; //01010
result = a ^ b;
cout << result << endl;//15
// 00101
//^ 01010
// 01111 = 15
a = 10; // 1010
b = 11; // 1011
c = 4; // 0100
result = a ^ b ^ c;
cout << result << endl;//5
// 1010
//^ 1011
// 0001
//^ 0100
// 0101 = 5
#pragma endregion
#pragma region 知识点五 位取反 ~
// 基本规则
// 写在数值前面 将数值转为2进制
// 对位运算 0变1 1变0
a = 5; // 0000 0000 0000 0101
// 0000 0000 0000 0101 取反得到的是 1111 1111 1111 1010 1111 1111 1111 1010是补码 要转换成源码二进制后转成10进制 就是打印出来的最终值
// 补码 反码 原码
a = ~a; // 1111 1111 1111 1010 - 1 = 1111 1111 1111 1001 = 1000 0000 0000 0110 = -6
cout << a << endl;//-6
#pragma endregion
#pragma region 知识点六 左移 << 和 右移 >>
// 规则 让一个数的2进制数进行左移和右移
// 左移几位 右侧加几个0
a = 5; // 0000 0000 0000 0101
result = a << 5;
// 1位 1010
// 2位 10100
// 3位 101000
// 4位 1010000
// 5位 10100000 = 32 + 128 = 160
cout << result << endl;//160
a = 128;// 0000 0000 1000 0000
//如果左移 将某一位为1的数 移出超过位数范围了 会直接丢弃掉
result = a << 15;
cout << result << endl;//0
// 右移几位 右侧去掉几个数
a = 5;//101
// 1位 10
// 2位 1
result = a >> 2;
cout << result << endl;//1
#pragma endregion
#pragma region 知识点七 位运算符支持复合运算符
// &= 、 |= 、 ^= 、 <<= 、 >>=
//注意:复合运算符也可称为 双目运算符
//它们两的作用是一样的 都是用自己和另外一个数去进行位运算
//a = a & 1;
a = 5;
a &= 1;
//101
//001
//001
cout << a << endl;//1
#pragma endregion
#pragma region 知识点八 位运算符的优先级
//位运算符本身
//运算优先级从高到低排列
// 位取反 ~
// 左移右移 <<、>>
// 位与 &
// 位异或 ^
// 位或 |
int i = 1 | 2 ^ 3 & 2 << 1;
cout << i << endl;//3
// 2 << 1 => 10 << 1 = 100
// 3 & 100 => 011 & 100 = 000 = 0
// 2 ^ 000 => 10 ^ 00 = 10
// 1 | 10 => 01 | 10 = 11 = 3
//和其他运算符比较
//运算优先级从高到低排列
//算数运算符
//位运算符
//关系运算符
//逻辑运算符
// 注意:cout 中的 << 符号 被重新定义了 不在是左移功能 而是用于进行控制台打印
// 但是它的优先级还是基于 位运算符 来判断的
// 所以 我们在使用它打印时 需要注意优先级问题 最后在后面打一个括号
// <<优先级高于||,先执行cout << false,输出0并返回cout对象,
// 再与true做||运算,结果未体现,只看到0输出
cout << false || true;//0
// 括号改变优先级,先算括号里false || true,结果为true,
// 再由cout输出,true转整数1输出,所以看到1
cout << (false || true);//1
#pragma endregion
}
16.3 练习题
35 << 4 和 66 >> 1 的结果为?
// .... 1 1 1 1 1 1 1 1 1
// 256 128 64 32 16 8 4 2 1
// 100011 << 4 = 1000110000 = 16 + 32 + 512 = 560
cout << (35 << 4) << endl; // 560
// 1000010 >> 1 = 100001 = 1 + 32 = 33
cout << (66 >> 1) << endl; // 33
99 ^ 33 和 76 | 85 的结果为?
// 99 ^ 33
// 1100011
//^ 0100001
// 1000010 = 2 + 64 = 66
cout << (99 ^ 33) << endl; // 66
// 76 | 85
// 1001100
//| 1010101
// 1011101 = 1 + 4 + 8 + 16 + 64 = 93
cout << (76 | 85) << endl; // 93
76 ^ 12 ^ 12 的结果为?
// 潜在知识点:异或加密
// 一个数异或另外一个数A得到的结果,再异或A就可以得到原来的数
// A相当于就是一个密钥,可以用来加密和解密
// 1001100
//^ 0001100
// 1000000
//^ 0001100
// 1001100 = 76
cout << (76 ^ 12 ^ 12) << endl; // 76
16.4 练习题代码
Lesson16_练习题.cpp
#include <iostream>
using namespace std;
int main()
{
std::cout << "位运算符练习题\n";
#pragma region 练习题一
//35 << 4 和 66 >> 1 的结果为?
// .... 1 1 1 1 1 1 1 1 1
// 256 128 64 32 16 8 4 2 1
// 100011 << 4 = 1000110000 = 16 + 32 + 512 = 560
cout << (35 << 4) << endl;//560
// 1000010 >> 1 = 100001 = 1 + 32 = 33
cout << (66 >> 1) << endl;//33
#pragma endregion
#pragma region 练习题二
//99 ^ 33 和 76 | 85 的结果为?
// 99 ^ 33
// 1100011
//^ 0100001
// 1000010 = 2 + 64 = 66
cout << (99 ^ 33) << endl;//66
// 76 | 85
// 1001100
//| 1010101
// 1011101 = 1 + 4 + 8 + 16 + 64 = 93
cout << (76 | 85) << endl;//93
#pragma endregion
#pragma region 练习题三
//76 ^ 12 ^ 12 的结果为?
// 潜在知识点:异或加密
// 一个数异或另外一个数A得到的结果 再异或A 就可以得到原来的数
// A相当于就是一个密钥,可以用来加密和解密
// 1001100
//^ 0001100
// 1000000
//^ 0001100
// 1001100 = 76
cout << (76 ^ 12 ^ 12) << endl;//76
#pragma endregion
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com