Go 语言指针
Go 语言指针
go语言指针基础
Go 空指针
Go 语言指针数组
Go 语言指向指针的指针
Go 语言指针作为函数参数
go语言指针基础
获取变量内存地址
变量是一种使用方便的占位符,用于引用计算机内存地址(16进制)。
Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import "fmt" func main() { var a int = 10 fmt.Printf( "变量的地址: %x\n" , &a ) } //输出结果: 变量的地址: 20818a220 |
什么是指针:
一个指针变量指向了一个值的内存地址。
类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:
1 | var var_name * var -type |
ar-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。以下是有效的指针声明
1 2 | var ip * int /* 指向整型*/ var fp *float32 /* 指向浮点型 */ |
如何使用指针
指针使用流程:
- 定义指针变量。
- 为指针变量赋值(赋予的是内存地址)。
- 访问指针变量中指向地址的值。
在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | package main import "fmt" //指针声明和赋值 func main() { var ( //实际变量 a int = 33 //指针变量 ip * int ) //将a的地址赋值给指针变量ip ip = &a fmt.Println( "a的值是" , a) fmt.Println( "a的地址是:" , &a) fmt.Println( "指针变量ip的值是:" , ip) fmt.Println( "指针ip 指向的值:" , *ip) } //输出结果: a的值是 33 a的地址是: 0xc000014098 指针变量ip的值是: 0xc000014098 指针ip 指向的值: 33 |
Go 空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil。
nil 指针也称为空指针。
nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。
一个指针变量通常缩写为 ptr。
1 2 3 4 5 6 7 8 9 10 11 12 | package main import "fmt" func main() { var ptr * int fmt.Printf( "ptr 的值为 : %x\n" , ptr ) } //输出结果: ptr 的值为 : 0 |
空指针判断:
1 2 | if (ptr != nil) /* ptr 不是空指针 */ if (ptr == nil) /* ptr 是空指针 */ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package main import "fmt" func main() { var ptr * int if ptr == nil { fmt.Println( "空指针" ) } else { fmt.Println( "非空" ) } } //输出结果: 空指针 |
Go 语言指针数组
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package main import "fmt" func main() { a := [] int {10, 100, 200} for i := 0; i < len(a); i++ { fmt.Printf( "a[%d] = %d\n" , i, a[i]) } } //输出结果: a[0] = 10 a[1] = 100 a[2] = 200 |
有一种情况,我们可能需要保存数组,这样我们就需要使用到指针。
以下声明了整型指针数组:
1 | var ptr [MAX]* int ; |
ptr 为整型指针数组。因此每个元素都指向了一个值。以下实例的三个整数将存储在指针数组中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package main import "fmt" func main() { var ptr [3]* int // 声明一个长度为3的指针数组 a := [] int {10, 100, 200} //定义一个实际数组 for i := 0; i < len(a); i++ { //将地址赋值给指针 ptr[i] = &a[i] fmt.Printf( "第%d个元素的指针地址是:%d\n" , i, &a[i]) } //使用指针变量指向值,进行遍历 for j := 0; j < len(ptr); j++ { fmt.Printf( "a[%d] = %d\n" , j, *ptr[j]) } } //输出结果: 第0个元素的指针地址是:824633762152 第1个元素的指针地址是:824633762160 第2个元素的指针地址是:824633762168 a[0] = 10 a[1] = 100 a[2] = 200 |
Go 语言指向指针的指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。
当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址:
指向指针的指针变量声明格式如下:
1 | var ptr ** int ; |
以上指向指针的指针变量为整型。
访问指向指针的指针变量值需要使用两个 * 号,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package main import "fmt" //指向指针的指针 func main() { var ( a int //变量 ptr * int //指针 pptr ** int //指向指针的指针 ) // 变量赋值 a = 1000 //ptr赋值 a 的地址 ptr = &a //pptr 赋值ptr的地址 pptr = &ptr fmt.Println( "a的值" , a) fmt.Println( "a的地址是" , &a) //ptr=&a 指针变量ptr 存放的是变量a的内存地址 fmt.Println( "指针ptr的值是(ptr):" , ptr) // *ptr= *&a 获取在变量a内存地址存储的值,即变量a的值 fmt.Println( "指针ptr指向的值(*ptr):" , *ptr) // pptr = &ptr 获取指针变量 ptr 的内存地址,即指针变量在内存中的位置 fmt.Println( "指针pptr的值是(pptr):" , pptr) // *pptr = *&ptr 获取存放在指针变量ptr内存地址的存储值(存储的是变量a的内存地址) fmt.Println( "指针pptr指向的值(*pptr):" , *pptr) //等效于*ptr,获取变量a的值 fmt.Println( "指针pptr指向 指针ptr指向的值(**pptr):" , **pptr) } //输出结果: a的值 1000 a的地址是 0xc000014098 指针ptr的值是(ptr): 0xc000014098 指针ptr指向的值(*ptr): 1000 指针pptr的值是(pptr): 0xc000006028 指针pptr指向的值(*pptr): 0xc000014098 指针pptr指向 指针ptr指向的值(**pptr): 1000 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | package main import "fmt" func main(){ var a int = 5 //把ptr指针 指向ss所在地址 var ptr * int = &a //开辟一个新的指针,指向ptr指针指向的地方 var pts * int = ptr //二级指针,指向一个地址,这个地址存储的是一级指针的地址 var pto ** int = &ptr //三级指针,指向一个地址,这个地址存储的是二级指针的地址,二级指针同上 var pt3 *** int = &pto fmt.Println( "a的地址:" ,&a, "\n 值" , a, "\n\n" , "ptr指针所在地址:" ,&ptr, "\n ptr指向的地址:" ,ptr, "\n ptr指针指向地址对应的值" ,*ptr, "\n\n" , "pts指针所在地址:" ,&pts, "\n pts指向的地址:" , pts, "\n pts指针指向地址对应的值:" ,*pts, "\n\n" , "pto指针所在地址:" ,&pto, "\n pto指向的指针(ptr)的存储地址:" ,pto, "\n pto指向的指针(ptr)所指向的地址: " ,*pto, "\n pto最终指向的地址对应的值(a)" ,**pto, "\n\n" , "pt3指针所在的地址:" ,&pt3, "\n pt3指向的指针(pto)的地址:" ,pt3, //等于&*pt3, "\n pt3指向的指针(pto)所指向的指针的(ptr)地址" , *pt3, //等于&**pt3, "\n pt3指向的指针(pto)所指向的指针(ptr)所指向的地址(a):" ,**pt3, //等于&***pt3, "\n pt3最终指向的地址对应的值(a)" , ***pt3) } //输出结果: a的地址: 0xc00009a008 值 5 ptr指针所在地址: 0xc000092010 ptr指向的地址: 0xc00009a008 ptr指针指向地址对应的值 5 pts指针所在地址: 0xc000092018 pts指向的地址: 0xc00009a008 pts指针指向地址对应的值: 5 pto指针所在地址: 0xc000092020 pto指向的指针(ptr)的存储地址: 0xc000092010 pto指向的指针(ptr)所指向的地址: 0xc00009a008 pto最终指向的地址对应的值(a) 5 pt3指针所在的地址: 0xc000092028 pt3指向的指针(pto)的地址: 0xc000092020 pt3指向的指针(pto)所指向的指针的(ptr)地址 0xc000092010 pt3指向的指针(pto)所指向的指针(ptr)所指向的地址(a): 0xc00009a008 pt3最终指向的地址对应的值(a) 5 |
Go 语言指针作为函数参数
Go 语言允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可。
指针属于引用类型。
以下实例演示了如何向函数传递指针,并在函数调用后修改函数内的值,:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package main import "fmt" func main() { var ( a int = 10 b int = 20 ) fmt.Printf( "交换前a=%d,b=%d\n" , a, b) //调用函数,将指针作为参数传递 swap(&a, &b) fmt.Printf( "交换后a=%d,b=%d\n" , a, b) } //定义两个形参,类型是指针(&a,&b作为参数传递进入,因此,*x和&a是与同一个内存地址关联。*y与&b与同一个内存地址关联) func swap(x, y * int ) { *x, *y = *y, *x } //输出结果: 交换前a=10,b=20 交换后a=20,b=10 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package main import "fmt" //实际值的传递 func main() { var ( a int = 10 b int = 20 ) fmt.Printf( "交换前a=%d,b=%d\n" , a, b) //将变量a,b作为参数传递,并使用x,y接收函数的返回值 x, y := swap(a, b) fmt.Printf( "交换后a=%d,b=%d\n" , x, y) } func swap(x, y int ) (a, b int ) { //值传递,两数交换. x, y = y, x fmt.Printf( "swap里x=%d,y=%d\n" , x, y) //需要将交换后的结果,作为返回值传递 return x, y } //输出结果: 交换前a=10,b=20 swap里x=20,y=10 交换后a=20,b=10 |
自古英雄多磨难
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!