golang语言指针操作


Posted in Golang onApril 14, 2022

指针

指针是代表某个内存地址的值。内存地址储存另一个变量的值。

指针(地址),一旦定义了不可改变,指针指向的值可以改变

go指针操作

1.默认值nil,没有NULL常量

2.操作符“&”取变量地址,“*“通过指针(地址)访问目标对象(指向值)

3.不支持指针运算,不支持“->”(箭头)运算符,直接用“.”访问目标成员

例子1:

package main //必须有个main包
import "fmt"
func main() {
	var a int = 10
	//每个变量有2层含义:变量的内存,变量的地址
	fmt.Printf("a = %d\n", a) //变量的内存
	fmt.Printf("&a = %d\n", &a)
	//保存某个变量的地址,需要指针类型   *int 保存int的地址, **int 保存 *int 地址
	//声明(定义), 定义只是特殊的声明
	//定义一个变量p, 类型为*int
	var p *int
	p = &a //指针变量指向谁,就把谁的地址赋值给指针变量
	fmt.Printf("p = %v, &a = %v\n", p, &a)
	*p = 666 //*p操作的不是p的内存,是p所指向的内存(就是a)
	fmt.Printf("*p = %v, a = %v\n", *p, a)

}

例子2:

package main
import "fmt"
func main() {
	a := 10
	b := &a
	*b = 11111  //操作指向a的值
	fmt.Println(a)  //11111
}

不能操作不合法指向

package main //必须有个main包
import "fmt"
func main() {
	var p *int
	p = nil
	fmt.Println("p = ", p)
	//*p = 666 //err, 因为p没有合法指向
	var a int
	p = &a //p指向a
	*p = 666
	fmt.Println("a = ", a)

}

new函数

表达式new(int)将创建一个int类型的匿名变量,为int类型的新值分配并清零一块内存空间,然后将这块内存空间的地址作为结果返回,而这个结果就是指向这个新的int类型值的指针值,返回的指针类型为*int

package main
import "fmt"
func main() {
	//var a *int
	a := new(int)  // a为*int类型,指向匿名的int变量
	fmt.Println(*a)  // 0
	b := new(int)  // b为*int类型,指向匿名的int变量
	*b = 2
	fmt.Println(*b) // 2
}

我们只需要使用new()函数,无需担心内存的生命周期,和回收删除。因为GO语言的(gc)内存管理系统会帮我们处理。

指针做函数的参数

例子1:交换值,普通变量做函数参数。内部交换成功,外部失败

package main //必须有个main包
import "fmt"
func swap(a, b int) {
	a, b = b, a
	fmt.Printf("swap: a = %d, b = %d\n", a, b)  //swap: a = 20, b = 10
}
func main() {
	a, b := 10, 20
	//通过一个函数交换a和b的内容
	swap(a, b) //变量本身传递,值传递(站在变量角度)
	fmt.Printf("main: a = %d, b = %d\n", a, b)  //main: a = 10, b = 20
}

例子2:指针传参,内部外部都交换成功

package main //必须有个main包
import (
	"fmt"
)
func test(a, b *int) {
	*a, *b = *b, *a
	fmt.Printf("swap: a = %d, b = %d\n", *a, *b)
}
func main() {
	a, b := 10, 20
	////通过一个函数交换a和b的内容
	test(&a, &b)
	fmt.Printf("main: a = %d, b = %d\n", a, b)
}

数组指针

//(*p)[0] = 666 数组指针赋值

package main //必须有个main包
import "fmt"
//p指向实现数组a,它是指向数组,它是数组指针
//*p代表指针所指向的内存,就是实参a
func modify(p *[5]int) {
	(*p)[0] = 666
	fmt.Println("modify *a = ", *p)  //modify *a =  [666 2 3 4 5]
}
func main() {
	a := [5]int{1, 2, 3, 4, 5} //初始化
	modify(&a) //地址传递
	fmt.Println("main: a = ", a)  // modify *a =  [666 2 3 4 5]
}

结构体指针变量

package main //必须有个main包
import "fmt"
//定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte //字符类型
	age  int
	addr string
}
func main() {
	//顺序初始化,每个成员必须初始化, 别忘了&
	var p1 *Student = &Student{1, "mike", 'm', 18, "bj"}
	fmt.Println("p1 = ", p1)  //p1 =  &{1 mike 109 18 bj}
	//指定成员初始化,没有初始化的成员,自动赋值为0
	p2 := &Student{name: "mike", addr: "bj"}
	fmt.Printf("p2 type is %T\n", p2) //p2 type is *main.Student
	fmt.Println("p2 = ", p2)  //p2 =  &{0 mike 0 0 bj}
}

结构体成员普通变量

//定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte //字符类型
	age  int
	addr string
}
func main() {
	//定义一个结构体普通变量
	var s Student
	//操作成员,需要使用点(.)运算符
	s.id = 1
	s.name = "mike"
	s.sex = 'm' //字符
	s.age = 18
	s.addr = "bj"
	fmt.Println("s = ", s) //s =  {1 mike 109 18 bj}
}

结构体成员指针变量

func main() {
	//1、指针有合法指向后,才操作成员
	//先定义一个普通结构体变量
	var s Student
	//在定义一个指针变量,保存s的地址
	var p1 *Student
	p1 = &s
	//通过指针操作成员  p1.id 和(*p1).id完全等价,只能使用.运算符
	p1.id = 1
	(*p1).name = "mike"
	p1.sex = 'm'
	p1.age = 18
	p1.addr = "bj"
	fmt.Println("p1 = ", p1)
	//2、通过new申请一个结构体
	p2 := new(Student)
	p2.id = 1
	p2.name = "mike"
	p2.sex = 'm'
	p2.age = 18
	p2.addr = "bj"
	fmt.Println("p2 = ", p2)
}

结构体比较和赋值

func main() {
	s1 := Student{1, "mike", 'm', 18, "bj"}
	s2 := Student{1, "mike", 'm', 18, "bj"}
	s3 := Student{2, "mike", 'm', 18, "bj"}
	fmt.Println("s1 == s2 ", s1 == s2)
	fmt.Println("s1 == s3 ", s1 == s3)
	//同类型的2个结构体变量可以相互赋值
	var tmp Student
	tmp = s3
	fmt.Println("tmp = ", tmp)
}

结构体作为函数参数

func test02(p *Student) {
	p.id = 666
}
func main() {
	s := Student{1, "mike", 'm', 18, "bj"}
	test02(&s) //地址传递(引用传递),形参可以改实参
	fmt.Println("main: ", s)
}
func test01(s Student) {
	s.id = 666
	fmt.Println("test01: ", s)
}
func main01() {
	s := Student{1, "mike", 'm', 18, "bj"}
	test01(s) //值传递,形参无法改实参
	fmt.Println("main: ", s)
}

以上就是go语言结构体指针操作示例详解的详细内容!

Golang 相关文章推荐
Golang 如何实现函数的任意类型传参
Apr 29 Golang
解决golang 关于全局变量的坑
May 06 Golang
关于golang高并发的实现与注意事项说明
May 08 Golang
GoLang中生成UUID唯一标识的实现
May 08 Golang
Go语言基础知识点介绍
Jul 04 Golang
golang中字符串MD5生成方式总结
Jul 04 Golang
Golang并发操作中常见的读写锁详析
Aug 30 Golang
如何解决goland,idea全局搜索快捷键失效问题
Apr 03 Golang
GO语言异常处理分析 err接口及defer延迟
Apr 14 Golang
Golang 字符串的常见操作
Apr 19 Golang
Golang 并发编程 SingleFlight模式
Apr 26 Golang
go goth封装第三方认证库示例详解
Aug 14 Golang
golang使用map实现去除重复数组
Apr 14 #Golang
golang生成并解析JSON
Apr 14 #Golang
Go语言 详解net的tcp服务
Apr 14 #Golang
golang连接MySQl使用sqlx库
Apr 14 #Golang
Go语言安装并操作redis的go-redis库
Apr 14 #Golang
golang操作redis的客户端包有多个比如redigo、go-redis
Apr 14 #Golang
Go语言grpc和protobuf
You might like
Zend Framework实现多文件上传功能实例
2016/03/21 PHP
CodeIgniter集成smarty的方法详解
2016/05/26 PHP
一份老外写的XMLHttpRequest代码多浏览器支持兼容性
2007/01/11 Javascript
dwr spring的集成实现代码
2009/03/22 Javascript
Easy.Ajax 部分源代码 支持文件上传功能, 兼容所有主流浏览器
2011/02/24 Javascript
javascript中arguments,callee,caller详解
2016/03/16 Javascript
一个简单的JavaScript Map实例(分享)
2016/08/03 Javascript
jQuery查找节点方法完整实例
2016/09/13 Javascript
原生JS实现在线问卷调查投票特效
2017/01/03 Javascript
简单实现jQuery级联菜单
2017/01/09 Javascript
JavaScript实现的选择排序算法实例分析
2017/04/14 Javascript
详解webpack进阶之loader篇
2017/08/23 Javascript
JavaScript实现图片拖曳效果
2017/09/08 Javascript
JS实现贪吃蛇游戏
2019/11/15 Javascript
prettier自动格式化去换行的实现代码
2020/08/25 Javascript
js将日期格式转换为YYYY-MM-DD HH:MM:SS
2020/09/18 Javascript
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
2014/06/18 Python
python实现连接mongodb的方法
2015/05/08 Python
Python字符串切片操作知识详解
2016/03/28 Python
对python xlrd读取datetime类型数据的方法详解
2018/12/26 Python
python处理自动化任务之同时批量修改word里面的内容的方法
2019/08/23 Python
python飞机大战pygame游戏之敌机出场实现方法详解
2019/12/17 Python
Python3搭建http服务器的实现代码
2020/02/11 Python
pycharm 激活码及使用方式的详细教程
2020/05/12 Python
5款实用的python 工具推荐
2020/10/13 Python
详解python os.path.exists判断文件或文件夹是否存在
2020/11/16 Python
CSS3使用border-radius属性制作圆角
2014/12/22 HTML / CSS
HTML5注册页面示例代码
2014/03/27 HTML / CSS
使用html5 canvas创建太空游戏的示例
2014/05/08 HTML / CSS
德国最大的网上鞋店之一:Schuhe24.de
2017/06/10 全球购物
100%植物性、有机、即食餐:Sakara Life
2018/10/25 全球购物
民主评议党员总结
2014/10/20 职场文书
2015年施工员工作总结范文
2015/04/20 职场文书
信息技术教研组工作总结
2015/08/13 职场文书
使用 CSS 轻松实现一些高频出现的奇形怪状按钮
2021/12/06 HTML / CSS
Vite + React从零开始搭建一个开源组件库
2022/06/25 Javascript