运算符

基本介绍

运算符是一种特殊的符号,用于表示数据的运算、赋值、比较

算术运算符

基本介绍

运算符 名称 案例 结果
+ 正号 +3 正3
- 减号 -1 负1
+ 字符串拼接 “he”+”llo” “hello”
+ 1+1 2
- 2-1 1
* 2*3 6
/ 6/2 3
% 取余 7/2 1
++ 自增 1 a = 2; a++ a = 3
自减 1 b = 2; b— b = 1

/ 使用细节

  • 如果运算的数都是整数,那么运算结构会去掉小树部分,仅保留整数部分
  • 如果需要保留小数部分,则需要有浮点数参与运算 ```go // 演示整数除法运算,保留小数部分 package main import ( “fmt” ) func main(){ a, b := 7, 3 e := a / b f := 7.0 / 3 // 注意: 此处不能这样表示: f = 7.0 / b fmt.Printf(“e 的数据类型是%T\n”, e) fmt.Println(“e =”, e) fmt.Printf(“f 的数据类型是%T\n”, f) fmt.Println(“f =”, f) }

/ 代码运行结果展示 e 的数据类型是int e = 2 f 的数据类型是float64 f = 2.3333333333333335 /

  1. <a name="vDdWu"></a>
  2. ### % 使用细节
  3. - 算术运算符中,% 代表取余运算,仅可用于整数
  4. - 运算原理是 a % b = a - (a / b) * b ,此处的 a / b 表示的是 a 整除 b
  5. ```go
  6. // 演示取余运算
  7. package main
  8. import (
  9. "fmt"
  10. )
  11. func main(){
  12. a, b := -7, 3
  13. c := a % b
  14. // 带入公式进行计算 c = -7 - (-7 / 3) * 3 = -7 - (-2) * 3 = -1
  15. fmt.Println("c =", c)
  16. }
  17. /*
  18. 代码运行结果展示
  19. c = -1
  20. */

++ 使用细节

  1. // 演示 ++ 使用
  2. package main
  3. import (
  4. "fmt"
  5. )
  6. func main(){
  7. a := 1
  8. fmt.Println("a =", a)
  9. a++
  10. // a++ 等价于 a = a + 1
  11. fmt.Println("a =", a)
  12. }
  13. /*
  14. 代码运行结果展示
  15. a = 1
  16. a = 2
  17. */

— 使用细节

  1. // 演示 -- 使用
  2. package main
  3. import (
  4. "fmt"
  5. )
  6. func main(){
  7. a := 1
  8. fmt.Println("a =", a)
  9. a--
  10. // a-- 等价于 a = a - 1
  11. fmt.Println("a =", a)
  12. }
  13. /*
  14. 代码运行结果展示
  15. a = 1
  16. a = 0
  17. */

注意事项

  • 对于除号 / ,整数之间做除法运算时,只保留整数部分,即 整除
  • Go中 ++ 、— 只能书写在变量后面,不能写成 ++a 、—a

关系运算符(比较运算符)

基本介绍

  • 关系运算符的结果都是bool型,true / false
  • 关系表达式经常用在 if 条件语句 或 循环控制中 | 运算符 | 名称 | 案例 | 结果 | | —- | —- | —- | —- | | == | 等于 | 4 == 3 | false | | != | 不等于 | 4 != 3 | true | | < | 大于 | 4 < 3 | false | | > | 小于 | 4 > 3 | true | | <= | 小于等于 | 4 <= 3 | false | | >= | 大于等于 | 4 >= 3 | true |

注意事项

  • 关系运算的返回的结果是bool型,只有 true 或 false
  • 关系运算符组成的表达式,称之为关系表达式:a > b
  • 运算符 == 不能写成 =

逻辑运算符

基本介绍

用于连接多个条件,返回的结果是bool型

运算符 名称 描述 示例
&& 逻辑与 若左右两边均为true,则返回true 4 > 3 && 3 > 2, 返回true
|| 逻辑或 若左右两边有一个为true,则返回true 4 > 3 || 3 > 5, 返回true
! 逻辑非 若原条件为true,则返回false !(3 > 5), 返回true

注意事项

  • && 也称 短路与,如果左边的条件为false,则第二个条件不会进行判断,直接返回false
  • || 也称 短路或,如果左边的条件为true,则第二个条件不会进行判断,直接返回true

进制 & 转换

基本介绍

对于整数,有四种表示方式:

  • 二进制:由0 - 1组成,满2进1

在Go中,不能直接使用二进制来表示一个整数,它沿用了C语言的特点
现代计算机技术全部采用的是二进制,因为它只使用了0、1两个数字符号,非常简便。

  • 八进制:由0 - 7组成,满8进1,以数字0开头表示
  • 十进制:由0 - 9组成,满10进1
  • 十六进制:由0 - 9 和 A - F组成,满16进1,以 0x 或 0X 开头表示(A - F 不区分大小写)

A - F 表示 10 - 15

  1. // 演示不同进制输出一个数
  2. package main
  3. import (
  4. "fmt"
  5. )
  6. func main(){
  7. // 使用二进制格式化输出, %b
  8. a := 24
  9. fmt.Printf("a = %b\n", a)
  10. // 使用八进制格式化输出, %o
  11. b := 011
  12. fmt.Printf("b = %b\n", b)
  13. // 使用十进制格式化输出, %d
  14. c := 24
  15. fmt.Printf("c = %d\n", c)
  16. // 使用十六进制格式化输出, %x
  17. d := 0X11
  18. fmt.Printf("d = %v\n", d)
  19. }
  20. /*
  21. 代码运行结果展示
  22. a = 11000
  23. b = 1001
  24. c = 24
  25. d = 17
  26. */

二进制 转 十进制

方法:从最低位(最右边)开始,将每个数乘以2**n-1,然后求和(n表示从右边开始第几位数)
案例:*将二进制数 1011 转换为十进制
1011 = 1
21-1 + 122-1 + 023-1 + 1*24-1 = 11

八进制 转 十进制

方法:从最低位(最右边)开始,将每个数乘以8**n-1,然后求和(n表示从右边开始第几位数)
案例:*将二进制数 0X34A 转换为十进制
0123 = 3
81-1 + 282-1 + 183-1 + 0*84-1 = 83

十六进制 转 十进制

方法:从最低位(最右边)开始,将每个数乘以16**n-1,然后求和(n表示从右边开始第几位数)
案例:*将二进制数 0123 转换为十进制
0X34A = 10
161-1 + 4162-1 + 3163-1 = 842

十进制 转 二进制

方法:将该数不断除2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制
案例:将十进制数 56 转成二进制
image.png

十进制 转 八进制

image.png

十进制 转 十六进制

image.png

原码、反码、补码

对于有符号数而言,二进制的最高位是符号位:0表示整数,1表示负数

二进制 十进制 备注
1 0000 0001 最右边的高位是0,表示正数
-1 1000 0001 最右边的高位是1,表示负数

正数的原码、反码、补码都一样

名称 1 -1
原码 0000 0001 1000 0001
反码 0000 0001 1111 1110
补码 0000 0001 1111 1111

原码

原码使用0、1代替符号+、-,表示正负数;
真值使用+、-表示正负数;

  • 正树的原码是该数值的二进制表示
  • 负数的原码是该数值的二进制表示

反码

  • 正树的反码和原码一样
  • 负数的反码是其符号位不变,其余位取反(0 -> 1,1 -> 0)
  • 0 的反码 是0

补码

  • 正树的补码和原码一样
  • 负数的补码是其反码最低位上 +1
  • 0 的补码 是0
  • 在计算机运算时,都是以补码的方式来运算的

补充链接:知乎: 一篇文章带你弄懂原码、反码和补码及其由来

位运算符

基本介绍

位运算的底层原理: 采用的是两者补码进行位运算, 而非十进制数值进行位运算的。

运算符 说明
按位与 & 按位对比若两者均为1,则结果为1;否则结果均为0
按位或 | 按位对比若两者中有一个为1,则结果为1,否则结果均为0
按位异或 ^ 按位对比若两者一个为1,一个为0,则结果为1,否则结果均为0
左移运算符 << 符号位不变,低位补0
右移运算符 >> 符号位不变,低位溢出,并用符号位补溢出的高位

&|^>><< 均属于双目运算符

  1. // 演示位运算
  2. package main
  3. import (
  4. "fmt"
  5. )
  6. func main (){
  7. // 底层的原理是 2、3 的补码进行位运算
  8. // 所以运算时需要先将2、3转换为二进制原码, 再转换为反码, 再转换为补码
  9. // 位运算的结果也是补码形式, 所以需要将补码形式的结果依次转换为反码、原码
  10. fmt.Println(2 & 3)
  11. fmt.Println(2 | 3)
  12. fmt.Println(2 ^ 3)
  13. // 0000 0011 左移2位 -> 00 0011_ _ 低位补0 -> 0000 1100
  14. fmt.Println(3 << 2)
  15. // 0000 0011 右移2位 -> _ _ 0000 00 符号位补溢出的高位 -> 0000 0000
  16. fmt.Println(3 >> 2)
  17. }
  18. /*
  19. 代码运行结果展示
  20. 2
  21. 3
  22. 1
  23. 12
  24. 0
  25. */

赋值运算符

基本介绍

赋值运算符就是将运算后的值,赋值给指定的变量

运算符 描述 示例
= 直接赋值 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 <<= 2 等价于 a = a << 2
>>= 右移 后 赋值 a >>= 2 等价于 a = a >> 2
&= 按位与 后 赋值 a &= 2 等价于 a = a & 2
|= 按位或 后 赋值 a |= 2 等价于 a = a | 2
^= 按位异或 后 赋值 a ^= 2 等价于 a = a ^ 2

其他运算符

运算符 描述 示例
& 返回变量的存储地址 &a 将返回变量a的实际内存地址
* 指针变量 *a 表示a是一个指针变量

运算符的优先级

  • 运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如下图,从上往下优先级逐级递增,越往下,优先级越高。
  • 只有单目运算符、赋值运算符是从右往左运算的

image.png