Arduino程序的运算符

上一篇:Arduino程序简单入门

四、算数运算符

4.1 =(赋值运算符)

= 赋值运算符(单等号)
将等号右边的数值赋值给等号左边的变量
在C语言中,单等号被称为赋值运算符,它与数学上的等号含义不同,赋值运算符告诉单片机,将等号的右边的数值或计算表达式的结果,存储在等号左边的变量中
例子

  int sensVal;  //声明一个名为sensVal的整型变量
  senVal = analogRead(0;  //将模拟引脚0的输入电压存储在SensVal变量中

编程技巧
要确保赋值运算符(=符号)左侧的变量能够储存右边的数值。如果没有大到足以容纳右边的值,存储在变量中的值将会发生错误。
不要混淆赋值运算符[=](单等号)与比较运算符[==](双等号),认为这两个表达式是相等的。

4.2 +(加)

加,减,乘,除
描述
这些运算符返回两个操作数的和,差,乘积,商。这些运算是根据操作数的数据类型来计算的,比如 9和4都是int类型,所以9 / 4 结果是 2.这也就代表如果运算结果比数据类型所能容纳的范围要大的话,就会出现溢出(例如. 1加上一个整数 int类型 32,767 结果变成-32,768)。如果操作数是不同类型的,结果是”更大”的那种数据类型。如果操作数中的其中一个是 float类型或者double类型, 就变成了浮点数运算。
例子

y = y + 3;
x = x - 7;
i = j * 6;
r = r / 5;
Syntax

result = value1 + value2;
result = value1 - value2;
result = value1 * value2;
result = value1 / value2;

Parameters:

value1: 任何常量或者变量,value2: 任何常量或者变量
编程小提示
整型常量的默认值是int类型,所以一些整型常量(定义中)的计算会导致溢出.(比如: 60 * 1000 会得到一个负数结果.那么if(60*1000 > 0) ,if得到的是一个false值
在选择变量的数据类型时,一定要保证变量类型的范围要足够大,以至于能容纳下你的运算结果。
要知道你的变量在哪个点会”翻身”,两个方向上都得注意.如: (0 - 1) 或 (0 - - 32768)
一些数学上的分数处理,要用浮点数,但其缺点是:占用字节长度大,运算速度慢。
使用类型转换符,例如 (int)myFloat 将一个变量强制转换为int类型。

4.3 -(减)

详见4.2 +(加)

4.4 *(乘)

详见4.2 +(加)

4.5 /(除)

详见4.2 +(加)

4.6 %(取模)

描述
一个整数除以另一个数,其余数称为模。它有助于保持一个变量在一个特定的范围(例如数组的大小)。
语法
结果=被除数%除数
参数
被除数:一个被除的数字
除数:一个数字用于除以其他数
返回
余数(模)
举例
X = 7%5; // X为2
X = 9% 5;// X为4
X = 5% 5;// X为0
X = 4%5; // X为4
示例代码

/*通过循环计算1到10的模*/
int values[10];
int i = 0;

void setup () {
}
 
void loop()
{
  values [i] = analogRead(0;
  i =(i + 1)% 10; //取模运算 
}

提示
模运算符对浮点数不起作用。

五、比较运算符

5.1 ==(等于)

if(条件判断语句)和 ==、!=、<、>(比较运算符)
if 语句与比较运算符一起用于检测某个条件是否达成,如某输入值是否在特定值之上等。if 语句的语法是:
if (someVariable > 50)
{
// 执行某些语句
}
本程序测试 someVariable 变量的值是否大于 50。当大于 50 时,执行一些语句。换句话说,只要 if 后面括号里的结果(称之为测试表达式)为真,则执行大括号中的语句(称之为执行语句块);若为假,则跳过大括号中的语句。 if 语句后的大括号可以省略。若省略大括号,则只有一条语句(以分号结尾)成为执行语句。

if (x > 120) digitalWrite(LEDpin, HIGH); 
 
if (x > 120)
digitalWrite(LEDpin, HIGH); 
 
if (x > 120){ digitalWrite(LEDpin, HIGH); } 
 
if (x > 120){ 
  digitalWrite(LEDpin1, HIGH);
  digitalWrite(LEDpin2, HIGH); 
}                                 // 以上所有书写方式都正确

在小括号里求值的表达式,需要以下操作符:

比较运算操作符:
x == y(x 等于 y)
x != y(x 不等于 y)
x < y(x 小于 y)
x > y(x 大于 y)
x <= y(x 小于等于 y)
x >= y(x 大于等于 y)
警告
注意使用赋值运算符的情况(如 if (x = 10))。一个“=”表示的是赋值运算符,作用是将 x 的值设为 10(将值 10 放入 x 变量的内存中)。两个“=”表示的是比较运算符(如 if (x == 10)),用于测试 x 和 10 是否相等。后面这个语句只有 x 是 10 时才为真,而前面赋值的那个语句则永远为真。
这是因为 C 语言按以下规则进行运算 if (x=10):10 赋值给 x(只要非 0 的数赋值的语句,其赋值表达式的值永远为真),因此 x 现在值为 10。此时 if 的测试表达式值为 10,该值永远为真,因为非 0 值永远为真。所以,if (x = 10) 将永远为真,这就不是我们运行 if 所期待的结果。另外,x 被赋值为 10,这也不是我们所期待的结果。

5.2 !=(不等于)

详见5.1 ==(等于)

5.3 <(小于)

详见5.1 ==(等于)

5.4 >(大于)

详见5.1 ==(等于)

5.5 <=(小于等于)

详见5.1 ==(等于)

5.6 >=(大于等于)

详见5.1 ==(等于)

六、布尔运算符

6.1 &&(与)

布尔运算符
这些运算符可以用于if条件句中。
&&(逻辑与)
只有两个运算对象为“真”,才为“真”,如:

if (digitalRead(2) == HIGH  && digitalRead(3) == HIGH) { // 读取两个开关的电平 
// ...
}

如果当两个输入都为高电平,则为“真”。
||(逻辑或)
只要一个运算对象为“真”,就为“真”,如:

if (x > 0 || y > 0) {
  // ...
}

如果x或y是大于0,则为“真”。
!(逻辑非)
如果运算对象为“假”,则为“真”,例如

if (!x) { 
  // ...
}

如果x为“假”,则为真(即如果x等于0)。
警告
千万不要误以为,符号为&(单符号)的位运算符”与”就是布尔运算符的“与”符号为&&(双符号)。他们是完全不同的符号。
同样,不要混淆布尔运算符||(双竖)与位运算符“或”符号为| (单竖)。
位运算符〜(波浪号)看起来与布尔运算符 ! 有很大的差别。
举例

if (a >= 10 && a <= 20){}   // 如果a的值在10至20之间,则为“真”

6.2 ||(或)

详见6.1 &&(与)

6.3 !(非)

详见6.1 &&(与)

七、指针运算符

7.1 * 取消引用运算符

指针运算符
& (取地址) 和 * (取地址所指的值)
指针对C语言初学者来说是一个比较复杂的内容,但是编写大部分arduino代码时可以不用涉及到指针。然而,操作某些数据结构时,使用指针能够简化代码,但是指针的操作知识很难在工具书中找到,可以参考C语言相关工具书或一篇详细的C语言教程

7.2 & 引用运算符

详见7.1 *取消引用运算符

八、位运算符

8.1 & (按位与)

按位与(&)
按位操作符对变量进行位级别的计算。它们能解决很多常见的编程问题。下面的材料大多来自这个非常棒的按位运算指导。
说明和语法
下面是所有的运算符的说明和语法。进一步的详细资料,可参考教程。
按位与(&)
位操作符与在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个并行按位与计算。代码片段就像这样:

int a =  92;    // 二进制: 0000000001011100
int b = 101;    // 二进制: 0000000001100101
int c = a & b;  // 结果:   0000000001000100, 或10进制的68

a和b的16位每位都进行按位与计算,计算结果存在c中,二进制结果是01000100,十进制结果是68.
按位与最常见的作用是从整型变量中选取特定的位,也就是屏蔽。见下方的例子。

8.2 | (按位或)

按位或(|)
按位或操作符在C++中是|。和&操作符类似,|操作符对两个变量的为一位都进行运算,只是运算规则不同。按位或规则:只要两个位有一个为1则结果为1,否则为0。换句话说:
0 0 1 1 运算元1
0 1 0 1 运算元2

0 1 1 1(运算元1 | 运算元2) - 返回的结果
这里是一个按位或运算在C + +代码片段:

int a =  92;    // 二进制: 0000000001011100
int b = 101;    // 二进制: 0000000001100101
int c = a | b;  // 结果:   0000000001111101, 或十进制的125

示例程序
按位与和按位或运算常用于端口的读取-修改-写入。在微控制器中,一个端口是一个8位数字,它用于表示引脚状态。对端口进行写入能同时操作所有引脚。
PORTD是一个内置的常数,是指0,1,2,3,4,5,6,7数字引脚的输出状态。如果某一位为1,着对应管脚为HIGH。(此引脚需要先用pinMode()命令设置为输出)因此如果我们这样写,PORTD=B00110001;则引脚2、3、7状态为HIGH。这里有个小陷阱,我们可能同时更改了引脚0、1的状态,引脚0、1是Arduino串行通信端口,因此我们可能会干扰通信。
我们的算法的程序是:
读取PORT并用按位与清除我们想要控制的引脚
用按位或对PORTD和新的值进行运算

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);
	}
}

8.3 ^ (按位异或)
按位异或(^)
C++中有一个不常见的操作符叫按位异或,也叫做XOR(通常读作”eks-or“)。按位异或操作符用‘^'表示。此操作符和按位或(|)很相似,区别是如果两个位都为1则结果为0:
0 0 1 1 运算元1
0 1 0 1 运算元2

0 1 1 0(运算元1 ^运算元2) - 返回的结果
按位异或的另一种解释是如果两个位值相同则结果为0,否则为1。
下面是一个简单的代码示例:

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);
}

8.4 ~ (按位非)
按位取反 (~)
按位取反在C+ +语言中是波浪号~。与&(按位与)和|(按位或)不同,按位取反使用在一个操作数的右侧。按位取反将操作数改变为它的“反面”:0变为1,1变成0。例如:
0 1 operand1

1 0 ~ operand1

int a = 103;    // 二进制:  0000000001100111
int b = ~a;     // 二进制:  1111111110011000 = -104

你可能会惊讶地看到结果为像-104这样的数字。这是因为整数型变量的最高位,即所谓的符号位。如果最高位是1,这个数字将变为负数。这个正数和负数的编码被称为补。想了解更多信息,请参考Wikipedia文章two’s complement.
顺便说一句,有趣的是,要注意对于任何整数型操作数X,〜X和-X-1是相同的。
有时,对带有符号的整数型操作数进行位操作可以造成一些不必要的意外。

8.5 <<(左移位运算符)

这些操作符可使左运算元中的某些位移动右运算元中指定的位数。
语法
variable « number_of_bits variable » number_of_bits
参数
variable - (byte, int, long) number_of_bits integer ⇐ 32
例子

int a = 5;        // 二进制数: 0000000000000101
int b = a << 3;   // 二进制数: 0000000000101000, 或十进制数:40
int c = b >> 3;   // 二进制数: 0000000000000101, 或者说回到开始时的5
//当你将x左移y位时(x«y),x中最左边的y位会逐个逐个的丢失:
int a = 5;        // 二进制: 0000000000000101
int b = a << 14;  // 二进制: 0100000000000000 - 101中最左边的1被丢弃

如果你确定位移不会引起数据溢出,你可以简单的把左移运算当做对左运算元进行2的右运算元次方的操作。例如,要产生2的次方,可使用下面的方式:
1 << 0 == 1
1 << 1 == 2
1 << 2 == 4
1 << 3 == 8

1 << 8 == 256
1 << 9 == 512
10 << 1 == 1024

当你将x右移y位(x»y),如果x最高位是1,位移结果将取决于x的数据类型。如果x是int类型,最高位为符号位,确定是否x是负数或不是,正如我们上面的讨论。如果x类型为int,则最高位是符号位,正如我们以前讨论过,符号位表示x是正还是负。在这种情况下,由于深奥的历史原因,符号位被复制到较低位:

X = -16; //二进制:1111111111110000
Y = X >> 3 //二进制:1111111111111110

这种结果,被称为符号扩展,往往不是你想要的行为。你可能希望左边被移入的数是0。右移操作对无符号整型来说会有不同结果,你可以通过数据强制转换改变从左边移入的数据:

X = -16; //二进制:1111111111110000
int y = (unsigned int)x >> 3;  // 二进制: 0001111111111110

如果你能小心的避免符号扩展问题,你可以将右移操作当做对数据除2运算。例如:

INT = 1000;
Y = X >> 3; 8 1000  //1000整除8,使y=125

8.6 >> (右移位运算符)

详见 8.5 <<(左移位运算符)

九、复合运算符

9.1 ++ (递增)

++ (递增) / – (递减)
描述
递增或递减一个变量
语法

x++;  //x自增1返回x的旧值
++x;  // x自增1返回x的新值

x--;  // x自减1返回x的旧值
--x;  //x自减1返回x的新值

参数
x: int或long(可能是unsigned)
返回
变量进行自增/自减操作后的原值或新值。
例子

x = 2;
y = ++x;      // 现在x=3,y=3
y = x--;      // 现在x=2,y还是3

9.2 – (递减)

详见 9.1 ++ (递增)

9.3 += (复合加)

+= , -= , *= , /=
描述
执行常量或变量与另一个变量的数学运算。+= 等运算符是以下扩展语法的速记。
语法
X += Y; //相当于表达式X = X + Y;
X -= Y; //相当于表达式X = X - Y;
X *= Y; //相当于表达式X = X * Y;
X /= Y; //相当于表达式X = X / Y;
参数
X:任何变量类型
Y:任何变量类型或常数
例子

x = 2;
x += 4;      // x 现在等于6
x -= 3;      // x 现在等于3
x *= 10;     // x 现在等于30
x /= 2;      // x 现在等于15

9.4 -= (复合减)

详见 9.3 += (复合加)

9.5 *= (复合乘)

详见 9.3 += (复合加)

9.6 /= (复合除)

详见 9.3 += (复合加)

9.7 &= (复合运算按位与)

描述
复合运算按位与运算符(&=)经常被用来将一个变量和常量进行运算使变量某些位变为0。这通常被称为“清算”或“复位”位编程指南。
语法
x &= y; // 等价于 x = x & y;
参数
x:char,int或long类型变量
Y:char,int或long类型常量
例如
首先,回顾一下按位与(&)运算符
0 0 1 1 运算元1
0 1 0 1 运算元2

0 0 0 1(运算元1&运算元2) - 返回的结果
任何位与0进行按位与操作后被清零,如果myBite是变量
myByte&B00000000 = 0;
因此,任何位与1进行“按位与运算”后保持不变
myByte B11111111 = myByte;
注意:因为我们用位操作符来操作位,所以使用二进制的变量会很方便。如果这些数值是其他值将会得到同样结果,只是不容易理解。同样,B00000000是为了标示清楚,0在任何进制中都是0(恩。。有些哲学的味道) 因此 - 清除(置零)变量的任意位0和1,而保持其余的位不变,可与常量B11111100进行复合运算按位与(&=)
1 0 1 0 1 0 1 0变量
1 1 1 1 1 1 0 0 mask

1 0 1 0 1 0 0 0
变量不变 位清零
将变量替换为x可得到同样结果
X X X X X X X X变量
1 1 1 1 1 1 0 0 mask

X X X X X X 0 0
变量不变 位清零
同理
myByte = 10101010;
myByte&= B1111100 == B10101000;

9.8 |= (复合运算按位或)

描述
复合按位或操作符(| =)经常用于变量和常量“设置”(设置为1),尤其是变量中的某一位。
语法
x |= y; //等价于 x = x | y;
参数
x: char,int或long类型
y:整数,int或long类型
例如
首先,回顾一下OR(|)运算符
0 0 1 1 运算元1
0 1 0 1 运算元2

0 1 1 1(运算元1 | 运算元2) - 返回的结果
如果变量myByte中某一位与0经过按位或运算后不变。
myByte | B00000000 = myByte;
与1经过或运算的位将变为1.
myByte | B11111111 B11111111;
因此 - 设置变量的某些位为0和1,而变量的其他位不变,可与常量B00000011进行按位与运算(| =)
1 0 1 0 1 0 1 0变量
0 0 0 0 0 0 1 1

1 0 1 0 1 0 1 1
变量保持不变 位设置
接下来的操作相同,只是将变量用x代替
X X X X X X X X变量
0 0 0 0 0 0 1 1 mask

X X X X X X 1 1
变量保持不变 位设置
同上:
myByte = B10101010;
myByte | = B00000011 == B10101011;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值