golang学习五:指针

一、指针的定义与使用

1. 指针的定义:

  • 指针就是存储变量内存地址的变量;
func main() {
	i := 100

	fmt.Printf("%p\n", &i) // 0xc000012090
	fmt.Printf("%v\n", &i) // 0xc000012090
}
// 定义一个指针变量
var p *int
p = &i	// 把变量i地址复制到指针变量p
fmt.Printf("i=%d, p=%p\n", i, p)	// i=100, p=0xc000012090

2. 指针的使用

// 定义一个指针变量
var p *int
p = &i
fmt.Printf("i=%d, p=%p\n", i, p) // i=100, p=0xc000012090

// 使用指针修改变量
*p = 80
fmt.Printf("i=%d, p=%p, pv=%v\n", i, p, *p) // i=80, p=0xc000012090, pv=80

注意:

  • 指针变量的默认值是 <nil>
  • 内存地址编号为0 (0 ~ 255为系统占用, 不允许用户使用);
  • 野指针: 指针变量指向了一个位置的空间
var p1 *int
*p = 56 // 野指针

3. new函数:

// new函数
// gc垃圾回收机制 自动释放空间
var p2 *int
p2 = new(int)
*p2 = 57
fmt.Println(*p2) // 57

4. 自动推导:

// 自动推导
p3 := new(int)
*p3 = 999
fmt.Println(*p3)	// 999

二、指针作为函数参数:

  • 地址传递
func Swap(a, b *int) {
	*a, *b = *b, *a
	fmt.Println(*a, *b) // 20 10
}

func main() {
	a := 10
	b := 20
	fmt.Println(a, b) // 10 20

	// &变量 取地址操作, 引用运算符
	// *指针变量 取值操作 解引用运算符
	Swap(&a, &b)
	fmt.Println(a, b) // 20 10
}

三、数组指针:

1. 定义数组指针


func main() {
	arr := [3]int{1, 2, 3}

	//定义指针 指向数组 => 数组指针
	var p *[3]int
	p = &arr
	fmt.Println(p, *p) // &[1 2 3] [1 2 3]

	// 自动推导
	p1 := &arr
	fmt.Println(p1, *p1)	// &[1 2 3] [1 2 3]
}

2. 通过指针操作数组:

(*p)[0] = 111
p[1] = 222
fmt.Println(p, *p)	// &[111 222 3] [111 222 3]

指向问题

func main() {
	arr := [5]int{1, 2, 3, 4, 5}

	p1 := &arr             // 是一个数组
	p2 := &arr[0]          // 是一个数组元素
	fmt.Printf("%p\n", p1) // 0xc000022090
	fmt.Printf("%p\n", p2) // 0xc000022090

	fmt.Printf("%T\n", p1) // *[5]int
	fmt.Printf("%T\n", p2) // *int
}

3. 指针数组:

func main() {
	a, b, c := [3]int{1, 2, 3}, [3]int{4, 5, 6}, [3]int{7, 8, 9}

	// 定义数组指针的数组
	var arr [3]*[3]int = [3]*[3]int{&a, &b, &c}
	fmt.Println(arr)        // [0xc000016120 0xc000016140 0xc000016160]
	fmt.Printf("%T\n", arr) // [3]*[3]int

	(*arr[1])[1] = 555	// 注意指针的运算优先级
	fmt.Println(b) // [4 555 6]
}

四、指针和切片:

1. 定义切片指针:

func main() {
	s := []int{1, 2, 3, 4, 5}
	p := &s
	fmt.Printf("%p\n", p) // 0xc00000c060
	fmt.Printf("%p\n", s) // 0xc000022090

	fmt.Printf("%T\n", p)	// *[]int
}

2. 通过指针操作切片元素:

// 通过指针操作切片
(*p)[1] = 222
fmt.Println(s)	// [1 222 3 4 5]

五、切片指针作为函数参数:

六、多级指针:

1.定义多级指针:

指向指针的指针

func main() {
	a := 10

	// 一级指针
	p := &a
	fmt.Println(p)        // 0xc000012090
	fmt.Printf("%T\n", p) // *int

	// 指向指针的指针
	pp := &p
	fmt.Printf("%T\n", pp)	// **int
}

七、内存存储模型:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅弋、璃鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值