GO_复合类型---指针

一、变量的两层含义:内存空间 + 内存地址

Go 中每一个普通变量都包含两层概念:

  1. 变量内存空间:用来存储数值(类比:教室)
  2. 变量地址 :内存的编号,通过 &变量名 获取(类比:教室门牌号)

示例代码

go

Go 复制代码
package main

import "fmt"

func main() {
	var a int
	a = 10
	fmt.Printf("a 的值:%v\n", a)    // 内存中存储的值
	fmt.Printf("a 的地址:%v\n", &a) // 变量内存地址
}

二、指针类型核心概念

1. 指针的作用

普通变量存储数值 ,指针变量存储另一个变量的内存地址。

2. 指针类型规则

  • *int:int 类型的指针,存储 int 变量的地址
  • **int:二级指针,存储 *int 指针变量的地址

3. 指针基础语法(取地址、解引用)

  • &变量:取变量的内存地址(赋值给指针)
  • *指针变量:解引用,通过指针操作指向的内存原值

完整示例

go

Go 复制代码
package main

import "fmt"

func main() {
	var a int = 100

	// 1. 定义int类型指针
	var p *int
	// 2. 给指针赋值:存储a的地址
	p = &a

	fmt.Printf("a的值:%d\n", a)
	fmt.Printf("a的地址:%p\n", &a)
	fmt.Printf("指针p存储的地址:%p\n", p)

	// 3. 解引用:通过指针修改原变量的值
	*p = 555
	fmt.Printf("解引用修改后:*p=%d , a=%d\n", *p, a)
}

核心结论 :修改 *p 会直接修改原变量 a 的值,因为二者指向同一块内存空间。


三、Go 指针专属特性(高频考点)

1. 无 -> 操作符

C/C++ 指针访问成员用 ->,Go 语言没有 -> ,统一使用 . 访问成员,语法统一极简。

2. 禁止操作无合法指向的指针(核心坑点)

声明指针但不赋值,指针默认值为 nil ,无任何合法内存指向,禁止解引用,会直接报错 panic。

错误示例(绝对禁止)

go

Go 复制代码
var p *int
// p 为 nil,无合法内存,解引用直接崩溃
*p = 100 // panic: runtime error: invalid memory address or nil pointer dereference

正确规则

指针必须指向合法内存空间,才能进行解引用操作。


四、new 函数:快速创建合法指针内存

1. new 函数作用

为指定类型 T 分配一块清零的内存空间,返回该内存的指针地址,保证指针有合法指向。

2. 特性

  • 分配的内存默认零值初始化
  • Go 自动垃圾回收,无需手动释放内存
  • 专门用来解决:指针 nil 非法访问问题

使用示例

go

Go 复制代码
package main

import "fmt"

func main() {
	// 方式1:new创建合法int指针
	p := new(int)
	*p = 666
	fmt.Println("*p =", *p)

	// 方式2:简写
	q := new(int)
	*q = 888
	fmt.Println("*q =", *q)
}

五、值传递 vs 地址传递(指针核心应用)

Go 语言所有函数参数都是值传递,想要修改原变量,必须传指针(地址传递模拟)。

1. 值传递:无法修改原值

函数内部拷贝变量副本,修改的是副本,原变量不受影响。

go

Go 复制代码
func swap(a, b int) {
	// 仅修改副本,外部原值不变
	a, b = b, a
}

func main() {
	x, y := 10, 20
	swap(x, y)
	fmt.Println(x, y) // 输出:10 20 无变化
}

2. 地址传递(指针传参):修改原值

传递变量地址,函数内部通过指针解引用,直接操作原变量内存,实现原值修改。

go

Go 复制代码
package main

import "fmt"

// 接收int指针类型
func swap(p1, p2 *int) {
	// 解引用交换原值
	*p1, *p2 = *p2, *p1
}

func main() {
	a, b := 10, 20
	// 传变量地址
	swap(&a, &b)
	fmt.Println(a, b) // 输出:20 10 交换成功
}

六、本章指针核心总结(复习必背)

  1. 变量 = 内存值 + 内存地址,&取地址,*解引用
  2. Go 指针无 ->,统一使用 . 访问成员
  3. nil 指针禁止解引用,必须保证合法内存指向
  4. new(T) 分配清零内存,返回指针,解决空指针问题
  5. Go 只有值传递,想要改原值必须传指针(地址传递)
  6. 指针核心用途:修改变量原值、避免大内存拷贝
相关推荐
高频因子挖掘机4 小时前
从回测到实盘:量化策略为什么不应该直接依赖行情 API
后端·github·api
蹊黎6 小时前
C++中vector类的部分简单实现
开发语言·c++·visual studio
大鸡腿同学12 小时前
手心向上,手心向下
后端
程序猿追12 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓12 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播12 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
CCblandy13 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
墨云安全13 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php
摇滚侠13 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记
Cc.Y13 小时前
Java零基础入门:深入Java核心:文件IO与序列化全解
java·开发语言·python