运算符:
- 很久以前,流传
程序=算法+数据
这样的说法。- 算法是什么?通俗点说就是
解决问题的过程
。小到加法指令,大到成千上万台服务器组成的分布式计算集群。抛去抽象概念和宏观架构,最终都由最基础的机器指令过程去处理不同层次存储设备里的数据。学习语言和设计架构不同,我们所关心的就是微观层次,诸如语法规则所映射的机器指令, 以及数据存储位置和格式等等。其中,运算符和表达式用来串联数据和指令,算是最基础的算法。
运算符列表:
+ & += &= && == != ( )
- | -= |= || < <= [ ]
* ^ *= ^= <- > >= { }
/ << /= <<= ++ = := , ;
% >> %= >>= -- ! ... . :&^ &^=
一元运算符
优先级最高,二元则分成五个级别,从高往低分别是:
- 相同优先级的二元运算符,从左往右依次计算
- 一元运算符:运算中只有1个操作数参与,如:i++,i–
- 二元运算符:运算中只有2个操作数参与,如:+ - * / %
a+b
最高 * / % << >> & &^+ - | ^== != < <= > >=&&
最低 ||
没有乘幂和绝对值运算符,对应的是标准库math里的Pow、Abs函数实现。
二元运算符:
操作数类型必须相同,除非是无显式类型声明的常量,且该常量操作数会自动转换为另一 操作数类型。
func main() {const i = 1 // 无显式类型声明的常量var j byte = 10fmt.Printf("%T\t%T\n", i, j) // int uint8b := i + j // b自动转换为uint8类型。fmt.Printf("%T, %v\n", b, b)const x float32 = 1.1d := x + i // v自动转换为float32类型。fmt.Printf("%T, %v\n", d, d)
}
算术运算符:
+
:加
-
:减
*
:乘
/
:除,取结果的商
%
:取余,取结果的余数
整数操作只能得到整数,要想得到小数,必须有浮点数参与运算。/和%运算除数不能为0
演示:
func main() {a := 1b := 2c := 0fmt.Println("a + b = ", a+b) //3fmt.Println("a - b = ", a-b) //-1fmt.Println("a * b = ", a*b) //2fmt.Println("a / b = ", a/b) //0fmt.Println("a % b = ", a%b) //1fmt.Println("a / c = ", a/c) //panic: runtime error: integer divide by zerofmt.Println("a % c = ", a%c) //panic: runtime error: integer divide by zero
}
字符+
两边都是数值时,+号是做加法运算,两边都是字符串时是做字符串拼接
char类型参与算术运算,使用的是计算机底层对应的十进制数值。
‘a’ --------- 97 a-z是连续的,'b’对应的值是98,'c’是99
‘A’ --------- 65 A-Z是连续的,'B’对应的值是66,'C’是67
‘0’ --------- 48 0-9是连续的,'1’对应的值是49,'2’是50
func main() {a := 'a'b := 'A'c := '0'fmt.Println(a + 1) // 98fmt.Println(b + 1) // 66fmt.Println(c + 1) // 49
}
自增自减运算:
自增、自减运算符只能作为独立语句,不能用于表达式。
表达式通常是求值代码,可作为右值或参数使用。表达式可作为语句用,但语句却不能当做表达式。
符号 | 作用 | 说明 |
---|---|---|
++ | 自增 | 变量的值加1 |
- - | 自减 | 变量的值减1 |
++和-- 只能放在变量的后面使用,不支持放在前面
参与操作的时候,如果放在变量的后边,先拿变量参与操作,后拿变量做++或者–。
最常见的用法:单独使用。
func main() {a := 1a++// ++a 不支持fmt.Println("a = ", a) // 2a--fmt.Println("a = ", a) // 1
}
赋值运算符:
作用:将一个表达式的值赋给左边,左边必须是可修改的,不能是常量。赋值运算符隐含了强制类型转换。
符号 | 作用 | 说明 |
---|---|---|
= | 普通赋值 | a=10,将10赋值给变量a |
+= | 加后赋值 | a+=b,将a+b的值给a |
-= | 减后赋值 | a-=b,将a-b的值给a |
*= | 乘后赋值 | a*=b,将a×b的值给a |
/= | 除后赋值 | a/=b,将a÷b的商给a |
%= | 取余后赋值 | a%=b,将a÷b的余数给a |
<<= | 左移后赋值 | a<<=b,将a与b的余数给a |
>>= | 右移后赋值 | a>>=b,将a与b的余数给a |
&= | 与后赋值 | |
^= | 异或后赋值 | |
` | =` | 或后赋值 |
赋值运算符和算术运算符一起使用的时候,会优先计算算术运算符
func main() {var sum = 100sum += 5 //105sum /= 5 + 5 // sum = sum /(5+5)fmt.Println(sum)
}
关系运算符:
符号 | 说明 |
---|---|
== | a==b,判断a和b的值是否相等,成立为true,不成立为false |
!= | a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
> | a>b,判断a是否大于b,成立为true,不成立为false |
>= | a>=b,判断a是否大于等于b,成立为true,不成立为false |
< | a<b,判断a是否小于b,成立为true,不成立为false |
<= | a<=b,判断a是否小于等于b,成立为true,不成立为false |
关系运算符的结果都是boolean类型,要么是true,要么是false。
不要把==
写成=
,==是判断是否相等,=是赋值
关系运算符和算术运算符、赋值运算符一起运算时的优先级是
算术运算符 > 关系运算符 > 赋值运算符
func main() {num1 := 1num2 := 2sum := num1+3 > num2 // 先计算num1+3,再拿num1+3的结果和num2比较,最后赋值给sumfmt.Println("num1 == num2", num1 == num2) //falsefmt.Println("num1 != num2", num1 != num2) //truefmt.Println("num1 > num2", num1 > num2) //falsefmt.Println("num1 >= num2", num1 >= num2) //falsefmt.Println("num1 < num2", num1 < num2) //truefmt.Println("num1 <= num2", num1 <= num2) //truefmt.Println("sum = ", sum) //true
}
逻辑运算符:
逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断的结果是 true 或 false。
在逻辑与运算中,只要有一个表达式的值为false,那么结果就可以判定为false了,没有必要将所有表达式的值都计算出来,短路与操作就有这样的效果,可以提高效率。同理在逻辑或运算中,一旦发现值为true,右边的表达式将不再参与运算。
符号 | 作用 | 说明 |
---|---|---|
! | 逻辑非 | 如果条件为true,则为fasle,也就是取反 |
&& | 短路与 | 两个数都是true则为true,否则为false(如果第一个条件为false,则不会执行第二个条件,结果直接为false) |
` | ` |
func main() {a := 1b := 2c := 3fmt.Println(a > b && b < c) // falsefmt.Println(a > b || b < c) // truefmt.Println(!(a > 6)) // truefmt.Println(a > b || a > b && a != 1) // false
}
位运算符:
位运算符是对整数在内存中的二进制进行操作的
运算符 | 描述 |
---|---|
& | 参与运算的两个数对应的二进制位相与,两位都是1才为1 |
| | 参与运算的两个数对应的二进制位相或,两位有1个是1就为1 |
^ | 参与运算的两个数对应的二进制位相异或,两位不同则为1 |
<< | 左移n位就是乘以2的n次方 |
>> | 右移n位就是除以2的n次方 |
func main() {a := 10 // 10的二进制1010b := 11 // 11的二进制1011// 下面都是对10和2的二进制进行操作,首先会先转换成二进制数,然后在运算fmt.Println(a & b) // 1010 = 10fmt.Println(a | b) // 1011 = 11fmt.Println(a ^ b) // 0001 = 1// fmt.Println(a << b) // 20480fmt.Println(a >> b) // 0
}
运算符优先级:
优先级值越大,表示优先级越高
优先级 | 分类 | 运算符 | 结合性 |
---|---|---|---|
1 | 逗号运算符 | , | 从左到右 |
2 | 赋值运算符 | =、+=、-=、*=、/=、 %=、 >=、 <<=、&=、^=、|= | 从右到左 |
3 | 逻辑或 | || | 从左到右 |
4 | 逻辑与 | && | 从左到右 |
5 | 按位或 | | | 从左到右 |
6 | 按位异或 | ^ | 从左到右 |
7 | 按位与 | & | 从左到右 |
8 | 相等/不等 | ==、!= | 从左到右 |
9 | 关系运算符 | <、<=、>、>= | 从左到右 |
10 | 位移运算符 | <<、>> | 从左到右 |
11 | 加法/减法 | +、- | 从左到右 |
12 | 乘法/除法/取余 | *(乘号)、/、% | 从左到右 |
13 | 单目运算符 | !、*(指针)、& 、++、–、+(正号)、-(负号) | 从右到左 |
14 | 后缀运算符 | ( )、[ ]、-> | 从左到右 |