Go基础之运算符 | 青训营

96 阅读7分钟

运算符

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符
  • 赋值运算符
  • 其他运算符
  • 拓展-运算符的优先级

算术运算符

算术运算符大家是比较了解的,除了自增和自减两个概念,其他的都是我们很容易了解的
假定:a = 10,b = 5

运算符说明示例
+加法运算符两侧数字相加a + b = 15
-减法运算符左侧数字减去右侧数字a - b = 5
*乘法运算符两侧数字相乘a * b = 50
/除法运算符左侧数字除以右侧数字a / b = 2
%取余运算符左侧数字除以右侧数字后的余数a % b = 0
++自增,自动增1,即a = a + 1 = a++a++,a在运算后值为11
--自减,自动减1,即b = b - 1 = b--b--,b在运算后值为4

代码演示:

package main
import "fmt"

func main() {

   a := 10
   b := 5
   var c int

   c = a + b  //相加
   fmt.Println("a + b = ", c )
   c = a - b  //相减
   fmt.Println("a - b = ", c )
   c = a * b  //相乘
   fmt.Println("a * b = ", c )
   c = a / b  //相除
   fmt.Println("a / b = ", c )
   c = a % b  //取余数
   fmt.Println("a % b = ", c )
   a++        //自增 a += 1
   fmt.Println("自增后:a = ", a )
   b--        //自减
   fmt.Println("自减后:b = ", a )
}

执行结果:

a + b = 15
a - b = 5
a * b = 50
a / b = 2
a % b = 0
自增后:a = 11
自减后:b = 4

关系运算符

关系运算符也可以说是比较运算符,对运算符两侧的数值进行比较,如大小,相等等。如果比较的结果为正确时则返回true,错误则返回false。
假定:a = 10,b = 5

运算符说明示例
<运算符左侧数值是否小于右侧数值,如果大于则返回false,小于则返回truea < b,返回false
>运算符左侧数值是否大于右侧数值,如果大于则返回true,小于则返回falsea > b,返回true
<=运算符左侧数值是否小于等于右侧数值,如果是则返回true,否则返回falsea <= b,返回false
>=运算符左侧数值是否大于等于右侧数值,如果是则返回true,否则返回falsea >= b,返回true
==运算符左侧数值是否等于右侧数值,如果相等则返回true,否则返回falsea == b,返回false
!=运算符左侧数值是否等于右侧数值,如果相等则返回false,否则返回truea != b,返回true

代码演示:

package main
import "fmt"

func main() {

   a := 10
   b := 5
   var c bool

   c = (a < b) 
   fmt.Println("a < b : ", c )
   c = (a > b)
   fmt.Println("a > b : ", c )
   c = (a <= b)
   fmt.Println("a <= b : ", c )
   c = (a >= b)
   fmt.Println("a >= b : ", c )
   c = (a == b) 
   fmt.Println("a == b : ", c )
   c = (a != b)       
   fmt.Println("a != b : ", c )
}

执行结果:

a < b : false 
a > b : true 
a <= b : false 
a >= b : true 
a == b : false 
a != b : true 

逻辑运算符

逻辑运算符在Go语言中非常重要,广泛应用在逻辑判断的地方。
假定a为true,b为false

运算符说明示例
&&逻辑与,符号两侧均为true,则返回true,否则返回falsea && b = false
||逻辑或,符号两侧任意一个为true或两个都为true,则返回true,否则返回falsea || b = true
!逻辑非,用来反转操作数的逻辑状态。如果为true则返回false,反之相同!a = false,!b = true

代码演示:

package main
import "fmt"

func main(){
    var a bool = true
    var b bool = false
    var c bool
    
    c = (a && b)
    fmt.Println("a && b :",c)
    c = (a || b)
    fmt.Println("a || b :",c)
    c = (!a)
    fmt.Println("!a :",c)
}

执行结果:

a && b : false
a || b : true
!a : false

位运算符

位运算符对整数在内存中的二进制位进行操作。
假定p为0,q为1

运算符说明示例
&按位与,如果符号左右数值二进制相对应位都是 1,则结果为 1,否则为 0p & q = 0
|按位或,如果符号左右数值二进制相对应位都是 0,则结果为 0,否则为 1p | q = 1
^按位异或,如果符号左右数值二进制相对应位值相同,则结果为 0,否则为 1p ^ q = 1
<<按位左移运算符,左操作数按位左移右操作数指定的位数q << 1 = 2
>>按位右移运算符,左操作数按位右移右操作数指定的位数q >> 1 = 0

代码演示:

package main
import "fmt"

func main(){
    p := 0
    q := 1
    fmt.Println(p & q)
    fmt.Println(p | q)
    fmt.Println(p ^ q)
    fmt.Println(q << 1)
    fmt.Println(q >> 1)
}

执行结果:

0
1
1
2
0

知识拓展:十进制如何转二进制
要将十进制数转换为二进制数,可以按照以下步骤进行:

  1. 将十进制数从右往左依次除以2,保留商和余数。
  2. 将得到的余数从下往上排列,得到的就是二进制数的各个位上的数字。

具体步骤如下:

  1. 选择一个要转换的十进制数。
  2. 将该十进制数除以2,得到商和余数。将余数写在第一个位置(最右边)。
  3. 使用前一步得到的商作为新的十进制数,重复步骤2,直到商为0为止。
  4. 将每一步得到的余数从下往上依次排列,得到的结果就是二进制数。

例如,将十进制数17转换为二进制数:

第一步. 17 ÷ 2 = 8 ... 1,余数为1。
第二步. 8 ÷ 2 = 4 ... 0,余数为0。
第三步. 4 ÷ 2 = 2 ... 0,余数为0。
第四步. 2 ÷ 2 = 1 ... 0,余数为0。
第五步. 1 ÷ 2 = 0 ... 1,余数为1。

最后将每一步得到的余数从下往上排列,得到的二进制数为10001。

因此,十进制数17转换为二进制数后为10001。

详细运算流程

  1. 将p 和 q转化为二进制数,即 p = (0000)B(0000)_B,q = (0001)B(0001)_B
  2. 二进制相对应位按&、|、^运算规则进行计算
  p & q  0000      p | q  0000         p ^ q  0000
         0001             0001                0001
         ----             ----                ----
         0000             0001                000111,否则为000,否则为1      相同为0,不同为1

赋值运算符

在这里,最常用的是赋值运算符‘=’,将符号右边值赋给左边的变量。其他的运算符大多是算术运算符和赋值运算符的简写。
假定a = 10

运算符说明示例
=将符号右边的值赋给左边变量a = 10
+=将符号左边变量值加上右边数值后再将结果赋给左边变量a += 10,即a = a + 10 = 20
-=将符号左边变量值减去右边数值后再将结果赋给左边变量a -= 1,即a = a - 1 = 9
*=将符号左边变量值乘上右边数值后再将结果赋给左边变量a *= 10,即a = a * 10 = 100
/=将符号左边变量值除以右边数值后再将结果赋给左边变量a /= 10,即a = a / 10 = 1
%=将符号左边变量值对右边数值求余后再将结果赋给左边变量a %= 10,即a = a % 10 = 0
<<=将符号左边变量值左移n位后再将结果赋值给左边变量a <<= 1,即a = (1010)B<<1=(10100)B=(20)D(1010)_B << 1 = (10100)_B = (20)_D
>>=将符号左边变量值右移n位后再将结果赋值给左边变量a >>= 1,即a = (1010)B>>1=(0101)B=(5)D(1010)_B >> 1 = (0101)_B = (5)_D
&=将符号左边变量值与右边数值进行按位与后再将结果赋值给左边变量a &= 1,即a = (1010)B(1010)_B & (0001)B=(0)D(0001)_B = (0)_D
^=将符号左边变量值与右边数值进行按位异或后再将结果赋值给左边变量a ^= 1,即a = (1010)B(1010)_B ^ (0001)B=(11)D(0001)_B = (11)_D
|=将符号左边变量值与右边数值进行按位或后再将结果赋值给左边变量a |= 1,即 a = (1010)B(1010)_B | (0001)B=(11)D(0001)_B = (11)_D

注意:这里的下标B表示为二进制数,下标D表示为十进制数

代码演示:

package main
import "fmt"

func main() {
    //这里a的值是一直在变化的
    var a int = 10
    fmt.Println("a = ", a )
    a += 10
    fmt.Println("(a += 10) = ", a )
    a -= 1
    fmt.Println("(a -= 1) =  ", a )
    a *= 10
    fmt.Println("(a *= 10) = ", a )
    a /= 10
    fmt.Println("(a /= 10) = ", a )
    a <<= 1
    fmt.Println("(a <<= 1) = ", a )
    a >>= 1
    fmt.Println("(a >>= 1) = ", a )
    a &= 1
    fmt.Println("(a &= 1) = ", a )
    a ^= 1
    fmt.Println("(a ^= 1) = ", a )
    a |= 1
    fmt.Println("(a |= 1) = ", a )

}

执行结果:

a =  10
(a += 10) =  20
(a -= 1) =   19
(a *= 10) =  190
(a /= 10) =  19
(a <<= 1) =  38
(a >>= 1) =  19
(a &= 1) =  1
(a ^= 1) =  0
(a |= 1) =  1

其他运算符

运算符说明示例
&返回变量的存储地址&a,即a的存储地址
*指针变量*a,即指针变量a
^按位取反(不要与按位异或混淆)^a,即将a转化为二进制数后按位取反

代码演示:

package main
import "fmt"

func main(){
    a := 2
    var p *int
    p = &a
    fmt.Println("&a :",p)
    fmt.Println("*p :",*p)
    fmt.Println("^a :",^a)    
}

执行结果:

&a : 0xc0000a6058
*p : 2
^a : -3

运算符的优先级

所谓优先级,就是当多个运算符出现在同一个表达式中时,先执行哪个运算符。
Go语言有几十种运算符,被分成十几个级别,有的运算符优先级不同,有的运算符优先级相同,请看下表。 Snipaste_2023-08-19_19-50-18.png 注意:优先级值越大,表示优先级越高。

当然,你可以通过使用括号来临时提升某个表达式的整体运算优先级。