Go 语言-->指针

Go 语言-->指针

它允许你操作内存中的实际数据 ,而不仅仅是数据的副本。指针存储的是另一个变量的内存地址,而不是变量的实际值。

1. 什么是指针

指针是存储变量内存地址的变量,它指向另一个变量。通过指针,你可以间接地访问和修改那个变量的值。

  • 指针变量:指针存储一个内存地址,这个内存地址指向一个具体的值。
  • 解引用:通过指针访问指向的变量的值。

2. 声明指针

在 Go 中,指针通过在类型前加上 * 来声明。例如,*int 表示一个指向 int 类型的指针。

示例:声明指针

go 复制代码
var ptr *int  // ptr 是一个指向 int 类型的指针

3. 获取指针(取地址)

使用 & 操作符可以获得一个变量的内存地址,这叫做取地址。

示例:获取指针

go 复制代码
package main

import "fmt"

func main() {
    var a int = 58
    var ptr *int = &a  // ptr 保存 a 的地址
    
    fmt.Println("a 的值:", a)       // 输出:a 的值: 58
    fmt.Println("ptr 的值:", ptr)   // 输出:ptr 的值: &a
    fmt.Println("ptr 指向的值:", *ptr)  // 输出:ptr 指向的值: 58
}
  • &a:返回变量 a 的内存地址。
  • *ptr:返回指针 ptr 所指向的变量的值。

4. 通过指针修改变量值

通过指针可以间接修改变量的值。通过解引用(*ptr)可以修改指针所指向的变量的值。

示例:通过指针修改值

go 复制代码
package main

import "fmt"

func main() {
    var a int = 58
    var ptr *int = &a  // ptr 指向 a 的地址

    fmt.Println("修改前 a 的值:", a)  // 输出:修改前 a 的值: 58

    *ptr = 100  // 通过指针修改 a 的值
    fmt.Println("修改后 a 的值:", a)  // 输出:修改后 a 的值: 100
}

5. 指针与函数传参

Go 中的函数传参是按传递的,这意味着函数内部的参数是传入值的副本。如果你想要在函数内修改参数的值,必须通过指针传递

示例:通过指针修改函数参数的值

go 复制代码
package main

import "fmt"

func modifyValue(ptr *int) {
    *ptr = 500  // 修改 ptr 指向的变量的值
}

func main() {
    a := 100
    fmt.Println("修改前 a 的值:", a)  // 输出:修改前 a 的值: 100
    
    modifyValue(&a)  // 将 a 的地址传递给函数
    fmt.Println("修改后 a 的值:", a)  // 输出:修改后 a 的值: 500
}

6. 零值指针

Go 中的指针默认值是 nil,即如果一个指针没有指向任何地址,它的默认值是 nil。你可以检查指针是否为 nil 来判断它是否已经被初始化。

示例:零值指针

go 复制代码
package main

import "fmt"

func main() {
    var ptr *int  // 默认为 nil
    fmt.Println("ptr 的值:", ptr)  // 输出:ptr 的值: <nil>

    if ptr == nil {
        fmt.Println("指针是 nil")
    }
}

7. 指针和数组、切片

Go 中的数组和切片也可以通过指针来传递,指针可以用来操作数组或切片的数据。

示例:指针与数组

go 复制代码
package main

import "fmt"

func modifyArray(arr *[3]int) {
    arr[0] = 100  // 通过指针修改数组
}

func main() {
    arr := [3]int{1, 2, 3}
    fmt.Println("修改前数组:", arr)  // 输出:修改前数组: [1 2 3]
    
    modifyArray(&arr)  // 将数组的地址传递给函数
    fmt.Println("修改后数组:", arr)  // 输出:修改后数组: [100 2 3]
}

8. 指针与结构体

指针也可以指向结构体,结构体指针可以通过 -> 语法来访问结构体的字段,或者通过 * 解引用来访问结构体字段。

示例:指针与结构体

go 复制代码
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func modifyPerson(p *Person) {
    p.Name = "Alice"
    p.Age = 30
}

func main() {
    person := Person{Name: "Bob", Age: 25}
    fmt.Println("修改前:", person)  // 输出:修改前: {Bob 25}
    
    modifyPerson(&person)  // 将结构体的地址传递给函数
    fmt.Println("修改后:", person)  // 输出:修改后: {Alice 30}
}

9. 指针的高级应用:指针的指针

Go 支持指针的指针,即你可以有一个指向指针的指针。这通常用于函数传递多个级别的地址或动态创建多级引用。

示例:指针的指针

go 复制代码
package main

import "fmt"

func main() {
    var a int = 58
    var ptr *int = &a
    var ptr2 **int = &ptr  // ptr2 是指向 ptr 的指针

    fmt.Println("a 的值:", a)       // 输出:a 的值: 58
    fmt.Println("ptr 的值:", *ptr)  // 输出:ptr 的值: 58
    fmt.Println("ptr2 指向的值:", **ptr2) // 输出:ptr2 指向的值: 58
}

10. 总结

  • 指针允许你通过内存地址间接访问和修改变量的值。
  • 取地址操作符 (&) 用于获取变量的内存地址。
  • 解引用操作符 (*) 用于访问指针指向的变量的值。
  • Go 中的 指针默认值为 nil ,检查指针是否为 nil 是一个好的编程习惯。
  • Go 中的 指针可以与数组、切片、结构体 等一起使用,可以高效地传递大数据结构而无需复制数据。

指针在 Go 中的使用使得函数能直接修改外部变量,而不需要返回修改后的副本,这在处理大数据结构或需要高效内存管理时非常有用。

相关推荐
2601_966949653 分钟前
如何利用 1 分钟 K 线在 14:50 精准捕捉尾盘异动?Python 量化实战:1 分钟 K 线 + 全市场扫描
开发语言·人工智能·python·量化·quantdash·量化数据源
CarIise5 分钟前
JavaScript基础语法与DOM操作实战课堂笔记
开发语言·javascript·笔记
林森lsjs12 分钟前
零基础吃透二叉树:定义、遍历与高频算法 —数据结构柒
java·开发语言·数据结构·算法·二叉树
MacroZheng14 分钟前
又一个神级画图Skill开源,再见draw.io!
java·人工智能·后端
wind1003235 分钟前
Qt5Widgets.dll 缺失报错|游戏软件无法启动完整修复教程
开发语言·qt·游戏·电脑
我叫张土豆1 小时前
在 OpenClaw Java 对话框输入一句话后,系统是如何运行的?
java·开发语言·人工智能
唐青枫1 小时前
把代码搬到编译期:Zig comptime、泛型与类型反射实战
后端
风曳丷1 小时前
06|Direct 与 Indirect Prompt Injection
后端
风曳丷1 小时前
05|Prompt Injection 不是一句神奇咒语
后端
牛油果子哥q1 小时前
C++模板万字深度精讲:函数/类模板特化、全特化与偏特化、SFINAE机制、类型萃取、模板元编程入门、工程实战落地
开发语言·c++·面试