运算符的基本介绍

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

  1. 算术运算符
  2. 赋值运算符
  3. 比较运算符/关系运算符
  4. 逻辑运算符
  5. 位运算符
  6. 其它运算符

    算术运算符

    算术运算符是对数值类型的变量进行运算的,比如:加减乘除。在 Go 程序中使用的非常多

    算术运算符的一览表

    | 运算符 | 运算 | 范例 | 结果 | | —- | —- | —- | —- | | + | 正号 | +1 | 1 | | - | 负号 | -1 | -1 | | + | 加 | 1+1 | 2 | | - | 减 | 2-1 | 1 | | | 乘 | 23 | 6 | | / | 除 | 2/1 | 2 | | % | 取模(取余) | 7%5 | 2 | | ++ | 自增 | a=1 a++ | a=2 | | — | 自减 | a=1 a— | a=0 | | + | 字符串 | “he”+”llo” | “hello” |

案例演示

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. //重点讲解 /、%
  7. //说明,如果运算的数都是整数,那么除后,去掉小数部分,保留整数部分
  8. fmt.Println(10 / 4) //2
  9. var n1 float32 = 10 / 4
  10. fmt.Println(n1) // 2
  11. //如果我们希望保留小数部分,则需要有浮点数参与运算
  12. var n2 float32 = 10.0 / 4
  13. fmt.Println(n2)//2.5
  14. // 演示 % 的使用
  15. // 看一个公式 a % b = a - a / b * b
  16. // fmt.Println("10%3=", 10 % 3) // =1
  17. // fmt.Println("-10%3=", -10 % 3) // = -10 - (-10) / 3 * 3 = -10 - (-9) = -1
  18. // fmt.Println("10%-3=", 10 % -3) // =1
  19. // fmt.Println("-10%-3=", -10 % -3) // =-1
  20. // ++ 和 --的使用
  21. var i int = 10
  22. i++ // 等价 i = i + 1
  23. fmt.Println("i=", i) // 11
  24. i-- // 等价 i = i - 1
  25. fmt.Println("i=", i) // 10
  26. }

算术运算符使用的注意事项

  1. 对于除号 “/“,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。 例如: x := 19/5 ,结果是 3
  2. 当对一个数取模时,可以等价 a%b=a-a/b*b , 这样我们可以看到 取模的一个本质运算。
  3. Golang 的自增自减只能当做一个独立语言使用

     //在golang中,++ 和 -- 只能独立使用.
     // var i int = 8
     // var a int 
     // a = i++ //错误,i++只能独立使用 
     // a = i-- //错误, i--只能独立使用
    
     // if i++ > 0 { //错误
     //     fmt.Println("ok")
     // }
    
  4. Golang 的++ 和 — 只能写在变量的后面,不能写在变量的前面,即:只有 a++ a— 没有 ++a —a

  5. Golang 的设计者去掉 c / java 中的 自增自减的容易混淆的写法,让 Golang 更加简洁,统一。(强制性的)

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

    基本介绍

  6. 关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false

  7. 关系表达式 经常用在 if 结构的条件中或循环结构的条件中

    关系运算符一览表

    | 运算符 | 运算 | 范例 | 结果 | | —- | —- | —- | —- | | == | 相等于 | 1==2 | false | | != | 不等于 | 1!=2 | true | | < | 小于 | 1<2 | true | | > | 大于 | 1>2 | false | | <= | 小于等于 | 1<=2 | true | | >= | 大于等于 | 1>=2 | false |

案例演示

    //演示关系运算符的使用
    var n1 int = 9
    var n2 int = 8
    fmt.Println(n1 == n2) //false
    fmt.Println(n1 != n2) //true
    fmt.Println(n1 > n2) //true
    fmt.Println(n1 >= n2) //true
    fmt.Println(n1 < n2) //flase
    fmt.Println(n1 <= n2) //flase
    flag := n1 > n2
    fmt.Println("flag=", flag)

关系运算符的细节说明

  1. 关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false。
  2. 关系运算符组成的表达式,我们称为关系表达式: a > b
  3. 比较运算符==不能误写成 =

    逻辑运算符

    基本介绍

    用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个 bool 值

    逻辑运算的说明

    | 运算符 | 运算 | 范例 | 结果 | | —- | —- | —- | —- | | && | 逻辑与运算符,如果两边的操作数都是true,则为true,否则为false | A :=true
    B :=false
    (A&&B) | false | | || | 逻辑或运算符,如果两边的操作数有一个为true,则为true,否则为false | A :=true
    B :=false
    (A||B) | true | | ! | 逻辑非运算符,如果条件为false,则为true,否则为false | A :=true
    B :=false
    !(A&&B) | true |

案例演示

    //演示逻辑运算符的使用  &&
    var age int = 40
    if age > 30 && age < 50 {
        fmt.Println("ok1")
    }

    if age > 30 && age < 40 {
        fmt.Println("ok2")
    }

    //演示逻辑运算符的使用  ||

    if age > 30 || age < 50 {
        fmt.Println("ok3")
    }

    if age > 30 || age < 40 {
        fmt.Println("ok4")
    }

    //演示逻辑运算符的使用  !

    if age > 30 {
        fmt.Println("ok5")
    }

    if !(age > 30) {
        fmt.Println("ok6")
    }

注意事项和细节说明

  1. &&也叫短路与:如果第一个条件为 false,则第二个条件不会判断,最终结果为 false
  2. ||也叫短路或:如果第一个条件为 true,则第二个条件不会判断,最终结果为 true
     var i int = 10
     //短路与
     //说明 因为  i < 9 为 false ,因此后面的 test() 就不执行
     if i < 9 && test() {
          fmt.Println("ok...")
     }
     //说明 因为  i > 9 为 true ,因此后面的 test() 就不执行
     if i > 9 || test() {
         fmt.Println("hello...")
     }
    

    赋值运算符

    基本的介绍

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

    赋值运算符的分类

    | 运算符 | 描述 | 范例 | | —- | —- | —- | | = | 将一个表达式的值赋给左值 | C=A+B将A+B表达式结果赋值给C | | += | 相加后再赋值 | C+=A等价于C=C+A | | -= | 相减后再赋值 | C-=A等价于C=C-A | | = | 相乘后再赋值 | C=A等价于C=C*A | | /= | 相除后再赋值 | C/=A等价于C=C/A | | %= | 求余后再赋值 | C%=A等价于C=C%A | | <<= | 左移后再赋值 | C<<=2等价于C=C<<2 | | >>= | 右移后再赋值 | C>>=2等价于C=C>>2 | | &= | 按位与后再赋值 | C&=2等价于C=C&2 | | ^= | 按位异或后再赋值 | C^=2等价于C=C^2 | | |= | 按位或后再赋值 | C|=2等价于C=C|2 |

赋值运算的案例演示

    //赋值运算符的使用演示
    // var i int 
    // i = 10 //基本赋值

    //有两个变量,a和b,要求将其进行交换,最终打印结果
    // a = 9 , b = 2 ==> a = 2 b = 9
    a := 9
    b := 2
    fmt.Printf("交换前的情况是 a = %v , b=%v \n", a, b) //交换前的情况是 a = 9 , b=2 
    //定义一个临时变量
    t := a
    a = b 
    b = t 
    fmt.Printf("交换后的情况是 a = %v , b=%v \n", a, b)//交换后的情况是 a = 2 , b=9 

    //复合赋值的操作
    a += 17 // 等价 a = a + 17
    fmt.Println("a=", a)//a= 19

赋值运算符的特点

  1. 运算顺序从右往左
  2. 赋值运算符的左边 只能是变量,右边 可以是变量、表达式、常量值
  3. 复合赋值运算符等价于下面的效果比如:a += 3 等价于a = a + 3

     // 1)赋值运算的执行顺序是从右向左   
     a:=1
     var c int 
     c = a + 3 
     fmt.Println(c)//4
    
     //2)赋值运算符的左边 只能是变量,右边 可以是变量、表达式、常量值
     // 表达式:任何有值都可以看做表达式
     var d int
     d = a //  
     d = 8 + 2 * 8 // =的右边是表达式
     d = test() + 90 //  =的右边是表达式
     //d = 890 // 890常量
     fmt.Println(d)
    

    位运算符

    二进制在运算中的说明

    二进制是逢 2 进位的进位制,0、1 是基本算符。现代的电子计算机技术全部采用的是二进制,因为它只使用 0、1 两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用 0和 1 两个数字及其组合来表示任何数。进位规则是“逢 2 进 1”,数字 1 在不同的位上代表不同的值, 按从右至左的次序,这个值以二倍递增。
    在计算机的内部,运行各种运算时,都是以二进制的方式来运行。

    原码、反码、补码

    对于有符号的而言

  4. 二进制的最高位是符号位:0表示正数,1表示负数 1 --> **0**000 0001 -1 --> **1**000 0001

  5. 正数的原码、反码、补码都一样
  6. 负数的反码 = 它的原码符号位不变,其他位取反(0->1 1->0)
    1. 1 ==> 原码 0000 0001 反码 0000 0001 补码 0000 00001
    2. -1 ==> 原码 1000 0001 反码 1111 1110 补码 1111 1111
  7. 负数的补码=它的反码+1
  8. 0的反码,补码都是0
  9. 在计算机运算的时候,都是以补码的方式来运算

    位运算符和移位运算符

    Golang 中有 3 个位运算分别是按位与&、按位或|、按位异或^
    它们的运算规则是:

  10. 按位与 & 两位全为1,结果为 1,否则为 0

  11. 按位或 | 两位有一个为 1,结果为 1,否则为 0
  12. 按位异或 ^ 两位一个为 0,一个为 1,结果为 1,否则为 0

Golang 中有 2 个移位运算符
>>、<< 右移和左移,运算规则:

  1. 右移运算符 >> 低位溢出,符号位不变,并用符号位补溢出的高位(正数补零,负数补1,移几位补几个)
  2. 左移运算符 << 符号位不变,低位补 0 | 运算符 | 描述 | | —- | —- | | & | 将参与运算的两数各对应的二进制相与。运算规则是:同时为1,结果为1,否则为0 | | | | 将参与运算的两数各对应的二进制相或。运算规则是:有一个为1,结果为1,否则为0 | | ^ | 将参与运算的两数各对应的二进制相异或。运算规则是二进位不同,结果为1,否则为0 | | << | 将”<<”左边的运算数的各二进位全部左移动若干位,高位丢弃,低位补0。左移n位就是乘以2的n次方 | | >> | 将”>>”左边的运算数的各二进位全部右移动若干位。右移n位就是除以2的n次方 |

位运算的练习题

    fmt.Println(2 & 3)   //10 & 11 = 10  --> 2
    fmt.Println(2 | 3)   // 10 | 11 = 11  --> 3
    fmt.Println(13 & 7)  // 1101 & 0111 = 0101 --> 5
    fmt.Println(5 | 4)   //  0101 | 0100 = 0101 --> 5
    fmt.Println(-3 ^ 3)  // 1101(补码)^0011 = 1110(补码) --> -2
    fmt.Println(1 >> 2)  // 0001 >> 2 = 0000 --> 0
    fmt.Println(-1 >> 2) //1111(补码) >> 2 = 1111(补码) --> -1
    fmt.Println(1 << 2)  // 0001 << 2 = 0100 --> 4
    fmt.Println(-1 << 2) //1111(补码) << 2 = 1100(补码) --> -4

其它运算符

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

运算符的优先级

运算符的优先级的一览表

分类 描述 关联性
后缀运算符 ( )、[ ]、-> 从左到右
单目运算符 !、*(指针)、& 、++、—、+(正号)、-(负号) 从右到左
乘法/除法/取余 *(乘号)、/、% 从左到右
加法/减法 +、- 从左到右
位移运算符 <<、>> 从左到右
关系运算符 <、<=、>、>= 从左到右
相等/不等 ==、!= 从左到右
按位与 & 从左到右
按位异或 ^ 从左到右
按位或 | 从左到右
逻辑与 && 从左到右
逻辑或 || 从左到右
赋值运算符 =、+=、-=、*=、/=、 %=、 >=、 <<=、&=、^=、|= 从右到左
逗号运算符 , 从左到右

对上表的说明

  1. 运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如上表,上一行运算符总是优先于下一行。
  2. 只有单目运算符、赋值运算符是从右向左运算的。
  3. 梳理了一个大概的优先级

    1. 括号,++, —
    2. 单目运算
    3. 算术运算符
    4. 移位运算
    5. 关系运算符
    6. 位运算符
    7. 逻辑运算符
    8. 赋值运算符
    9. 逗号

      进制

      进制的表示方式

      对于整数,有四种表示方式:
  4. 二进制:0,1 ,满 2 进 1。在 golang 中,不能直接使用二进制来表示一个整数,它沿用了 c 的特点。

  5. 十进制:0-9 ,满 10 进 1。
  6. 八进制:0-7 ,满 8 进 1. 以数字 0 开头表示。
  7. 十六进制:0-9 及 A-F,满 16 进 1. 以 0x 或 0X 开头表示。此处的 A-F 不区分大小写。

     var i int = 5
     //二进制输出 
     fmt.Printf("%b \n", i)//101
    
     //八进制:0-7 ,满8进1. 以数字0开头表示
     var j int = 011 // 011=> 9
     fmt.Println("j=", j)//j= 9
    
     //0-9及A-F,满16进1. 以0x或0X开头表示
     var k int = 0x11 // 0x11=> 16 + 1 = 17
     fmt.Println("k=", k)//k= 17
    

    进制的图示

    | 十进制 | 十六进制 | 八进制 | 二进制 | | —- | —- | —- | —- | | 0 | 0 | 0 | 0 | | 1 | 1 | 1 | 1 | | 2 | 2 | 2 | 10 | | 3 | 3 | 3 | 11 | | 4 | 4 | 4 | 100 | | 5 | 5 | 5 | 101 | | 6 | 6 | 6 | 110 | | 7 | 7 | 7 | 111 | | 8 | 8 | 10 | 1000 | | 9 | 9 | 11 | 1001 | | 10 | A | 12 | 1011 | | 11 | B | 13 | 1111 | | 12 | C | 14 | 10000 | | 13 | D | 15 | 10001 | | 14 | E | 16 | 10011 | | 15 | F | 17 | 10111 |

进制转换

其它进制转十进制

规则:从低位(右边)开始,将每个位上的数提取出来,乘以进制的(位数-1)次方,然后求和
案例:二进制1011转换为十进制的数
1011 = 12^0 + 12^1 + 02^2 + 12^3 = 1 + 2 + 0 +8 =11

十进制转其它进制

规则:将该数不断除以要转换的进制,直到商为0为止,然后将每步得到的余数倒过来,就是对应的进制数了
案例:将56转换成二进制
56 ÷ 2 = 28 余 0
28÷ 2 = 14 余 0
14÷ 2 = 7 余 0
7 ÷ 2 = 3 余 1
3 ÷ 2 = 1 余 1
1 ÷ 2 = 0 余 1
56 = 111000

其他进制转二进制

规则:将其他进制的每一位,转成对应的一个二进制数即可
案例:将0x237 转成二进制数
7 = 0111
3 = 0011
2 = 10
0x237 = 1000110111

二进制转其它进制

规则:将二进制数每运算符 - 图1(n为其他进制)位一组,转成对应的进制数即可
案例:将二进制:11010101转成十六进制
1010 = 0x5
1101 = 0xD
11010101 = 0xD5