1 << pin c 语言位运算符,Arduino语法-位运算

语法列表

& (位与)

| (位或)

^ (位异或)

~ (位非)

<< (左移)

(右移)

位与说明

按位与(&)

按位操作符在变量的位级执行运算。它们帮助解决各种常见的编程问题。以下大部分资料来自一个有关位数学的优秀教程,或许可以在这里找到。[1]

描述和语法

以下是所有这些运算符的描述和语法。更详细的资料或许可以在参考指南中找到。

按位与(&)

在C++中按位与运算符是单个与符号,

用于其它两个整型表达式之间使用。按位与运算独立地在周围的表达式的每一位上执行操作。根据这一规则:如果两个输入位都是1,结果输出1,否则输出0。表达这一思想的另一个方法是:

0 0 1 1 operand1

0 1 0 1 operand2

----------

0 0 0 1 (operand1 & operand2) - returned result

在Arduino中,int型是16位的。所以在两个整型表达式之间使用&将会导致16个与运算同时发生。代码片断就像这样:

int a = 92; // in binary: 0000000001011100

int b = 101; // in binary: 0000000001100101

int c = a & b; // result: 0000000001000100, or 68 in decimal.

在a和b的16位的每一位将使用按位与处理。且所有16位结果存入C中,以二进制存入的结果值01000100,即十进制的68。

按位与的其中一个最常用的用途是从一个整型数中选择特定的位,常被称为掩码屏蔽。看如下示例:

位或说明

按位或(|)

在C++中按位或运算符是垂直的条杆符号,|。就像&运算符,|独立地计算它周围的两个整型表达式的每一位。(当然)它所做的是不同的(操作)。两个输入位其中一个或都是1按位或将得到1,否则为0。换句话说:

0 0 1 1 operand1

0 1 0 1 operand2

----------

0 1 1 1 (operand1 | operand2) - returned result

这是一个使用一小断C++代码描述的按位或(运算)的例子:

int a = 92; // in binary: 0000000001011100

int b = 101; // in binary: 0000000001100101

int c = a | b; // result: 0000000001111101, or 125 in decimal.

按位与和按位或的一个共同的工作是在端口上进行程序员称之为读-改-写的操作。在微控制器中,每个端口是一个8位数字,每一位表示一个引脚的状态。写一个端口可以同时控制所有的引脚。

PORTD是内建的参照数字口0,1,2,3,4,5,6,7的输出状态的常量。如果一个比特位是1,那么该引脚置高。(引脚总是需要用pinMode()指令设置为输出模式)。所以如果我们写入PORTD = B00110001;我们就会让引脚2,3和7输出高。一个小小的问题是,我们同时也改变了某些引脚的0,1状态。这用于Arduino与串口通讯,所以我们可能会干扰串口通讯。

我们的程序规则是:

仅仅获取和清除我们想控制的与相应引脚对应的位(使用按位与)。

合并要修改的PORTD值与所控制的引脚的新值(使用按位或)。

int i; // counter variable

int j;

void setup(){

DDRD = DDRD | B11111100; // set direction bits for pins 2 to 7, leave 0 and 1 untouched (xx | 00 == xx)

// same as pinMode(pin, OUTPUT) for pins 2 to 7

Serial.begin(9600);

}

void loop(){

for (i=0; i<64; i++){

PORTD = PORTD & B00000011; // clear out bits 2 - 7, leave pins 0 and 1 untouched (xx & 11 == xx)

j = (i << 2); // shift variable up to pins 2 - 7 - to avoid pins 0 and 1

PORTD = PORTD | j; // combine the port information with the new information for LED pins

Serial.println(PORTD, BIN); // debug to show masking

delay(100);

}

}

位异或说明

按位异或(^)

在C++中有一个有点不寻常的操作,它被称为按位异或,或者XOR(在英语中,通常读作“eks-or”)。按位异或运算符使用符号^。该运算符与按位或运算符“|”非常相似 ,唯一的不同是当输入位都为1时它返回0。

0 0 1 1 operand1

0 1 0 1 operand2

----------

0 1 1 0 (operand1 ^ operand2) - returned result

看待XOR的另一个视角是,当输入不同时结果为1,当输入相同时结果为0。

这里是一个简单的示例代码:

int x = 12; // binary: 1100

int y = 10; // binary: 1010

int z = x ^ y; // binary: 0110, or decimal 6

“^”运算符常用于翻转整数表达式的某些位(例如从0变为1,或从1变为0)。在一个按位异或操作中,如果相应的掩码位为1, 该位将翻转,如果为0,该位不变。以下是一个闪烁引脚5的程序.

// Blink_Pin_5

// demo for Exclusive OR

void setup(){

DDRD = DDRD | B00100000; // set digital pin five as OUTPUT

Serial.begin(9600);

}

void loop(){

PORTD = PORTD ^ B00100000; // invert bit 5 (digital pin 5), leave others untouched

delay(100);

}

位非说明

按位取反(~)

在C++中按位取反运算符为波浪符“~”。不像“&”和“|”,按位取反运算符应用于其右侧的单个操作数。按位取反操作会翻转其每一位。0变为1,1变为0。例如:

0 1 operand1

1 0 ~ operand1

int a = 103; // binary: 0000000001100111

int b = ~a; // binary: 1111111110011000 = -104

看到此操作的结果为一个负数:-104,你可能会感到惊讶,这是因为一个整型变量的最高位是所谓的符号位。如果最高位为1,该整数被解释为负数。这里正数和负数的编码被称为二进制补码。欲了解更多信息,请参阅维基百科条目:补码。

顺便说一句,值得注意的是,对于任何整数x, ~x 与 -x-1 相等。

有时候,符号位在有符号整数表达式中能引起一些不期的意外。

左移、右移说明

左移运算(<>)

描述

From The Bitmath Tutorial in The Playground

在C++中有两个移位运算符:左移运算符<>。这些运算符将使左边操作数的每一位左移或右移其右边指定的位数。

语法

variable << number_of_bits

variable >> number_of_bits

参数

*variable - (byte, int, long) number_of_bits integer <= 32

示例:

int a = 5; // binary: 0000000000000101

int b = a << 3; // binary: 0000000000101000, or 40 in decimal

int c = b >> 3; // binary: 0000000000000101, or back to 5 like we started with

当把x左移y位(x << y),x中最左边的y位将会丢失。

int a = 5; // binary: 0000000000000101

int b = a << 14; // binary: 0100000000000000 - 101中的第一个1被丢弃

如果您确信没有值被移出,理解左移位运算符一个简单的办法是,把它的左操作数乘2将提高其幂值。例如,要生成2的乘方,可以使用以下表达式:

1 << 0 == 1

1 << 1 == 2

1 << 2 == 4

1 << 3 == 8

...

1 << 8 == 256

1 << 9 == 512

1 << 10 == 1024

...

当把x右移y位,x的最高位为1,该行为依赖于x的确切的数据类型。如果x的类型是int,最高位为符号位,决定x是不是负数,正如我们在上面已经讨论过的。在这种情况下,符号位会复制到较低的位:

int x = -16; // binary: 1111111111110000

int y = x >> 3; // binary: 1111111111111110

该行为,被称为符号扩展,常常不是你所期待的。反而,你可能希望移入左边的是0。事实上右移规则对于无符合整型表达式是不同的。所以你可以使用强制类型转换来避免左边移入1。

int x = -16; // binary: 1111111111110000

int y = (unsigned int)x >> 3; // binary: 0001111111111110

如果你可以很小心地避免符号扩展,你可以使用右移位运算符>>,作为除以2的幂的一种方法。例如

int x = 1000;

int y = x >> 3; // 1000除以8,得y = 125.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值