运算符介绍
运算符
对于程序中存在的各种数据,他们的一项重要活动就是参与运算,而运算需要通过运算符来完成,他会根据特定的规则,对给出的操作数进行运算,然后返回运算的结果。
什么是操作数?
操作数是指参与运算符运算的具体目标,他们可以是字面量,变量,表达式,以及可返回或包含值的实体。
运算符是一种特殊的函数?
不管代码中的运算符是如何书写的,他们与函数在本质上是相同的,均被用于完成某种运算,并具有输入和输出,与运算符关联的操作数类似于函数的参数。
赋值运算符
赋值运算符会将右操作数的计算结果赋予左操作数,最为常见的是=
。当然,赋值运算符可以变得更为复杂,比如,+=
会先将右操作数的计算结果与左操作数的计算结果相加,再将相加的结果赋予左操作数。
赋值运算符的左操作数需要是一个可存储值的实体,比如,变量,类的属性等。
赋值运算符对操作数数据类型的要求
赋值运算符右操作数所计算出的值的数据类型,需要与左操作数保持一致,或可进行隐式转换,如果语言要求类型安全的话。
在 C# 中,直接将10000000
赋值给字符串类型的变量是行不通的,因为整数类型不能隐式转换为字符串类型。
// ERROR 下面的赋值是错误的,整数类型无法隐式转换为字符串类型
string num = 10000000;
算术运算符
算术运算符用于对操作数进行数学运算,这包含了经典的加减乘除(+
,-
,*
,/
),增量(++
),减量(--
)等。
字符串类型的加法运算
需要指出,在大部分语言中,对字符串使用加法算术运算符(+
),相当于将左右两边的字符串拼接在一起,然后作为一个新的字符串返回。
比较运算符
比较运算符一般用于对比两边的操作数是否相等,不相等,大于,小于,大于等于或小于等于,并返回一个表示对比结果的布尔值。
比较运算符的严格比较
由于操作数提升的存在,一些语言支持严格的比较运算符,以避免数据类型发生隐式转换。
在 JavaScript 中,表达式1=='1'
将返回true
,而1==='1'
将返回false
,因为===
是严格的比较运算符,不允许隐式转换。
// == 允许数据类型隐式转换,表达式结果为 true
console.log(1 == '1')
// == 不允许数据类型隐式转换,表达式结果为 false
console.log(1 === '1')
true
false
值,数据类型
想要了解数据类型的隐式转换,你可以查看数据类型转换一段。
逻辑运算符
逻辑运算符通常用于流程控制,他的表面效果为判断左右两边的条件是否全部成立(&&
或and
),或左右两边的条件是否至少一个成立(||
或or
),或条件是否不成立(!
或not
)。
什么是逻辑运算符的短路求值?
事实上,逻辑运算符只是返回左右两边某个操作数的计算结果,这些结果将等价于一个布尔值,当运算没有必要继续进行时,右操作数将被丢弃,这被称为短路求值。
在下面的 JavaScript 代码中,'A'&&'B'
返回'B'
,因为需要计算左右两边的操作数,才能确保条件均成立,'A'||'B'
返回'A'
,因为左操作数已确保有一个条件成立,没有必要再计算右操作数。
// 'A' 和 'B' 都会被计算
console.log('A' && 'B')
// 'A' 会被计算 ,'B' 将被丢弃
console.log('A' || 'B')
B
A
位运算符
位运算符进行的计算,是以操作数的二进制格式为基础的,你可能很少见到该运算符的出现,因为他的作用比较隐晦,一般是为了实现数学上的某些惊人技巧。
操作数提升
当运算符操作数的数据类型不相同时,可能会进行操作数提升,操作数将被隐式转换为某种数据类型,然后才会参与运算。至于提升的具体规则,需要视具体的运算符和语言而定。
在下面的 C# 代码中,1
会隐式转换为浮点数类型,然后再与1f
进行加法运算。
// 1 会被隐式转换为浮点数类型
Console.WriteLine((1f + 1).GetType());
System.Single
运算符优先级
当一个表达式中存在多个运算符时,将按照他们的优先级来决定处理顺序。如果你不能确定,那么可以使用()
括住希望优先处理的部分,这在大部分语言中是可行的。比如,对于表达式1*2+3
,可以使用()
来优先处理加法运算符,1*(2+3)
。
运算符结合性
如果运算符的优先级相同,那么先处理谁取决于运算符的结合性,大部分的二元运算符是左结合的,计算会按照从左到右的顺序进行,比如,1+2+3
的计算顺序是(1+2)+3
,而不是1+(2+3)
。至于右结合运算符,其数量较少,赋值运算符是其中之一,比如,a=b=c
的计算顺序是a=(b=c)
,而不是(a=b)=c
。
操作数计算顺序
在一个表达式中,操作数的计算顺序与运算符的优先级或结合性无关,他们会从左到右依次被计算。
在下面的 JavaScript 代码中,操作数b()
和c()
并没有因为()
而被优先计算。
// 四个作为操作数的函数
a = () => {
console.log('a')
return 1
}
b = () => {
console.log('b')
return 2
}
c = () => {
console.log('c')
return 3
}
d = () => {
console.log('d')
return 4
}
// b() 和 c() 并不会被优先计算
const result = a() / (b() + c()) * d()
console.log(result)
a
b
c
d
0.8
源码
operators.cs·codebeatme/programming·GitHub
operators.js·codebeatme/programming·GitHub