目录

前言

1、指针概念

2、使用指针流程

3、空指针

4、指针数组

5、指向指针的指针

6、多重指针

7、指针作为函数参数


前言

Go 中指针很容易,使用指针可以更简单的执行一些任务。

变量是一种使用方便的占位符,用于引用计算机内存地址。取地址符号是 & ,放到一个变量前使用就会返回相应变量的内存地址。

1、指针概念

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

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

var var_name *var-name

// var_name    为指针变量名
// *var-name   为指针类型
// * 号用于指定变量是作为一个指针

定义指向 int 类型和 float32 的指针。

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

2、使用指针流程

①定义指针变量;

②为指针变量赋值;

③访问指针变量中指向地址的值。

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

示例:

package main

import "fmt"

func main() {
	var (
		a  int  = 10 //实际变量
		ip *int      //指针变量
	)
	//a的地址赋值给ip指针
	ip = &a

	fmt.Println("a的值:", a)
	fmt.Println("a的地址值:", &a)
	fmt.Println("指针ip的值:", ip)
	fmt.Println("指针ip指向的值:", *ip)
}

//运行结果为:
a的值: 10
a的地址值: 0xc000014098
指针ip的值: 0xc000014098
指针ip指向的值: 10

3、空指针

当一个指针被定义后没有分配到任何变量时,它的值是 nil 。

nil 也被称为空指针。

nil 在概念上和其他语言的 null、None、nil、NULL 一样,都指代零值或空值。

一个指针变量通常缩写为 ptr

示例:

package main

import "fmt"

func main() {
	var ptr *int

	fmt.Println("ptr的值为:", ptr)
}

//运行结果为:
ptr的值为: <nil>

空指针判断:

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

4、指针数组

第一种方式:

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

第二种方式:

package main

import "fmt"

func main() {

	var ptr [3]*int             //指针数组声明
	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(a); 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

5、指向指针的指针

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

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

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

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的地址值:", ptr)
	fmt.Println("指针ptr指向的值:", *ptr)
	fmt.Println("指针pptr指向地址对应的值:", *pptr)
	fmt.Println("指针pptr指向指针ptr指向的值:", **pptr)
	fmt.Println("指针pptr的地址", &pptr)
}

//运行结果为:
a的值: 1000
a的地址: 0xc0000aa058
指针ptr指向的值: 1000
指针pptr指向地址对应的值: 0xc0000aa058
指针pptr指向指针ptr指向的值: 1000
指针pptr的地址 0xc0000ce020

6、多重指针

流程:pt3 ---》pto---》ptr---》变量a

示例:

package main

import "fmt"

func main() {
	var (
		//变量a
		a int = 5
		//把ptr指针指向变量a所在地址
		ptr *int = &a
		//开辟一个新的指针,指向ptr指针所指向的地址
		pts *int = ptr
		//二级指针,指向一个地址,这个地址存储的是一级指针的地址
		pto **int = &ptr
		//三级指针,指向一个地址,这个地址存储的是二级指针的地址
		pt3 ***int = &pto
	)
	fmt.Println("a的地址: ", &a)
	fmt.Println("a的值: ", a)
	fmt.Println("-----------------------------")
	fmt.Println("ptr指针所在的地址: ", &ptr)
	fmt.Println("ptr指针指向的地址: ", ptr)
	fmt.Println("ptr指针指向地址(a)所对应的值: ", *ptr)
	fmt.Println("-----------------------------")
	fmt.Println("pts指针所在的地址: ", &pts)
	fmt.Println("pts指针指向的地址: ", pts)
	fmt.Println("pts指针指向地址(a)所对应的值: ", *pts)
	fmt.Println("-----------------------------")
	fmt.Println("pto指针所在地址: ", &pto)
	fmt.Println("pto指针指向的指针(ptr)的存储地址:", pto)
	fmt.Println("pto指针指向的指针(ptr)所指向的地址: ", *pto)
	fmt.Println("pto指针最终指向的地址(a)对应的值: ", **pto)
	fmt.Println("------------------------------")
	fmt.Println("pt3指针所在的地址: ", &pt3)
	fmt.Println("pt3指针指向的指针(pto)的地址", pt3)                      //等于&*pt3
	fmt.Println("pt3指针指向的指针(pto)所指向的指针(ptr)的地址: ", *pt3)        //等于&**pt3
	fmt.Println("pt3指针指向的指针(pto)所指向的指针(ptr)所指向的地址(a): ", **pt3) //等于&***pt3
	fmt.Println("pt3指针最终指向的地址(a)对应的值: ", ***pt3)
}

//运行结果为:
a的地址:  0xc000014098
a的值:  5
-----------------------------
ptr指针所在的地址:  0xc000006028
ptr指针指向的地址:  0xc000014098
ptr指针指向地址(a)所对应的值:  5
-----------------------------
pts指针所在的地址:  0xc000006030
pts指针指向的地址:  0xc000014098
pts指针指向地址(a)所对应的值:  5
-----------------------------
pto指针所在地址:  0xc000006038
pto指针指向的指针(ptr)的存储地址: 0xc000006028
pto指针指向的指针(ptr)所指向的地址:  0xc000014098
pto指针最终指向的地址(a)对应的值:  5
------------------------------
pt3指针所在的地址:  0xc000006040
pt3指针指向的指针(pto)的地址 0xc000006038
pt3指针指向的指针(pto)所指向的指针(ptr)的地址:  0xc000006028
pt3指针指向的指针(pto)所指向的指针(ptr)所指向的地址(a):  0xc000014098
pt3指针最终指向的地址(a)对应的值:  5

7、指针作为函数参数

允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可。

示例:向函数传递指针,并在函数调用后修改函数内的值。

package main

import "fmt"

func main() {
	//定义局部变量
	var a int = 100
	var b int = 200
	fmt.Println("交换前a:", a)
	fmt.Println("交换前b:", b)
	swap(&a, &b)
	fmt.Println("交换后a:", a)
	fmt.Println("交换后b:", b)
}
func swap(x, y *int) { 
	//值传递两数交换
	*x, *y = *y, *x
}

//运行结果为:
交换前a: 100
交换前b: 200
交换后a: 200
交换后b: 100