运算符的基本介绍
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等
- 算术运算符
- 赋值运算符
- 比较运算符/关系运算符
- 逻辑运算符
- 位运算符
- 其它运算符
算术运算符
算术运算符是对数值类型的变量进行运算的,比如:加减乘除。在 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” |
案例演示
package main
import (
"fmt"
)
func main() {
//重点讲解 /、%
//说明,如果运算的数都是整数,那么除后,去掉小数部分,保留整数部分
fmt.Println(10 / 4) //2
var n1 float32 = 10 / 4
fmt.Println(n1) // 2
//如果我们希望保留小数部分,则需要有浮点数参与运算
var n2 float32 = 10.0 / 4
fmt.Println(n2)//2.5
// 演示 % 的使用
// 看一个公式 a % b = a - a / b * b
// fmt.Println("10%3=", 10 % 3) // =1
// fmt.Println("-10%3=", -10 % 3) // = -10 - (-10) / 3 * 3 = -10 - (-9) = -1
// fmt.Println("10%-3=", 10 % -3) // =1
// fmt.Println("-10%-3=", -10 % -3) // =-1
// ++ 和 --的使用
var i int = 10
i++ // 等价 i = i + 1
fmt.Println("i=", i) // 11
i-- // 等价 i = i - 1
fmt.Println("i=", i) // 10
}
算术运算符使用的注意事项
- 对于除号 “/“,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。 例如: x := 19/5 ,结果是 3
- 当对一个数取模时,可以等价
a%b=a-a/b*b
, 这样我们可以看到 取模的一个本质运算。 Golang 的自增自减只能当做一个独立语言使用
//在golang中,++ 和 -- 只能独立使用. // var i int = 8 // var a int // a = i++ //错误,i++只能独立使用 // a = i-- //错误, i--只能独立使用 // if i++ > 0 { //错误 // fmt.Println("ok") // }
Golang 的++ 和 — 只能写在变量的后面,不能写在变量的前面,即:只有 a++ a— 没有 ++a —a
Golang 的设计者去掉 c / java 中的 自增自减的容易混淆的写法,让 Golang 更加简洁,统一。(强制性的)
关系运算符(比较运算符)
基本介绍
关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false
- 关系表达式 经常用在 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)
关系运算符的细节说明
- 关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false。
- 关系运算符组成的表达式,我们称为关系表达式:
a > b
- 比较运算符
==
不能误写成=
逻辑运算符
基本介绍
用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个 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")
}
注意事项和细节说明
- &&也叫短路与:如果第一个条件为 false,则第二个条件不会判断,最终结果为 false
- ||也叫短路或:如果第一个条件为 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
赋值运算符的特点
- 运算顺序从右往左
- 赋值运算符的左边 只能是变量,右边 可以是变量、表达式、常量值
复合赋值运算符等价于下面的效果比如:
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 在不同的位上代表不同的值, 按从右至左的次序,这个值以二倍递增。
在计算机的内部,运行各种运算时,都是以二进制的方式来运行。原码、反码、补码
对于有符号的而言
二进制的最高位是符号位:0表示正数,1表示负数
1 --> **0**000 0001
-1 --> **1**000 0001
- 正数的原码、反码、补码都一样
- 负数的反码 = 它的原码符号位不变,其他位取反(0->1 1->0)
- 1 ==> 原码 0000 0001 反码 0000 0001 补码 0000 00001
- -1 ==> 原码 1000 0001 反码 1111 1110 补码 1111 1111
- 负数的补码=它的反码+1
- 0的反码,补码都是0
-
位运算符和移位运算符
Golang 中有 3 个位运算分别是按位与&、按位或|、按位异或^
它们的运算规则是: 按位与 & 两位全为1,结果为 1,否则为 0
- 按位或 | 两位有一个为 1,结果为 1,否则为 0
- 按位异或 ^ 两位一个为 0,一个为 1,结果为 1,否则为 0
Golang 中有 2 个移位运算符
>>、<< 右移和左移,运算规则:
- 右移运算符 >> 低位溢出,符号位不变,并用符号位补溢出的高位(正数补零,负数补1,移几位补几个)
- 左移运算符 << 符号位不变,低位补 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 是一个指针变量 |
运算符的优先级
运算符的优先级的一览表
分类 | 描述 | 关联性 |
---|---|---|
后缀运算符 | ( )、[ ]、-> | 从左到右 |
单目运算符 | !、*(指针)、& 、++、—、+(正号)、-(负号) | 从右到左 |
乘法/除法/取余 | *(乘号)、/、% | 从左到右 |
加法/减法 | +、- | 从左到右 |
位移运算符 | <<、>> | 从左到右 |
关系运算符 | <、<=、>、>= | 从左到右 |
相等/不等 | ==、!= | 从左到右 |
按位与 | & | 从左到右 |
按位异或 | ^ | 从左到右 |
按位或 | | | 从左到右 |
逻辑与 | && | 从左到右 |
逻辑或 | || | 从左到右 |
赋值运算符 | =、+=、-=、*=、/=、 %=、 >=、 <<=、&=、^=、|= | 从右到左 |
逗号运算符 | , | 从左到右 |
对上表的说明
- 运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如上表,上一行运算符总是优先于下一行。
- 只有单目运算符、赋值运算符是从右向左运算的。
梳理了一个大概的优先级
二进制:0,1 ,满 2 进 1。在 golang 中,不能直接使用二进制来表示一个整数,它沿用了 c 的特点。
- 十进制:0-9 ,满 10 进 1。
- 八进制:0-7 ,满 8 进 1. 以数字 0 开头表示。
十六进制: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
二进制转其它进制
规则:将二进制数每(n为其他进制)位一组,转成对应的进制数即可
案例:将二进制:11010101转成十六进制
1010 = 0x5
1101 = 0xD
11010101 = 0xD5