Kotlin从0到1——运算符

 运算符的作用是操纵对象和数据,它以一个或多个变量为基础,生成新的值。
 运算符具有优先级和结合性。优先级决定一个表达式存在多个运算符时各部分的计算顺序。结合性决定了在相同优先级的情况下是从左到右(左结合)还是从右到左(右结合)。Kotlin中运算符优先
级和结合性参见下表(数字越小,优先级越高):

符号 优先级 结合性 目数 说明
. 1 从左到右 双目
() 1 从左到右 双目 小括号
[] 1 从左到右 双目 中括号
++ 2 从右到左 单目 前缀增
-- 2 从右到左 单目 前缀减
+ 2 从右到左 单目 正号
- 2 从右到左 单目 负号
++ 2 从右到左 单目 后缀增
-- 2 从右到左 单目 后缀减
2 从右到左 单目 逻辑非
* 3 从左到右 双目 乘法
/ 3 从左到右 双目 除法
% 3 从左到右 双目 取余
+ 4 从左到右 双目 加法
- 4 从左到右 双目 减法
< 5 从左到右 双目 小于
<= 5 从左到右 双目 小于等于
> 5 从左到右 双目 大于
>= 5 从左到右 双目 大于等于
== 6 从左到右 双目 等于
!= 6 从左到右 双目 不等于
&& 7 从左到右 双目 逻辑与
|| 8 从左到右 双目 逻辑或
= 9 从左到右 双目 赋值
+= 9 从左到右 双目 复合赋值运算符加
-= 9 从左到右 双目 复合赋值运算符减
*= 9 从左到右 双目 复合赋值运算符乘
/= 9 从左到右 双目 复合赋值运算符除
%= 9 从左到右 双目 复合赋值运算符取余

熟悉Java的同学从上表中并没有看到 |&^~ 和移位相关的操作符。在Kotlin中通过 andorxorinv() 实现位操作;通过 shrshlushr 实现移位操作,并且没有移位赋值操作符。
 实际操作中为了方便阅读,明确执行顺序,一般通过添加括号而不是依赖运算符的优先级来控制计算顺序。

1.赋值运算符 =

= 将符号右边的值复制到左边。右边的值可以是变量、常量 和任何表达式。比如:

val a = 5              
var b = 3 + 45

2.算术运算符 +-*/%

基本算术运算符都是一样的这里就不再多说,下面举几个代码实例:

val  num1 = 3
val num2 = 4
val i = num1 + num2    // i = 3 + 4 = 7
val j = num1 - num2     // j = 3 - 4 = -1
val k = num1 * num2    // k = 3 * 4 = 12
val m = num1 / num2   // m = 3 / 4 = 0
val n = num1 % num2  // n = 3 % 4 = 3

一元运算符 +-+保持变量原值。 -修改变量值为原值的相反数。

val a = -46
val b = +a   // b= -46
val c = -a    // c = 46

3.关系运算符>>=<<=!===

其中 >>=<<= 适用于所有实现了 Comparable 接口的对象,!===适用于任何对象。下面给出一些示例代码:

var i = 23
var j = 12
println(i  < j)          // 输出结果为 false
println(i >= j)         // 输出结果为 true
val a = Integer(5)
val b = Integer(5)
println(a == b)     // 输出结果为 true
println(a != b)     // 输出结果为 false

4.逻辑运算符||&&!

逻辑运算符只适用于 Boolean 或者 boolean类型, 经过它运算后生成一个布尔值。比如:

val b = false
println(!b)  // 输出true
var k = 23
val c = b || k>2 && k ==23  
println(c)  // 输出true

5.位运算符

Kotlin中使用 orandxor 操作符和方法inv() 分别表示按位 或 、 与、异或 、求反操作。示例代码:

var i = 0b0011   // 十进制数3
var j = 0b1010 // 十进制数10
println(i or j)     // 11
println(i and j)  //  2
println(i xor j)   //  9
println(i.inv())   //  -4

补充:
机器数:
 数字在计算机中二进制表示的方式,叫做这个数的机器数。高位用于存放数字的符号,0表示正数,1表示负数.
真值:
 带符号位的机器数对应的真正数值称为机器数的真值。比如,有符号数 10000001 的真值为 -1, 而不是2^7 +1 = 129。00000001 的真值为 1.
原码:
 原码定义为符号位加上真值的绝对值。比如,+2 的原码为 00000010,; -2 的原码为 10000010 。
反码:
 反码定义: 1. 如果是正数,那么其反码就是原码本身; 2.如果是负数,那么原码符号位不变,其余各位取反。 比如 +2 原码为 00000010 , 反码为 00000010; -2 原码为 10000010 , 反码为 11111101。
补码:
 补码定义:1. 如果是正数,那么其补码就是原码本身; 2.如果是负数,那么原码符号位不变,其余各位取反,最后 +1 。 比如 +2 原码为 00000010 , 反码为 00000010; -2 原码为 10000010 , 补码为 11111110。由于计算机中存储的是数值的补码,针对示例代码中变量:
i = 0b0011 , 其完整的二进制(int类型用 32 位 2 进制表示)表示为:
0000 0000 0000 0000 0000 0000 0000 0011
j = 0b1010 , 其完整的二进制表示为:
0000 0000 0000 0000 0000 0000 0000 1010
or (按位或)操作:
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 1010
0000 0000 0000 0000 0000 0000 0000 1011 => 2^3 + 2^1 + 1 = 11
and (按位与)操作:
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 1010
0000 0000 0000 0000 0000 0000 0000 0010 => 2^1 = 2
xor (按位异或)操作:
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 1010
0000 0000 0000 0000 0000 0000 0000 1001 => 2^3 + 1 = 9
inv()(按位求反)操作:
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1100 => - 2^2 = -4

6.移位运算符

Kotlin中使用 shrshlushr 操作符实现移位操作,并且没有移位赋值符合运算符。可用下面的方案来测试了解各个操作符的作用:

var i = 0b0111   // 十进制数7
println(i shr 2)
println(i shl 2)  // 左移,相当于 2^n * i , n 移位位数 , i操作数
println(i ushr 2)
var j = -0b111   // 十进制数 -7
println(j shr 2)    // 有符号右移,最左边用符号位填充
println(j shl 2)
println(j ushr 2)   // 无符号右移,最左边位用0填充,负数变正数

补充:相同的,针对移位操作示例代码中的变量:
i = 0b0111 , 其完整的二进制表示为:
0000 0000 0000 0000 0000 0000 0000 0111
shr 2 , 有符号右移两位, 最左边用符号位填充 , 结果为:
0000 0000 0000 0000 0000 0000 0000 0001 => 1
shl 2, 左移两位, 最右边用 0 填充 , 结果为:
0000 0000 0000 0000 0000 0000 0001 1100 => 2^4 + 2^3 + 2^2 = 28
ushr 2, 无符号右移两位, 最左边用 0 填充 , 结果为:
0000 0000 0000 0000 0000 0000 0000 0001 => 1
j = -0b0111 , 其完整的二进制表示为:
1111 1111 1111 1111 1111 1111 1111 1001
shr 2 , 有符号右移两位, 最左边用符号位填充 , 结果为:
1111 1111 1111 1111 1111 1111 1111 1110 => -2
shl 2, 左移两位, 最右边用 0 填充 , 结果为:
1111 1111 1111 1111 1111 1111 1110 0100 => - 28
ushr 2, 无符号右移两位, 最左边用 0 填充 , 结果为:
0011 1111 1111 1111 1111 1111 1111 1110 => 1073741822

示例代码中几乎包含了所有的运算符,特别需要注意关系运算符和逻辑运算符中的示例代码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容