1、保留关键字
关键字不能用于自定义名字,只能在特定语法结构中使用。
![](https://i-blog.csdnimg.cn/blog_migrate/8549528d140b05d2627d7394d5366ef4.png)
2、预定义标识符
![](https://i-blog.csdnimg.cn/blog_migrate/f4f4be76a206e11becafd1fee0c67b53.png)
3、运算符
运算符用以表示数据的运算、赋值和比较等
3.1算术运算符
下面是Go语言中关于算术运算、逻辑运算和比较运算的二元运算符,它们按照优先级递减的顺序排列:
![](https://i-blog.csdnimg.cn/blog_migrate/55f6533cdfc0e7d618be6bbb77073bca.png)
重点: /、%
如果运算的数都是整数,那么除后,去掉小数部分,保留帧数部分
package main
import "fmt"
func main() {
//重点: /、%
//如果运算的数都是整数,那么除后,去掉小数部分,保留帧数部分
fmt.Println(10 / 4)
var n1 float32 = 10 / 4
fmt.Println(n1)
//如果我们希望保留小数部分,则需要有浮点数参与运算
var n2 float32 = 10.0 / 4
fmt.Println(n2)
}
演示 % 的使用
公式 a % b = a - a / b * b
//演示 % 的使用
//公式 a % b = a - a / b * b
fmt.Println("10%3=", 10%3)
fmt.Println("-10%3=", -10%3)
fmt.Println("10%-3=", 10%-3)
fmt.Println("-10%-10=", -10%-10)
++和--的使用
//++ 和 -- 的使用
var i int = 10
i++
fmt.Println("i=", i)
i--
fmt.Println("i=", i)
细节说明
对于除号,整数数和小数除是有区别的,整数之间做除法时,只保留整数部分而舍弃小数部分
对一个取模时,等价于 a-a/b*b
在golang中++和--只能独立使用。
Golang的++和--只能放在变量的后面,不冷血在变量前面
Golang设计者去掉c/java中的自增和自减的容易混淆的写法,让Golang更加简洁,统一。
3.2 关系运算符(比较运算符)
关系运算符的结果都是bool型,也就是要么是true,要么是false
关系表达式,经常在if条件语句中或虚幻结构的条件中
var n1 int = 9
var n2 int = 8
fmt.Println(n1 == n2)
fmt.Println(n1 != n2)
fmt.Println(n1 > n2)
fmt.Println(n1 < n2)
fmt.Println(n1 >= n2)
fmt.Println(n1 <= n2)
flag := n1 > n2
fmt.Println("flag=", flag)
细节说明
关系运算符的结果都是bool型
关系运算符的组成表达式,称为关系表达式
比较运算符"==" 不能写成"="
3.3 逻辑运算符
用于用于连接多个条件,结果也是bool型
//逻辑运算符的使用
var age int = 40
if age > 30 && age < 50 {
fmt.Println("ok")
}
if age > 30 && age < 40 {
fmt.Println("ok")
}
//演示逻辑或 ||
if age > 30 || age < 50 {
fmt.Println("ok")
}
if age > 30 || age < 40 {
fmt.Println("ok")
}
//逻辑非 !
if age > 30 {
fmt.Println("ok")
}
if !(age > 30) {
fmt.Println("ok")
}
3.4赋值算符
将某个运算后的值,赋给指定的变量
// //赋值运算符的案例
// var i int
// i = 10 //基本赋值
//有两个变量,将其进行交换
a := 9
b := 2
//定义一个临时变量
t := a
a = b
b = t
fmt.Printf("a = %v, b = %v\n", a, b)
//复合赋值操作
a += 17 //等价 a = a + 17
fmt.Println("a=", a)
特点
运算顺序是先计算再赋值
赋值运算符的左边,只能是变量。右边可以是变量、表达式、常量值
复合赋值运算符效果:a += 3 --> a = a + 3
3.5位运算符
见7
3.6其他运算符
&,*
a := 100
fmt.Println("a 的地址=", &a)
var ptr *int = &a
fmt.Println("ptr 指向的值是=", *ptr)
}
golang语言明确指明没有三目运算符
3.7运算符的优先级问题
运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序
只有单目运算符、赋值运算符是先赋值的,其他的都是先运算,在赋值。
按照优先级递减的顺序排列:
![](https://i-blog.csdnimg.cn/blog_migrate/77e8849757c3e25865082d7fab26bc2a.png)
5、键盘输入语句
在编程时,需要接收用户输入的数据,就可以使用键盘输入语句来获取
步骤:
导入fmt包
调用包的fmt.Scanln()或者fmt.Scanf()
使用方式:
使用fmt.Scanln()获取
//方式1:Scanln()
var name string
var age byte
var sal float32
var isPass bool
fmt.Println("请输入姓名 ")
fmt.Scanln(&name)
fmt.Println("请输入年龄 ")
fmt.Scanln(&age)
fmt.Println("请输入薪水 ")
fmt.Scanln(&sal)
fmt.Println("请输入是否通过考试 ")
fmt.Scanln(&isPass)
fmt.Printf("名字是 %v \n 年龄是 %v \n 薪水是 %v\n 是否通过考试 %v \n", name, age, sal, isPass)
使用fmt.Scanf()获取
//方式2:fmt.Scanf,可以按指定的格式输入
var name string
var age byte
var sal float32
var isPass bool
fmt.Println("请输入你的姓名,年龄,薪水,是否通过考试,使用空格间隔开")
fmt.Scanf("%s %d %f %t", &name, &age, &sal, &isPass)
fmt.Printf("名字是 %v \n 年龄是 %v \n 薪水是 %v\n 是否通过考试 %v \n", name, age, sal, isPass)
6、进制转换
6.1其他进制转十进制
二进制转十进制:
规则:从最低位开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和
八进制转十进制
规则:从最低位开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和
十六进制转十进制
规则:从最低位开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和
6.2十进制转其他进制
二进制
规则:将该数不断除以二,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制
56-->二进制-->111000
八进制
规则:将该数不断除以八,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制
十六进制
规则:将该数不断除以十六,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制
6.3二进制转八进制和十六进制
八进制:
规则:将二进制数每三位一组(从低位开始组合),转成对应的八进制数即可。
11010101-->0325
十六进制:
规则:将二进制数每四位一组(从低位开始组合),转成对应的八进制数即可。
11010101-->D5
6.4八进制、十六进制转二进制
八进制-->二进制
规则:将八进制数每一位,转成对应的一个3位的二进制即可
十六进制-->二进制
规则:将八进制数每一位,转成对应的一个3位的二进制即可
7、位运算
引入思考:
运行结果
var a int = 1 >> 2
var b int = -1 >> 2
var c int = 1 << 2
var d int = -1 << 2
fmt.Println("a=", a)
fmt.Println("b=", b)
fmt.Println("c=", c)
fmt.Println("d=", d)
运行结果
fmt.Println(2 & 3)
fmt.Println(2 | 3)
fmt.Println(13 & 7)
fmt.Println(5 & 4)
fmt.Println(-3 ^ 3)
二进制在运算中的说明:
二进制是逢2进1的进位制,0、1是基本算符。
原码、反码、补码
对于有符号的而言
二进制的最高位是符号位:0表示正数,1表示负数
1==>[0000 0001], -1==>[1000 0001]
正数的源码,反码,补码都一样
负数的反码=它的源码符号位不变,其它位取反
1 ==> 原码[0000 0001] 反码[0000 0001] 补码[0000 0001]
-1 ==> 原码[1000 0001] 反码[1111 1110] 补码[1111 1111]
负数的补码==它的反码+1
0的反码,补码都是0
在计算机运算的时候,都是以补码的方式来运算的。
位运算符和移位运算符
位运算
按位与& :两位全为1,结果为1,否则为0
按位或 | :两位有一个为1,结果为1,否则为0
按位异或^ :两位一个为0,一个为1,结果为1,否则为0
fmt.Println(2 & 3)
fmt.Println(2 | 3)
fmt.Println(13 & 7)
fmt.Println(5 & 4)
fmt.Println(-2 ^ 2)
移位运算
>>,<<右移和左移,运算规则:
右移运算符 >>,低位溢出,符号位不变,并用符号位补溢出的高度
左移运算符 <<,符号位不变,低位补0
程序流程控制
介绍
在程序中,程序运行的流程控制着程序如何执行,主要有三大流程控制语句
顺序控制
分支控制
循环控制
1、顺序流程控制
顺序从上到下逐行的执行,中间没有任何判断和跳转
var x float32 = 81.32
fmt.Println(x)
var num1 float32 = -0.0089
var num2 float64 = -0.000000042
fmt.Println("num1=", num1, "num2=", num2)
//尾数部分可能丢失,噪声精度损失。-123.0000901
var num3 float32 = -123.0000901
var num4 float64 = -123.0000901
fmt.Println("num3=", num3, "num4=", num4)
注意事项
Golang中定义变量时,采用合法的前向引用
2、分支控制if-else
分支控制就是让程序有选择的执行
单分支
双分支
多分支
2.1单分支
当条件表达式位true时,就会执行{}的代码
if 条件表达式{
程序块
}
package main
import "fmt"
func main() {
var age int
fmt.Println("请输入年龄")
fmt.Scanln(&age)
if age > 18 {
fmt.Println("你年龄大于18岁,要对自己的行为负责哦")
}
}
即使只有一条语句,也必须要用{}括起来
2.2双分支
当条件表达式成立,及执行代码块1,否则执行代码块2,{}必须要有
if 条件表达式{
执行代码块1
} else {
执行代码块2
}
var age int
fmt.Println("请输入年龄")
fmt.Scanln(&age)
if age > 18 {
fmt.Println("你年龄大于18岁,要对自己的行为负责哦")
} else {
fmt.Println("你还未成年")
}
2.3多分支
if 条件表达式{
执行代码块1
} else if 条件表达式2{
执行代码块2
}
.......
else{
执行代码块n
}
多分支只有一个执行入口
var b bool = true
if b == false {
fmt.Println("a")
} else if b {
fmt.Print("b")
} else if !b {
fmt.Println("c")
} else {
fmt.Println("d")
}
2.4嵌套分支
在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支结构称为内层分支,外面的分支结构称为外层分支
不宜过多,建议在三层之内
if 条件表达式{
if 条件表达式{
}......
}else{
}
package main
import "fmt"
func main() {
var month byte
var age byte
var price float64 = 60.0
fmt.Println("请输入游玩的月份")
fmt.Scanln(month)
fmt.Println("请输入游客的年龄")
fmt.Scanln(age)
if month >= 4 && month <= 10 {
if age > 60 {
fmt.Printf("%v 月 年龄 %v 票价:%v", month, age, price*0.3)
} else if age > 18 {
fmt.Printf("%v 月 年龄 %v 票价:%v", month, age, price)
} else {
fmt.Printf("%v 月 年龄 %v 票价:%v", month, age, price/2)
}
} else {
if age >= 18 && age < 60 {
fmt.Println("淡季成人 票价 40")
} else {
fmt.Println("淡季儿童和老人 票价 20")
}
}
}
2.5switch分支结构
switch语句用于基于不同条件下执行不同动作,每一个case分支都是唯一的,从上到下注意测试,知道匹配为止
匹配项后面也不需要再加brea
语法
switch 表达式{
case 表达式1,表达式2,...:
语句块1
case 表达式....:
语句块2
........
default:
语句块
}
package main
import "fmt"
func main() {
var key byte
fmt.Println("请输入一个字符a,b,c,d,e,f,g")
fmt.Scanf("%c", &key)
switch key {
case 'a':
fmt.Printf("周一")
case 'b':
fmt.Printf("周二")
case 'c':
fmt.Printf("周三")
case 'd':
fmt.Printf("周四")
case 'e':
fmt.Printf("周五")
case 'f':
fmt.Printf("周六")
case 'g':
fmt.Printf("周日")
default:
fmt.Println("输入有误")
}
}
细节
case后是一个表达式,可以是常量,变量,有返回值的函数等
case后各个表达式值的数据类型,必须和switch的表达式数据类型一致
case后面可以带多个表达式,使用逗号间隔
case后面的表达式如果是常量,则要求不能重复
case后面不需要带break,程序匹配到一个case后就会执行对应的代码块,然后推出switch,如果一个都匹配不到,则执行default
default不是必须的
switch后也可以不带表达式,类似于if-else分支来使用。
var score int = 90
switch {
case score >90:
fmt.Println("1")
case score <=90 && score >= 70:
fmt.Println("2")
case score >= 60 && score < 70:
fmt.Println("3")
}
switch后也可以直接声明定义一个变量,分号结束,不推荐
switch穿透fallthrough,如果在case语句块后面增加fallthrough,则会继续执行下一个case,也叫switch穿透
Type Switch:switch语句还可以被用于type-switch来判断某个interface变量中实际指向的变量类型