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判断key是否在map中的代码
Apr 24 Golang
goland 清除所有的默认设置操作
Apr 28 Golang
golang slice元素去重操作
Apr 30 Golang
Golang 编译成DLL文件的操作
May 06 Golang
Go语言实现Snowflake雪花算法
Jun 08 Golang
Go遍历struct,map,slice的实现
Jun 13 Golang
go语言使用Casbin实现角色的权限控制
Jun 26 Golang
Go语言空白表示符_的实例用法
Jul 04 Golang
一文搞懂Golang 时间和日期相关函数
Dec 06 Golang
victoriaMetrics库布隆过滤器初始化及使用详解
Apr 05 Golang
Go语言 详解net的tcp服务
Apr 14 Golang
golang语言指针操作
Apr 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
给多个地址发邮件的类
2006/10/09 PHP
PHP中的使用curl发送请求(GET请求和POST请求)
2017/02/08 PHP
HTML5如何适配 iPhone IOS 底部黑条
2021/03/09 HTML / CSS
最近项目写了一些js,水平有待提高
2009/01/31 Javascript
boxy基于jquery的弹出层对话框插件扩展应用 弹出层选择器
2010/11/21 Javascript
带左右箭头图片轮播的JS代码
2013/12/18 Javascript
JavaScript获取table中某一列的值的方法
2014/05/06 Javascript
js动态修改整个页面样式达到换肤效果
2014/05/23 Javascript
利用Node.js制作爬取大众点评的爬虫
2016/09/22 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
原生js实现网易轮播图效果
2020/04/10 Javascript
jQuery基于Ajax方式提交表单功能示例
2017/02/10 Javascript
使用Node.js实现RESTful API的示例
2017/08/01 Javascript
JS执行控制之节流模式实例分析
2018/12/21 Javascript
如何优雅的在一台vps(云主机)上面部署vue+mongodb+express项目
2019/01/20 Javascript
关于layui表单中按钮自动提交的解决方法
2019/09/09 Javascript
12 种使用Vue 的最佳做法
2020/03/30 Javascript
python列表操作使用示例分享
2014/02/21 Python
python中正则表达式的使用方法
2018/02/25 Python
pyqt5的QComboBox 使用模板的具体方法
2018/09/06 Python
python读取大文件越来越慢的原因与解决
2019/08/08 Python
基于Tensorflow高阶读写教程
2020/02/10 Python
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
希腊香水和化妆品购物网站:Parfimo.gr
2019/10/03 全球购物
儿子婚宴答谢词
2014/01/09 职场文书
庆七一活动方案
2014/01/25 职场文书
不拖欠农民工工资承诺书
2014/03/31 职场文书
买房委托公证书
2014/04/08 职场文书
大学社团计划书
2014/05/01 职场文书
四风对照检查材料范文
2014/09/27 职场文书
护理医院见习报告
2014/11/03 职场文书
2014年护士个人工作总结
2014/11/11 职场文书
国庆节新闻稿
2015/07/17 职场文书
小米11和iphone12哪个值得买?小米11对比iphone12评测
2021/04/21 数码科技
MySQL 重写查询语句的三种策略
2021/05/10 MySQL
SQL实现LeetCode(176.第二高薪水)
2021/08/04 MySQL