golang基础学习——指针和运算符

指针

基本介绍

  1. 基本数据类型,变量存的就是值,也叫值类型。
  2. 获取变量的地址,用&,比如:var num int,获取num的地址:&num
  3. 指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值 比如:var ptr *int = &num
  4. 获取指针类型所指向的值,使用:*,比如 var ptr * int,使用 *ptr获取ptr指向的值。
    demo:
package main
import (
	"fmt"
)

//golang中指针的使用
func main() {
	var i int = 10
	//i的地址是什么,&i
	fmt.Println("i的地址为:", &i) //i的地址为: 0x14000014088

	//ptr是一个指针变量,ptr的类型为*int, ptr本身的值为&i
	var ptr *int = &i
	fmt.Println("ptr:", ptr)       //ptr: 0x14000124008
	fmt.Println("ptr所指向的值:", *ptr) //ptr所指向的值: 10
}

demo02:通过指针修改所指向地址的值

package main
import (
	"fmt"
)
func main() {
	var num int = 99
	fmt.Println("num的地址:", &num) //num的地址: 0x14000014088
	var ptr *int = &num
	*ptr = 199
	fmt.Println("通过指针修改后的num的值为:", num) //通过指针修改后的num的值为: 199
}

指针使用细节

  • 值类型,都有对应的指针类型,形式为*数据类型, 比如int 对应的指针类型为 *int,float32对应的指针类型就是 *float32,以此类推。
  • 值类型包括:基本数据类型int系列,float系列,bool,string、数组和结构体struct。

值类型和引用类型

值类型和引用类型的说明

  • 值类型:基本数据类型int系列,float系列,bool,string,数组和结构体struct
  • 引用类型:指针、slice切片、map、管道chan、interface等都是引用类型

值类型和引用类型使用特点

  • 值类型:变量直接存储值,内存通常在栈中分配
  • 引用类型:变量存储的是一个地址,这个地址对应的空间才是真正的存储数据(值),内存通常在堆中分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收。

标识符命名注意事项

  1. 包名:保持package的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和标准库不要冲突fmt
  2. 变量名、函数名、常量名:采用驼峰法,如stuName。
  3. 如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用(注:可以简单的理解成,首字母大写是公开的,首字母小写是私有的),在golang中没有public和private关键字
    demo:
    golang基础学习——指针和运算符_第1张图片

    遇到的问题:Go代码引入自己创建的包,运行时出现 package 包路径 is not in GOROOT 问题。
    用环境变量 GO111MODULE 开启或关闭模块支持,它有三个可选值:off、on、auto,默认值是 auto。
    解决方案:将GO111MODULE修改为off,在终端输入
go env -w GO111MODULE=off

再运行main.go即可运行。

运算符

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

  1. 算术运算符
  2. 赋值运算符
  3. 比较运算符
  4. 逻辑运算符
  5. 位运算符
  6. 其它运算符 & *
    note:go语言中没有三元运算符。

算术运算符

对数值类型的变量进行运算,如加减乘除。在go中使用的非常多。
除法的案例:

package main
import (
	"fmt"
)
func main() {
	//说明,如果运算的数都是整数,那么除后,去掉小数部分,保留整数部分
	fmt.Println(10 / 4) //2

	var n1 float32 = 10 / 4
	fmt.Println(n1) //2

	//如果我们希望保留小数,则需要浮点数参与运算
	var n2 float32 = 10 / 4.0
	fmt.Println(n2) //2.5
}

取模的案例:

func main() {
	//取模运算
	//a % b = a - a / b * b
	fmt.Println(10 % 3)   //1
	fmt.Println(-10 % 3)  //-1
	fmt.Println(10 % -3)  //1
	fmt.Println(-10 % -3) //-1
}

++ 和 --的使用案例:

func main() {
	//++ 和--
	var i int = 11
	i++
	fmt.Println("i:", i) //i: 12 相当于i = i + 1
	i--
	fmt.Println("i:", i) //i: 11 相当于i = i - 1
}

算术运算符的使用细节说明

  1. 对于除号“/” ,它的整数和小数除是有区别的,整数之间做除法时,只保留整数部分而舍弃小数部分,例如:x := 19/5 结果为3
  2. 当对一个数取模时,可以等价 a%b= a-a/b*b,这时取模的本质运算。
  3. golang的自增自减只能当作一个独立语言使用时,不能这样使用b := a++ 或者b:= a–
func main() {
	//++和--只能独立使用
	var i int = 8
	var a int
	a := i++ //错误
	a := i-- //错误
	if i++ > 0 { //错误
		fmt.Println("ok")
	}
}
  1. golang的++和–只能写在变量的后面,不能写在变量的前面,即:只有a++ a-- 没有++a --a
func main() {
	var i int = 8
	++i //错误
	--i //错误
}
  1. golang的设计者去掉c/java中的自增自减的容易混淆的写法,让golang更加简洁,统一。(强制性的)
    练习题x2:
    1:假如还有97天放假,问:xx个星期零xx天
    2.定义一个变量保存华氏温度,华氏温度转换摄氏温度的公式为:5/9*(华氏温度-100),请求出华氏温度对应的摄氏温度。
func main() {
	var days int = 97
	fmt.Printf("还剩%d个星期零%d天\n", days/7, days%7) //还剩13个星期零6天

	var temp float32 = 33.2
	stemp := 5.0 / 9 * (temp - 100)
	fmt.Printf("%v 华氏度对应的摄氏度为%v\n", temp, stemp) //33.2华氏度对应的摄氏度为-37.111115
}

关系运算符

介绍:关系运算符的结果都是bool型,要么是true,要么是false;关系表达式经常用在if结构的条件转换或者循环结构的条件中。

func main() {
	//演示关系运算符的使用
	var n1 int = 9
	var n2 int = 10
	fmt.Println(n1 == n2) //false
	fmt.Println(n1 != n2) //ture
	fmt.Println(n1 >= n2) //false
	fmt.Println(n1 <= n2) //true
	fmt.Println(n1 > n2)  //false
	fmt.Println(n1 < n2)  //true
	flag := n1 > n2
	fmt.Println(flag) //false
}

关系运算符细节说明

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

逻辑运算符

介绍:用于连接多个条件(一般来说就是关系表达式),最终的结果也是一个bool值。
与或非,&& || !(和其它语言类似)
demo:

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

	//演示逻辑运算符的使用 &&
	if age > 30 || age < 50 {
		fmt.Println("ok3") //ok3
	}
	if age > 30 || age < 40 {
		fmt.Println("ok4") //ok4
	}

	//演示逻辑运算符的使用 !
	if age > 30 {
		fmt.Println("ok5") //仅输出ok5
	}
	if !(age > 30) {
		fmt.Println("ok6")
	}
}

逻辑运算符注意事项和细节说明

  1. &&也叫短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false
  2. ||也叫短路或:如果第一个条件为ture,则第二个条件不会判断,最终结果为true
    demo:
package main
import (
	"fmt"
)
func test() bool {
	fmt.Println("test...")
	return true
}
func main() {
	//短路与的演示
	var i int = 10
	if i > 9 && test() {
		fmt.Println("ok1")
	}
	//test...
	//ok1
	因为i<9为false,所以不执行test()
	if i < 9 && test() {
		fmt.Println("ok1")
	}
	//无输出

	//短路或的演示
	if i < 9 || test() {
		fmt.Println("hello")
	}
	//test...
	//hello
	//因为i>9为true,所以不执行test(),仅输出hello
	if i > 9 || test() {
		fmt.Println("hello")
	}
	//hello
}

赋值运算符

介绍:赋值运算符就是将某个运算后的值,赋给指定的变量。
常见的如:=、+=、-=、/=、%=,先进行等号前的运算再赋值,如c+=a 等同于c = c+a。
demo:

func main() {
	//赋值运算符的使用
	//有两个变量,对其进行交换,打印最终结果
	a := 9
	b := 3
	fmt.Printf("交换前的a:%d,b:%d\n", a, b) //交换前的a:9,b:3
	//定义临时变量
	t := a
	a = b
	b = t
	fmt.Printf("交换后的a:%d,b:%d\n", a, b) //交换后的a:3,b:9

	//复合赋值的操作
	a += 20
	fmt.Println("a:", a) //23
}

赋值运算符的特点

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

测试题

有两个变量,a和b,要求将其进行交换,但是不允许使用中间变量,打印最终结果。
demo:

func main() {
	var a int = 5
	var b int = 8
	//解法1
	a, b = b, a
	fmt.Printf("a:%v,b:%v\n", a, b) //a:8,b:5
	//解法2
	a = a + b
	b = a - b
	a = a - b
	fmt.Printf("a:%v,b:%v\n", a, b) //a:5,b:8
}

运算符优先级如下表


note:只有单目运算符、赋值运算符是从右向左运算的。

位运算符

位运算符一览,在后续的二进制学习中会进一步说明。
golang基础学习——指针和运算符_第2张图片

其它运算符

主要有两个&和*,分别为本文第一部分指针相关的取地址和指针取值。
note:go语言不支持三元运算符,只能使用if else替代。
demo:求三个数最大值:

func main() {
	var n1 int = 58
	var n2 int = 73
	var n3 int = 81
	var max int
	if n1 > n2 && n1 > n3 {
		max = n1
	} else if n2 > n1 && n2 > n3 {
		max = n2
	} else {
		max = n3
	}
	fmt.Println("三个数之中最大值为:", max) //三个数之中最大值为: 81
}

你可能感兴趣的:(go,golang,开发语言,后端)