运算符用以表示数据的运算、赋值和比较等

一、算术运算符

数值类型的变量进行运算,常用的运算符如下表所示:

运算符运算范例结果
+正号+33
-负号-3-3
+5 + 38
-5 - 32
*5 * 315
/15 / 35
%取模(求余)5 % 32
++自增a = 3, a++a = 4
自减a = 3, a–a = 2
+字符串加“Wo” + “rld”“World”

几点说明:

  1. 如果执行除法运算("/")的是整数 (数据类型可以是int或者float),那么除后去掉小数部分,保留整数部分;只有浮点数(小数)参与时才能保留小数部分
  2. 取模运算(%): a % b = a − a / b ∗ b a \% b = a - a / b * b a%b=a−a/b∗b,比如 10 % − 3 = 10 − 10 / ( − 3 ) ∗ ( − 3 ) = 1 10 \% -3 = 10 - 10 / (-3) * (-3) = 1 10%−3=10−10/(−3)∗(−3)=1,其中 10 / ( − 3 ) = − 3 10 / (-3) = -3 10/(−3)=−3。
  3. Golang中的 自增( + + ++ ++) 和 自减( − − -- −−) 只能当做一个独立语句使用,并且只能写在变量后面不允许 a = i + + a = i++ a=i++ 或 a = i − − a = i-- a=i−−, b : = a + + b := a++ b:=a++ 或 b : = a − − b := a-- b:=a−−, + + a ++a ++a 或 − − a --a −−a 这样使用。
// 自增++和自减--只有一种使用方式:写在变量后,独立成一条语句
a++
a--

示例:

package main

import (
  "fmt"
)
func main() {
  // 假如还有97天放假,计算还有多少个星期零几天
  var days int = 97
  var weeks int = days / 7
  var day int = days % 7
  fmt.Printf("%d 个星期 %d 天\n", weeks, day)

  // 定义一个变量保存华氏温度,将其转换为对应的摄氏温度
  // 华氏温度转摄氏温度:5 / 9 * (华氏温度 - 100)
  var hTemp float32 = 305.0
  var cTemp float32 = 5.0 / 9 * (hTemp - 100)
  fmt.Printf("华氏温度为: %v, 摄氏温度为: %v\n", hTemp, cTemp)
}

输出结果为:

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

关系运算符的结果都是bool型,非 true 即 false经常用在 if 结构或循环结构的条件中

运算符运算范例结果
==相等5 == 3false
!=不等于5 != 3true
<小于5 < 3false
>大于5 > 3true
<=小于等于5 <= 3false
>=大于等于5 >= 3true

三、逻辑运输符

连接多个条件 (通常是关系表达式),最终的结果也是一个bool值。

  1. &&: 逻辑运算符,两边的操作数都为 true 时,结果为true,否则为false。
  2. ||: 逻辑运算符,两边的操作数有一个为true时,结果为true;操作数都为false时,结果才为false。
  3. !: 逻辑运算符,! true = false,! false = true。

示例:

package main

import (
  "fmt"
)
func main() {
  var age int = 20
  para1 := 10
  para2 := 30
  
  // 注意:Go 中的 if 条件语句不加小括号
  if para1 < age && para2 > age { // true
    fmt.Println("OK!") // 输出打印 OK!
  }
}

Tips:逻辑与 && 也叫短路与,若第一个条件为false,则不用判断第二个条件,结果为false;逻辑或 || 也叫短路或,若第一个条件为true,则不用判断第二个条件,结果为true。

四、赋值运算符

赋值运算符就是将某个运算后的值,赋给指定的变量常用的赋值运算符包括:

  1. = = =, C = 5 + 3 C=5+3 C=5+3,即将 ( 5 + 3 ) = 8 (5+3)=8 (5+3)=8 赋值给 C C C;
  2. + = += +=, C + = 3 C+=3 C+=3,即 C = C + 3 C=C+3 C=C+3;
  3. − = -= −=, C − = 3 C-=3 C−=3,即 C = C − 3 C=C-3 C=C−3;
  4. ∗ = *= ∗=, C ∗ = 3 C*=3 C∗=3,即 C = C ∗ 3 C=C*3 C=C∗3;
  5. / = /= /=, C / = 3 C/=3 C/=3,即 C = C / 3 C=C/3 C=C/3;
  6. % = \%= %=, C % = 3 C\%=3 C%=3,即 C = C % 3 C=C\%3 C=C%3。

除此之外,还有涉及二进制运算的赋值运算符

  1. < < = <<= <<=,左移后赋值, C < < = 2 C<<=2 C<<=2 即 C = C < < 2 C=C<<2 C=C<<2;
  2. > > = >>= >>=,右移后赋值, C > > = 2 C>>=2 C>>=2 即 C = C > > 2 C=C>>2 C=C>>2;
  3. & = \&= &=,按位与后赋值, C & = 2 C\&=2 C&=2 即 C = C & 2 C=C\&2 C=C&2;
  4. ∣ = |= ∣=,按位或后赋值, C ∣ = 2 C|=2 C∣=2 即 C = C ∣ 2 C=C|2 C=C∣2;
  5. ^ = = =,按位异或后赋值, C C C ^ = 2 =2 =2 即 C = C C=C C=C^ 2 2 2。

1. 赋值运算符的特点

  1. 运算顺序从右往左
  2. 赋值运算符的左边只能是变量,右边可以是变量、表达式 (任何有值的都可以看做表达式)、常量

2. 练习题

有两个变量,a 和 b,要求不使用中间变量交换a 和 b的值

package main

import (
  "fmt"
)
func main() {
  a := 10
  b := 36
  fmt.Printf("交换前的值为: a = %v, b = %v\n", a, b)

  // 不使用中间变量完成 a 和 b 的交换
  a = a + b
  b = a - b // b = a + b - b = a
  a = a - b // a = a + b - a = b
  fmt.Printf("交换后的值为: a = %v, b = %v\n", a, b)
}

输出结果为:

五、运算符的优先级

运算符的优先级 (表达式运算中的运算顺序) 大致为 (从上到下优先级从高到低)

运算符
括号, + + ++ ++, − − -- −−
单目运算符
单目运算符
移位运算
关系运算符
位运算符
逻辑运算符
赋值运算符
逗号

只有单目运算符赋值运算符从右向左运算的。

六、位运算符

1. 原码、反码、补码

对于有符号的数而言:

  1. 二进制的最高位是符号位:0表示正数,1表示负数;
  2. 正数的原码、反码、补码都一样
  3. 负数的反码:原码的符号位不变,其他位按位取反;
  4. 负数的补码:反码+1;
  5. 0的反码和补码都是0;
  6. 计算机运算的时候都是以补码的形式运算的。

2. 按位与:&

运算规则:有0则0,双1为1。

比如:2 & 3 = 0000 0010 (补码) & 0000 0011 (补码) = 0000 0010 (补码 = 原码) = 2

3. 按位或:|

运算规则:有1则1,双0为0。

比如:2 | 3 = 0000 0010 | 0000 0011 = 0000 0011 = 3

4. 按位异或:^

运算规则:不同为1,相同为0。

比如:2 ^ 3 = 0000 0010 ^ 0000 0011 = 0000 0001 = 1

-2 ^ 2:-2的原码为 1000 0010,反码为 1111 1101,补码为反码+1即1111 1110,2的补码=原码=0000 0010,-2 ^ 2 = 1111 1110 ^ 0000 0010 = 1111 1100 (补码) = 1000 0100 (原码) = -4。

5. 移位运算符

1) 右移运算符 >>

运算规则:低位溢出,符号位不变,用符号位补溢出的高位。

比如:1>>2,1的补码为0000 0001,右移两位之后的结果为 0000 0000 (补码=原码) = 0。

2) 左移运算符 <<

运算规则:符号位不变,低位补0。

比如:1<<2,1的补码为0000 0001,左移两位之后的结果为 0000 0100 (补码=原码) = 4。

七、其他运算符

  1. &:返回变量存储地址;
  2. *:指针变量;
  3. Go中明确不支持三元运算符三元运算符等价于用 if-else:

示例:求两个数和三个数中的最大值。

package main

import (
  "fmt"
)
func main() {
  a := 10
  b := 36
  var max int
  // 求两个数中的最大值
  if a >= b {
    max = a
  } else {
    max = b
  }
  fmt.Printf("最大值为: max = %v\n", max)
  
  // 求三个数中的最大值
  /****************************
  偷懒写法:
  if max < c {
    max = c
  }
  *****************************/
  c := 42
  if a >= b && a >= c {
    max = a
  } else if b >= c {
    max = b
  } else {
    max = c
  }
  fmt.Printf("最大值为: max = %v\n", max)
}