文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

go语言有指针运算吗

2023-07-04 22:42

关注

本篇内容介绍了“go语言有指针运算吗”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

go语言没有指针运算。go语言的语法上是不支持指针运算的,所有指针都在可控的一个范围内使用;但实际上,go语言可以通过unsafe包的Pointer()方法把指针转换为uintptr类型的数字,来间接实现指针运算。

内存就是一系列有序列号的存储单元,变量就是编译器为内存地址分配的昵称,那么指针是什么呢?

指针就是一个指向另一个内存地址变量的值

指针指向变量的内存地址,指针就像该变量值的内存地址一样

我们来看一个代码片段

func main() {    a := 200    b := &a    *b++    fmt.Println(a)}

在 main 函数的第一行,我们定义了一个新的变量 a ,并赋值为 200。接下来我们定义了一个变量 b ,并将变量 a 的地址赋值给 b 。我们并不知道 a 的准确存储地址,但是我们依然可以将 a 的地址存储在变量 b 中。

go语言有指针运算吗

go语言有指针运算吗

因为 Go 强类型的特性,第三行代码也许是最具干扰性的了,b 包含 a 变量的地址,但是我们想增加存储在 a 变量中的值。

这样我们必须取消引用 b ,而是跟随指针由 b 引用 a。
然后我们将该值加 1 后,存储回 b 中存储的内存地址上。

最后一行打印了 a 的值,可以看到 a 的值已经增加为了 201

go语言有指针运算吗

go语言有指针运算吗

Go语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量

区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针

要搞明白Go语言中的指针需要先知道3个概念:指针地址、指针类型和指针取值

指针地址和指针类型

Go语言中的指针操作非常简单,只需要记住两个符号:&(取地址)和*(根据地址取值)。

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用&字符放在变量前面对变量进行“取地址”操作。

取变量指针的语法如下:

ptr := &v    // v的类型为T

其中:

go语言有指针运算吗

func main() {    a := 10    b := &a    fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078    fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int    fmt.Println(&b)                    // 0xc00000e018}

指针运算符

1.指针运算符为左值时,我们可以更新目标对象的状态;而为右值时则是为了获取目标的状态。

func main() {    x := 10    var p *int = &x  //获取地址,保存到指针变量    *p += 20        //用指针间接引用,并更新对象    println(p, *p)  //输出指针所存储的地址,以及目标对象}

输出:

0xc000040780 30

2.指针类型支持相等运算符,但不能做加减运算和类型转换。如果两个指针指向同一地址,或都为nil,那么它们相等。

func main() {    x := 10    p := &x    p++   //编译报错 invalid operation: p++ (non-numeric type *int)    var p2 *int = p+1  //invalid operation: p + 1 (mismatched types *int and int)    p2 = &x    println(p == p2)   //指向同一地址}

可通过unsafe.Pointer将指针转换为uintptr后进行加减法运算,但可能会造成非法访问。

指针运算

在很多 golang 程序中,虽然用到了指针,但是并不会对指针进行加减运算,这和 C 程序是很不一样的。Golang 的官方入门学习工具(go tour) 甚至说 Go 不支持指针算术。虽然实际上并不是这样的,但我在一般的 go 程序中,好像确实没见过指针运算(嗯,我知道你想写不一般的程序)。

  • 但实际上,go 可以通过 unsafe.Pointer 来把指针转换为 uintptr 类型的数字,来间接实现指针运算。

  • 这里请注意,uintptr 是一种整数类型,而不是指针类型。

比如:

uintptr(unsafe.Pointer(&p)) + 1

就得到了 &p 的下一个字节的位置。然而,根据 《Go Programming Language》 的提示,我们最好直接把这个计算得到的内存地址转换为指针类型:

unsafe.Pointer(uintptr(unsafe.Pointer(&p) + 1))

因为 go 中是有垃圾回收机制的,如果某种 GC 挪动了目标值的内存地址,以整型来存储的指针数值,就成了无效的值。

同时也要注意,go 中对指针的 + 1,真的就只是指向了下一个字节,而 C 中 + 1 或者 ++ 考虑了数据类型的长度,会自动指向当前值结尾后的下一个字节(或者说,有可能就是下一个值的开始)。如果 go 中要想实现同样的效果,可以使用 unsafe.Sizeof 方法:

unsafe.Pointer(uintptr(unsafe.Pointer(&p) + unsafe.Sizeof(p)))

最后,另外一种常用的指针操作是转换指针类型。这也可以利用 unsafe 包来实现:

var a int64 = 1(*int8)(unsafe.Pointer(&a))

如果你没有遇到过需要转换指针类型的需求,可以看看这个项目(端口扫描工具),其中构建 IP 协议首部的代码,就用到了指针类型转换。

“go语言有指针运算吗”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯