`golang` 指针讨论

简介: `golang` 指针讨论

golang 指针讨论


好几天没有更新了,因为小熊给老板打了包票,要把 10 天的工作,压缩在 5 天,怎么压缩,靠加班咯。今天回家以后连不上那几台服务器,加班不成,写写文章。



aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzIwMjAtMDUtMTMtMTQxNjA4LmpwZw.png



这两天特别惨,我的眼镜还丢了,上班只能靠很近才能看清。本来申请的显示器,被配送员送到其他同事那里了,结果那同事明知道箱子上的名字不是自己的还拆开用,要等明天才有的用了。我怎么这么倒霉??


go 语言的教程拖拖拉拉写了好久了,本身比较简单,按部就班的写影响到了我的学习进度,所以我要加速度了,从这一篇开始。话不多说现在开始。


指针


c 中有指针的概念,在 go 中也有,但是实际上用的比较少,因为指针容易出错,而且不易阅读。


每个变量都有他的地址


var a int
fmt.Printf("a 的地址是:%p \n", &a)


输出


a 的地址是:0xc0000b2008


指针用来存地址

//声明 变量名 + 指针类型 , 命令规则以ptr结尾
var ptr *int /* 指向整型*/
// var fp *float32 /* 指向浮点型 */
ptr = &a // 变量内部存的值是普通类型,指针内部存的值是地址
fmt.Printf("ptr 存的值是:%p \n", ptr)

输出,可以看到 ptr 存的值就是 a 的地址。


ptr 存的值是:0xc0000b2008


存的就是 a 的地址,ptr 的指向*ptr 肯定就是 a 本身了。


if a == *ptr {
    fmt.Println("a == *ptr")
}


输出


a == *ptr


指针的作用


指针可以消灭掉返回值,直接对参数做改变。

定义一个交换函数,形参为指针类型

func swap(x *int, y *int) {
  var temp int
  temp = *x /* 保存 x 地址的值 */
  *x = *y   /* 将 y 赋值给 x */
  *y = temp /* 将 temp 赋值给 y */
}


调用


a := 100
b := 200
//操作地址,不需要返回
swap(&a, &b)
fmt.Printf("交换后 a 的值 : %d\n", a)
fmt.Printf("交换后 b 的值 : %d\n", b)


输出


交换后 a 的值 : 200
交换后 b 的值 : 100


虽然可以这么做,但是不推荐,因为 go 比 c++ 多出来多返回值的特性,所以这里写在返回里可读性更强。


PS1: 但如果你的参数是比较复杂的类型,比如数组。用指针可以节省空间。


PS2: 对引用类型的操作会改变原引用类型的值,这里与指针有异曲同工之妙


多维指针


刚刚用到的指针,只不过指向一个变量的地址,他就被叫做一维指针。


var ptr *int
ptr = &a


指针本身也是一个变量,是变量就有地址,所以指针也可以被取地址。


var ptr *int
pptr = &ptr


*int 类型的指针存的是 int 类型数据的地址,得到 *变量类型 就是他的指针,推导出指向 *int 变量的指针为 **int 类型,这种类型被称为二维指针,每多一个 * 就多一个维。


var a int
var ptr *int  //一维
var pptr **int // 二维
var ppptr ***int // 三维
ptr = &a
pptr = &ptr
ppptr = &pptr
fmt.Printf("a的地址:%p \n", &a)
fmt.Printf("ptr存的地址:%p \n", ptr)
fmt.Printf("pptr存的地址的指向:%p \n", *pptr)
fmt.Printf("ppptr存的地址的指向的指向:%p \n", **ppptr)


输出

a的地址:0xc000014090
ptr存的地址:0xc000014090
pptr存的地址的指向:0xc000014090
ppptr存的地址的指向的指向:0xc000014090



PS1: 日常工作中,不建议使用多维指针,可读性不好,容易犯错误,一层指针能搞定的,一定不要使用多维炫技术。不然过几个月你自己都看不懂。


PS2: 不得不使用二维指针的场景:你希望在一个函数的参数中改变一个指针的值,你就只能传这个指针的指针给这个函数。


PS3:多维指针的唯一好处:减少传参

相关文章
|
存储 安全 编译器
Golang 语言中的指针介绍
Golang 语言中的指针介绍
56 0
|
2月前
|
Go
Golang语言高级数据类型之指针篇
这篇文章详细讲解了Golang语言中的指针概念、指针地址和类型、定义指针变量、指针的细节操作、指针传值,以及内置函数new和make的用法和它们之间的区别。
21 0
|
3月前
|
存储 大数据 测试技术
掌握 GoLang 中的指针:高效代码的提示和技巧
掌握 GoLang 中的指针:高效代码的提示和技巧
|
6月前
|
Java Go
Golang深入浅出之-Go语言指针面试必知:理解与使用指针
【4月更文挑战第21天】Go语言中的指针允许直接操作内存,常用于高效数据共享和传递。本文介绍了指针的基础知识,如声明、初始化和解引用,以及作为函数参数使用。此外,讨论了`new()`与`make()`的区别和内存逃逸分析。在结构体上下文中,指针用于减少复制开销和直接修改对象。理解指针与内存管理、结构体的关系及常见易错点,对于面试和编写高性能Go代码至关重要。
87 2
|
Go
Golang 语言怎么打印结构体指针类型字段的值?
Golang 语言怎么打印结构体指针类型字段的值?
252 0
|
存储 安全 Go
Golang 语言 method 接收者使用值类型和指针类型的区别
Golang 语言 method 接收者使用值类型和指针类型的区别
51 0
|
6月前
|
C++ Go 自然语言处理
Golang每日一练(leetDay0047) 复制带随机指针链表、单词拆分I\II
Golang每日一练(leetDay0047) 复制带随机指针链表、单词拆分I\II
44 0
Golang每日一练(leetDay0047) 复制带随机指针链表、单词拆分I\II
|
6月前
|
Go
golang力扣leetcode 38.复制带随机指针的链表
golang力扣leetcode 38.复制带随机指针的链表
34 0
|
Go
Golang 语言怎么避免空指针引发的 panic
Golang 语言怎么避免空指针引发的 panic
139 0
|
存储 安全 Go
Golang 语言中的非类型安全指针
Golang 语言中的非类型安全指针
42 0