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各时间字符串使用解析
Apr 02 Golang
go语言求任意类型切片的长度操作
Apr 26 Golang
golang 实现Location跳转方式
May 02 Golang
goland 设置project gopath的操作
May 06 Golang
Golang中异常处理机制详解
Jun 08 Golang
Go语言实现Base64、Base58编码与解码
Jul 26 Golang
Go语言基础函数基本用法及示例详解
Nov 17 Golang
Golang使用Panic与Recover进行错误捕获
Mar 22 Golang
Golang Elasticsearches 批量修改查询及发送MQ
Apr 19 Golang
Golang 遍历二叉树
Apr 19 Golang
Go微服务项目配置文件的定义和读取示例详解
Jun 21 Golang
Go语言编译原理之源码调试
Aug 05 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 php_openssl.dll的作用
2013/07/01 PHP
php实现向javascript传递数组的方法
2015/07/27 PHP
php使用变量动态创建类的对象用法示例
2017/02/06 PHP
PHP基于方差和标准差计算学生成绩的稳定性示例
2017/07/04 PHP
Google Map API更新实现用户自定义标注坐标
2009/07/29 Javascript
IE下JS读取xml文件示例代码
2013/08/05 Javascript
js截取小数点后几位的写法
2013/11/14 Javascript
javascript在当前窗口关闭前检测窗口是否关闭
2014/09/29 Javascript
Python脚本后台运行的几种方式
2015/03/09 Javascript
JavaScript实现图片DIV竖向滑动的方法
2015/04/25 Javascript
jQuery动画显示和隐藏效果实例演示(附demo源码下载)
2015/12/31 Javascript
jquery在ie7下选择器的问题导致append失效的解决方法
2016/01/10 Javascript
JS实现的自定义显示加载等待图片插件(loading.gif)
2016/06/17 Javascript
jQuery获取radio选中项的值实例
2016/06/18 Javascript
微信小程序 教程之wxapp 视图容器 view
2016/10/19 Javascript
详解react-webpack2-热模块替换[HMR]
2017/08/03 Javascript
从vue源码看props的用法
2019/01/09 Javascript
javascript实现的时间格式加8小时功能示例
2019/06/13 Javascript
详解vue-router的导航钩子(导航守卫)
2020/11/02 Javascript
vue中如何自定义右键菜单详解
2020/12/08 Vue.js
[01:10:24]DOTA2-DPC中国联赛 正赛 VG vs Aster BO3 第一场 2月28日
2021/03/11 DOTA
Python网络编程使用select实现socket全双工异步通信功能示例
2018/04/09 Python
python selenium登录豆瓣网过程解析
2019/08/10 Python
python3实现单目标粒子群算法
2019/11/14 Python
jupyter notebook运行命令显示[*](解决办法)
2020/05/18 Python
Python建造者模式案例运行原理解析
2020/06/29 Python
python中查看.db文件中表格的名字及表格中的字段操作
2020/07/07 Python
欧洲领先的火车票和大巴票预订平台:Trainline
2018/12/26 全球购物
精选干货:Java精选笔试题附答案
2014/01/18 面试题
制定岗位职责的原则
2013/11/08 职场文书
工厂门卫岗位职责
2015/04/13 职场文书
雷锋的故事观后感
2015/06/10 职场文书
2019毕业典礼主持词!
2019/07/05 职场文书
MySQL中优化SQL语句的方法(show status、explain分析服务器状态信息)
2022/04/09 MySQL
python实现手机推送 代码也就10行左右
2022/04/12 Python
SpringBoot使用AOP实现统计全局接口访问次数详解
2022/06/16 Java/Android