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 相关文章推荐
go语言中切片与内存复制 memcpy 的实现操作
Apr 27 Golang
golang中切片copy复制和等号复制的区别介绍
Apr 27 Golang
Go语言切片前或中间插入项与内置copy()函数详解
Apr 27 Golang
使用Golang的channel交叉打印两个数组的操作
Apr 29 Golang
基于Golang 高并发问题的解决方案
May 08 Golang
Golang全局变量加锁的问题解决
May 08 Golang
详解Go语言Slice作为函数参数的使用
Jul 02 Golang
Go语言基础知识点介绍
Jul 04 Golang
go开发alertmanger实现钉钉报警
Jul 16 Golang
golang实现浏览器导出excel文件功能
Mar 25 Golang
Golang 入门 之url 包
May 04 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的安全策略
2006/10/09 PHP
隐性调用php程序的方法
2009/03/09 PHP
PHP多个文件上传到服务器实例
2014/10/29 PHP
Yii输入正确验证码却验证失败的解决方法
2017/06/06 PHP
JS 巧妙获取剪贴板数据 Excel数据的粘贴
2009/07/09 Javascript
JS 用6N±1法求素数 实例教程
2009/10/20 Javascript
JQuery 构建客户/服务分离的链接模型中Table中的排序分析
2010/01/22 Javascript
JS图片浏览组件PhotoLook的公开属性方法介绍和进阶实例代码
2010/11/09 Javascript
按下回车键指向下一个位置的一个函数代码
2014/03/10 Javascript
Ubuntu中搭建Nodejs开发环境过程分享
2014/06/01 NodeJs
javascript面向对象特性代码实例
2014/06/12 Javascript
JavaScript从0开始构思表情插件
2016/07/26 Javascript
web前端vue filter 过滤器
2018/01/12 Javascript
JS中touchstart事件与click事件冲突的解决方法
2018/03/12 Javascript
vue中axios的封装问题(简易版拦截,get,post)
2018/06/15 Javascript
深入Node TCP模块的理解
2019/03/13 Javascript
javascript实现的时间格式加8小时功能示例
2019/06/13 Javascript
layui清除radio的选中状态实例
2019/11/14 Javascript
python pickle 和 shelve模块的用法
2013/09/16 Python
Python实现数据库编程方法详解
2015/06/09 Python
python 计算文件的md5值实例
2017/01/13 Python
Python实现自动登录百度空间的方法
2017/06/10 Python
python爬虫_实现校园网自动重连脚本的教程
2018/04/22 Python
使用python语言,比较两个字符串是否相同的实例
2018/06/29 Python
python3实现的zip格式压缩文件夹操作示例
2019/08/17 Python
基于pytorch的lstm参数使用详解
2020/01/14 Python
如何使用Python抓取网页tag操作
2020/02/14 Python
你不知道的葡萄干处理法、橙蜜处理法、二氧化碳酵母法
2021/03/17 冲泡冲煮
美国最大的宠物药店:1-800-PetMeds
2016/10/02 全球购物
日本食品网上商店:JaponShop.com
2017/11/28 全球购物
致800米运动员广播稿
2014/02/16 职场文书
副总经理岗位职责范本
2014/09/30 职场文书
地道战观后感500字
2015/06/04 职场文书
Nginx URL重写rewrite机制原理及使用实例
2021/04/01 Servers
解决MySQL Varchar 类型尾部空格的问题
2022/04/06 MySQL
Redis超详细讲解高可用主从复制基础与哨兵模式方案
2022/04/07 Redis