您的位置:首页 > 编程语言 > Go语言

Go 语言指针

2022-03-29 13:39 531 查看

Go 语言指针

go语言指针基础

Go 空指针

Go 语言指针数组

Go 语言指向指针的指针

Go 语言指针作为函数参数

 

 

go语言指针基础

获取变量内存地址

变量是一种使用方便的占位符,用于引用计算机内存地址(16进制)。

Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。

package main

import "fmt"

func main() {
var a int = 10

fmt.Printf("变量的地址: %x\n", &a  )
}

//输出结果:
变量的地址: 20818a220

  

什么是指针:

 

 

一个指针变量指向了一个值的内存地址。

类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:

var var_name *var-type

  

ar-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。以下是有效的指针声明

var ip *int        /* 指向整型*/
var fp *float32    /* 指向浮点型 */

  

 

如何使用指针

指针使用流程:

  • 定义指针变量
  • 为指针变量赋值(赋予的是内存地址)。
  • 访问指针变量中指向地址的值。

在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。

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。

package main

import "fmt"

func main() {
var  ptr *int

fmt.Printf("ptr 的值为 : %x\n", ptr  )
}

//输出结果:
ptr 的值为 : 0

  

空指针判断:

if(ptr != nil)     /* ptr 不是空指针 */
if(ptr == nil)    /* ptr 是空指针 */
package main

import "fmt"

func main() {
var ptr *int
if ptr == nil {
fmt.Println("空指针")
} else {
fmt.Println("非空")
}
}

//输出结果:
空指针

  

 

Go 语言指针数组

示例:

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

  

有一种情况,我们可能需要保存数组,这样我们就需要使用到指针。

以下声明了整型指针数组:

var ptr [MAX]*int;

  

ptr 为整型指针数组。因此每个元素都指向了一个值。以下实例的三个整数将存储在指针数组中:

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 语言指向指针的指针

如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。

当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址:

指向指针的指针变量声明格式如下:

var ptr **int;

  

以上指向指针的指针变量为整型。

访问指向指针的指针变量值需要使用两个 * 号,如下所示:

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

  

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 语言允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可。

指针属于引用类型。

以下实例演示了如何向函数传递指针,并在函数调用后修改函数内的值,:

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

  

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

  

 

  

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: