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 28 Golang
go结构体嵌套的切片数组操作
Apr 28 Golang
Go语言中break label与goto label的区别
Apr 28 Golang
golang 在windows中设置环境变量的操作
Apr 29 Golang
go类型转换及与C的类型转换方式
May 05 Golang
goland 设置project gopath的操作
May 06 Golang
Go timer如何调度
Jun 09 Golang
go语言使用Casbin实现角色的权限控制
Jun 26 Golang
Go语言读取txt文档的操作方法
Jan 22 Golang
Golang 结构体数据集合
Apr 22 Golang
Go调用Rust方法及外部函数接口前置
Jun 14 Golang
Go gorilla securecookie库的安装使用详解
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
解析PHP处理换行符的问题 \r\n
2013/06/13 PHP
mac环境中使用brew安装php5.5.15
2014/08/18 PHP
Zend Framework创建自己的动作助手详解
2016/03/05 PHP
详解Yii2.0使用AR联表查询实例
2017/06/16 PHP
php5.6.x到php7.0.x特性小结
2019/08/17 PHP
HTA版JSMin(省略修饰语若干)基于javascript语言编写
2009/12/24 Javascript
JQuery验证工具类搜集整理
2013/01/16 Javascript
setTimeout函数兼容各主流浏览器运行执行效果实例
2013/06/13 Javascript
JavaScript数组复制详解
2017/02/02 Javascript
vue调用高德地图实例代码
2017/04/28 Javascript
几种响应式文字详解
2017/05/19 Javascript
Require.JS中的几种define定义方式示例
2017/06/01 Javascript
JS作用域链详解
2017/06/26 Javascript
js实现简易聊天对话框
2017/08/17 Javascript
修改UA在PC中访问只能在微信中打开的链接方法
2017/11/27 Javascript
vuex中的 mapState,mapGetters,mapActions,mapMutations 的使用
2018/04/13 Javascript
Vue实现侧边菜单栏手风琴效果实例代码
2018/05/31 Javascript
谈谈React中的Render Props模式
2018/12/06 Javascript
nodejs中使用archive压缩文件的实现代码
2019/11/26 NodeJs
element-ui 远程搜索组件el-select在项目中组件化的实现代码
2019/12/04 Javascript
[03:11]完美世界DOTA2联赛PWL DAY8集锦
2020/11/09 DOTA
Python 除法小技巧
2008/09/06 Python
Python中的XML库4Suite Server的介绍
2015/04/14 Python
Python守护进程用法实例分析
2015/06/04 Python
Python操作Access数据库基本步骤分析
2016/09/19 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
Python排序搜索基本算法之归并排序实例分析
2017/12/08 Python
python爬虫的数据库连接问题【推荐】
2018/06/25 Python
在脚本中单独使用django的ORM模型详解
2020/04/01 Python
美国网上订购鲜花:FTD
2016/09/23 全球购物
大学毕业生自我鉴定
2013/11/05 职场文书
精彩广告词大全
2014/03/19 职场文书
弘扬民族精神演讲稿
2014/05/07 职场文书
人民调解协议书范本
2014/10/11 职场文书
面试中老生常谈的MySQL问答集锦夯实基础
2022/03/13 MySQL
Python捕获、播放和保存摄像头视频并提高视频清晰度和对比度
2022/04/14 Python