golang 指针实践

1,657 阅读3分钟
package main

import "fmt"

//============================================
//指针基本概念
//指针:就是地址,指向内存地址空间,这个地址往往是在内存中存储的另一个变量的值的起始位置
//指针变量:即存储地址的变量

//go指针特点
//1,默认值:nil
//2,&取变量地址
//3,*取目标对象的值
//4,直接用.来访问成员
/*func main() {
   //代码段01-解释&,*号的应用
   var num = 100  //声明int 类型num
   fmt.Printf("&a=%p\n", &num) //输出:&a=0xc042050080

   //代码段02-声明指针类型
   var p *int=nil
   p=&num
   fmt.Printf("a=%d,*p=%d\n",num,*p)//输出:a=100,*p=100,此处将指针地址赋值给p,用*p访问对象依旧指向同一个值

    //代码段03
   *p=123 //此处直接通过指针修改了对象的值,因为p和a此时指向的对象是同一个,所以a的值也变了
   fmt.Printf("a=%d,*p=%d\n",num,*p)//输出:a=123,*p=123

}*/

//============================================================
//new(T)表达式关于指针的应用
//1,new(T)创建的对象为堆内存上,作用就是创建T类型的匿名变量为该类型变量开辟一块内存空间,然后将这块空间的内存地址作为结果返回。*T
//2,开辟的内存空间的值就是该变量类型的默认值如:new(int)则默认值为0,如果new(bool)则默认值为false
/*func main() {
   var obj *int               //创建int类型的指针
   obj = new(int)             //让*obj指针指向int变量
   fmt.Println("*obj=", *obj) //*obj= 0

   //demo2---演示bool,其他数据类型自行测试
   var obj2 *bool
   obj2 = new(bool)
   fmt.Println("*obj2", *obj2)
   //直接修改指针对象的值
   *obj2 = true
   fmt.Println("*obj2", *obj2)
//注释:我们使用new函数无需担心其内存的生命周期或怎样将其销毁删除,go语言的内存管理系统会帮我们大理一切
}*/

//==================================================
//指针做函数参数
//
/*func main() {
   var a, b = 10, 99
   test(a, b)//输出:a=10,b=99 值类型传参[值类型传参本质是将变量的值copy一份作为参数传给函数]
   fmt.Printf("a=%d,b=%d\n", a, b)

   test2(&a, &b)//输出:&a=99,&b=10 指针传参[指针类型传参本质就是将指向具体内存空间地址当作参数传递,形参通过*直接访问变量的值,函数内部堆形参的操作就是在操作内存空中间的变量值]
   fmt.Printf("&a=%d,&b=%d\n", a, b)

}
func test(a, b int) {
   a, b = b, a
}
func test2(a, b *int) {
   *a, *b = *b, *a
}*/

//==================指针常见错误使用方式====================
//空指针和野指针
func main() {
   //1,空指针:即未被初始化的指针
   var obj *int
   //fmt.Println("*p", *obj) //输出:invalid memory address or nil pointer dereference,无效地址,即没有可指向的内存空间

   //空指针解决方案
   obj=new(int)
   fmt.Println("*p",*obj)

   //2,野指针:即指向未知的内存地址空间
   //var p *int
   //*p = 0x042058080//未知空间
   //fmt.Println("*p",*p)

}

//相关拓展知识块================栈帧==============
//1:用来给函数提供内存空间,取内存于stack上
//2:函数调用时产生栈帧,函数调用结束释放栈帧
//3:栈帧的存储:1,局部变量2,形参(两者地位等同)3,内存字段描述值