• 十一、指针


    指针

    1、指针的使用

    一个指针变量指向了一个值的内存地址。
    var ip *int /* 指向整型*/
    var fp *float32 /* 指向浮点型 */

    代码示例

    package main
     
    import "fmt"
     
    func main() {
        var a int = 20 /* 声明实际变量 */
        var ip *int /* 声明指针变量 */
    
        ip = &a /* 指针变量的存储地址 */
    
        fmt.Printf("a 变量的地址是: %x\n", &a)
    
        /* 指针变量的存储地址 */
        fmt.Printf("ip 变量储存的指针地址: %x\n", ip)
    
        /* 使用指针访问值 */
        fmt.Printf("*ip 变量的值: %d\n", *ip)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    查看运行结果
    在这里插入图片描述

    2、空指针

    当一个指针被定义后没有分配到任何变量时,它的值为nil
    nil 指针也称为空指针 ,一个指针变量通常缩写为 ptr

    代码示例

    package main
    
    import "fmt"
    
    func main() {
    	var ptr *int
    	fmt.Printf("ptr: %v\n", ptr)
    	if ptr == nil {
    		fmt.Println("ptr是空指针")
    	} else {
    		fmt.Println("ptr不是空指针")
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    查看运行结果
    在这里插入图片描述

    3、指针数组

    1. 定义长度为3的整形数组
      代码示例
    package main
    
    import "fmt"
    
    func main() {
    	a := []int{10, 20, 30}
    	for i := 0; i < len(a); i++ {
    		fmt.Printf("a[%d] = %d\n", i, a[i])
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    查看运行结果
    在这里插入图片描述

    1. 声明整形指针数组
    var ptr [MAX]   *int
    
    • 1

    *** ptr 为整形指针数组,因此每个元素都指向了一个值,下面示例中的三个整数将存储在指针数组中**
    代码示例

    package main
    
    import "fmt"
    
    func main() {
    	a := []int{10, 20, 30} //世纪数组
    	var ptr [3]*int        //指针数组申明
    	//对实际数组进行遍历
    	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])
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    查看运行结果
    在这里插入图片描述

    4、指向指针的指针

    1. 概述及实例
    • 如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量

    • 当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址:
      在这里插入图片描述

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

    var ptr **int;
    
    • 1

    代码示例

    package main
    
    import "fmt"
    
    func main() {
    	var (
    		a    int   //变量
    		ptr  *int  //指针
    		pptr **int //指向指针的指针
    	)
    	a = 100 //变量赋值
    
    	//指针ptr地址
    	ptr = &a
    
    	//指向指针ptr地址
    	pptr = &ptr
    
    	//获取pptr的值
    	fmt.Printf("变量a = %d\n", a)
    	fmt.Println("变量a的地址 =", &a)
    	fmt.Printf("指针变量 *ptr = %d\n", *ptr)
    	fmt.Println("指针pptr指向的值", *pptr)
    	fmt.Printf("指向指针的指针变量 **pptr = %d\n", **pptr)
    	fmt.Println("pptr指针的地址 =", &pptr)
    }
    
    • 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

    查看运行结果
    在这里插入图片描述

    4、多重指针

    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指针指向地址所对应的值: ", *ptr)
    	fmt.Println("-----------------------------")
    	fmt.Println("pts指针所在的地址: ", &pts)
    	fmt.Println("pts指针指向的地址: ", pts)
    	fmt.Println("pts指针指向地址所对应的值: ", *pts)
    	fmt.Println("-----------------------------")
    	fmt.Println("pto指针所在地址: ", &pto)
    	fmt.Println("pto指针指向的指针(ptr)的存储地址", pto)
    	fmt.Println("pto指针指向的指针(ptr)所指向的地址: ", *pto)
    	fmt.Println("pto指针最终指向的地址对应的值: ", **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)
    }
    
    • 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

    查看运行结果
    在这里插入图片描述

    5、指针作为函数参数

    • 允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可
    • 向函数传递指针,并在函数调用后修改函数内的值

    代码示例

    package main
    
    import "fmt"
    
    func main() {
    	var (
    		a int = 100
    		b int = 300
    	)
    	fmt.Printf("交换前a的值: %d\n", a)
    	fmt.Printf("交换前b的值: %d\n\n", b)
    
    	swap(&a, &b)
    
    	fmt.Printf("交换后a的值: %d\n", a)
    	fmt.Printf("交换后b的值: %d\n", b)
    }
    
    func swap(x, y *int) {
    	//值传递,两数交换
    	*x, *y = *y, *x
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    查看运行结果
    在这里插入图片描述

    总结

    取地址操作符&和取值操作符*是一对互补操作符,&取出地址,*根据地址取出地址指向的值。
    变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

    1. 对变量进行取地址(&)操作,可以获得这个变量的指针变量。
    2. 指针变量的值是指针地址。
    3. 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。
  • 相关阅读:
    MySQL高级篇之索引分类
    MODIS数据产品预处理方法
    C++面试知识点总结
    session和cookie和token
    vue3标签页切换组件封装类似el-tabs
    【MYSQL】表操作
    fiddler导出录制脚本并导出jmter脚本文件
    ctfshow web入门 SQl注入 web185--web190
    SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
    TCP重传机制、滑动窗口、流量控制、拥塞控制
  • 原文地址:https://blog.csdn.net/qq_34158880/article/details/127820674