|
|
第1行: |
第1行: |
− | *'''Bitwise AND (&), Bitwise OR (|), Bitwise XOR (^)''' | + | *'''按位取反 (~)''' |
− | 按位与(&)
| + | 按位取反在C+ +语言中是波浪号~。与&(按位与)和|(按位或)不同,按位取反使用在一个操作数的右侧。按位取反将操作数改变为它的“反面”:0变为1,1变成0。例如: |
− | | |
− | 按位操作符对变量进行位级别的计算。它们能解决很多常见的编程问题。下面的材料大多来自这个非常棒的按位运算指导。
| |
− | | |
− | 说明和语法
| |
− | | |
− | 下面是所有的运算符的说明和语法。进一步的详细资料,可参考教程。
| |
− | | |
− | 按位与(&)
| |
− | | |
− | 位操作符与在C + +中是一个&符,用在两个整型变量之间。按位与运算符对两侧的变量的每一位都进行运算,规则是:如果两个运算元都是1,则结果为1,否则输出0.另一种表达方式:
| |
− | | |
− | 0 0 1 1 运算元1
| |
− | 0 1 0 1 运算元2
| |
− | ----------
| |
− | 0 0 0 1(运算元1&运算元2)-返回结果
| |
− | 在Arduino中,int类型为16位,所以在两个int表达式之间使用&会进行16个并行按位与计算。代码片段就像这样:
| |
| <pre style="color:green"> | | <pre style="color:green"> |
− | int a = 92; //二进制: 0000000001011100
| |
− | int b = 101; // 二进制: 0000000001100101
| |
− | int c = a & b; // 结果: 0000000001000100, 或10进制的68
| |
− | </pre>
| |
− |
| |
− | a和b的16位每位都进行按位与计算,计算结果存在c中,二进制结果是01000100,十进制结果是68.
| |
− |
| |
− | 按位与最常见的作用是从整型变量中选取特定的位,也就是屏蔽。见下方的例子。
| |
− |
| |
− | 按位或(|)
| |
| | | |
− | 按位或操作符在C++中是|。和&操作符类似,|操作符对两个变量的为一位都进行运算,只是运算规则不同。按位或规则:只要两个位有一个为1则结果为1,否则为0。换句话说:
| + | 0 1 operand1 |
− | | |
− | 0 0 1 1 运算元1
| |
− | 0 1 0 1 运算元2
| |
| ---------- | | ---------- |
− | 0 1 1 1(运算元1 | 运算元2) - 返回的结果 | + | 1 0 ~ operand1 |
− | 这里是一个按位或运算在C + +代码片段:
| + | int a = 103; // 二进制: 0000000001100111 |
− | <pre style="color:green">
| + | int b = ~a; // 二进制: 1111111110011000 = -104 |
− | int a = 92; // 二进制: 0000000001011100 | |
− | int b = 101; //二进制: 0000000001100101 | |
− | int c = a | b; // 结果: 0000000001111101, 或十进制的125
| |
| </pre> | | </pre> |
| | | |
− | 示例程序
| + | 你可能会惊讶地看到结果为像-104这样的数字。这是因为整数型变量的最高位,即所谓的符号位。 |
| | | |
− | 按位与和按位或运算常用于端口的读取-修改-写入。在微控制器中,一个端口是一个8位数字,它用于表示引脚状态。对端口进行写入能同时操作所有引脚。
| + | 如果最高位是1,这个数字将变为负数。这个正数和负数的编码被称为补。 |
| | | |
− | PORTD是一个内置的常数,是指0,1,2,3,4,5,6,7数字引脚的输出状态。如果某一位为1,着对应管脚为HIGH。(此引脚需要先用pinMode()命令设置为输出)因此如果我们这样写,PORTD=B00110001;则引脚2、3、7状态为HIGH。这里有个小陷阱,我们可能同时更改了引脚0、1的状态,引脚0、1是Arduino串行通信端口,因此我们可能会干扰通信。
| + | 顺便说一句,有趣的是,要注意对于任何整数型操作数X,〜X和-X-1是相同的。 |
− | | |
− | 我们的算法的程序是:
| |
− | | |
− | 读取PORT并用按位与清除我们想要控制的引脚
| |
− | | |
− | 用按位或对PORTD和新的值进行运算
| |
− | <pre style="color:green">
| |
− | int i; // 计数器
| |
− | int j;
| |
− |
| |
− | void setup()
| |
− | DDRD = DDRD | B11111100; //设置引脚2~7的方向,0、1脚不变(xx|00==xx)
| |
− | //效果和pinMode(pin,OUTPUT)设置2~7脚为输出一样
| |
− | serial.begin(9600);
| |
− | }
| |
− |
| |
− | void loop () {
| |
− | for (i=0; i<64; i++){
| |
− |
| |
− | PORTD = PORTD & B00000011; // 清除2~7位,0、1保持不变(xx & 11 == xx)
| |
− | j = (i << 2); //将变量左移为·2~7脚,避免0、1脚
| |
− | PORTD = PORTD | j; //将新状态和原端口状态结合以控制LED脚
| |
− | Serial.println(PORTD, BIN); // 输出掩盖以便调试
| |
− | delay(100);
| |
− | }
| |
− | }
| |
− | </pre>
| |
− | | |
− | 按位异或(^)
| |
− | | |
− | C++中有一个不常见的操作符叫按位异或,也叫做XOR(通常读作”eks-or“)。按位异或操作符用‘^'表示。此操作符和按位或(|)很相似,区别是如果两个位都为1则结果为0:
| |
− | | |
− | 0 0 1 1 运算元1
| |
− | 0 1 0 1 运算元2
| |
− | ---------- | |
− | 0 1 1 0(运算元1 ^运算元2) - 返回的结果
| |
− | 按位异或的另一种解释是如果两个位值相同则结果为0,否则为1。
| |
− | | |
− | 下面是一个简单的代码示例:
| |
− | <pre style="color:green">
| |
− | int x = 12; // 二进制: 1100
| |
− | int y = 10; // 二进制: 1010
| |
− | int z = x ^ y; // 二进制: 0110, 或十进制 6
| |
− | // Blink_Pin_5
| |
− | //演示“异或”
| |
− | void setup(){
| |
− | DDRD = DDRD | B00100000; //设置数字脚5设置为输出
| |
− | serial.begin(9600);
| |
− | }
| |
− |
| |
− | void loop () {
| |
− | PORTD = PORTD ^ B00100000; // 反转第5位(数字脚5),其他保持不变
| |
− | delay(100);
| |
− | }
| |
− | </pre>
| |
| | | |
| + | 有时,对带有符号的整数型操作数进行位操作可以造成一些不必要的意外。 |
| | | |
| [[https://www.microduino.cn/wiki/index.php/Arduino_%E8%AF%AD%E6%B3%95%E6%89%8B%E5%86%8C/zh 返回Arduino语法手册]] | | [[https://www.microduino.cn/wiki/index.php/Arduino_%E8%AF%AD%E6%B3%95%E6%89%8B%E5%86%8C/zh 返回Arduino语法手册]] |
按位取反在C+ +语言中是波浪号~。与&(按位与)和|(按位或)不同,按位取反使用在一个操作数的右侧。按位取反将操作数改变为它的“反面”:0变为1,1变成0。例如:
0 1 operand1
----------
1 0 ~ operand1
int a = 103; // 二进制: 0000000001100111
int b = ~a; // 二进制: 1111111110011000 = -104
你可能会惊讶地看到结果为像-104这样的数字。这是因为整数型变量的最高位,即所谓的符号位。
如果最高位是1,这个数字将变为负数。这个正数和负数的编码被称为补。
顺便说一句,有趣的是,要注意对于任何整数型操作数X,〜X和-X-1是相同的。
有时,对带有符号的整数型操作数进行位操作可以造成一些不必要的意外。
[返回Arduino语法手册]