Go 语言指针

& 括号星号原则:由于编辑器的抵触,( * ) 仅仅是代表一个星号而已

& 不指向地址的指针为空原则:声明指针却没有指向地址,那么这个指针的地址将为 nil(空)

& 指针首先分配地址空间原则:声明指针之后首先得分配一段内存空间,才能对指针的值进行读写操作

& 指针不喜欢变量地址原则:声明指针之后使用语句 p = new(int) 用来分配一段 int 内存空间,而不是指向变量的地址 p = &a

指针的定义和初始化

语法:var 指针名 (*)指针类型

package main

import "fmt"

func main() {

	// 1. 定义指针变量和 int 类型的变量
	var p_int *int
	num1 := 100

	// 2. 使指针 p_int 指向变量 num1 的地址
	p_int = &num1

	// 3. 修改指针的值在本质上也就修改了它指向的值
	*p_int = 200
	fmt.Println(num1) // 200
}

重点(即不指向地址的指针为空原则):没有指向变量地址的指针是空的(nil)

package main

import "fmt"

func main() {

	var p_int *int
	fmt.Println(p_int) // <nil>

	num1 := 100
	p_int = &num1
	fmt.Println(p_int) // 0xc0000160d0
}

野指针:指针指向未知的空间(即指针首先分配地址空间原则)

package main

func main() {

	// 野指针 -- 指向未知的空间
	var p_int *int

	//*p_int = 100 // invalid memory address or nil pointer dereference
}

创建内存空间(即指针不喜欢变量原则)

package main

import "fmt"

func main() {

	var p_int *int

	p_int = new(int)

	*p_int = 100

	fmt.Println(*p_int) // 100
}

自动推导类型

package main

import "fmt"

func main() {

	// 自动推导类型
	// 1. 分配变量的地址
	num := 100
	p := &num
	fmt.Println(*p) // 100

	// 2. 创建地址空间
	p1 := new(int)
	*p1 = 200
	fmt.Println(*p1) // 200
}

指针作为函数形参

重点:地址传递

package main

import "fmt"

// 交换 a 和 b 的值
func Swap(a *int, b *int) {
	*a, *b = *b, *a
}

func main() {

	num1, num2 := 1, 2

	fmt.Println(num1, num2) // 1 2

	Swap(&num1, &num2)

	fmt.Println(num1, num2) // 2 1
}

数组指针

数组指针声明及赋值过程

步骤:首先初始化数组,然后声明数组指针,最后将指针指向数组

package main

import "fmt"

func main() {

	// 1. 定义长度为 3 的数组
	arr := [3]int{1, 2, 3}

	// 2. 定义数组指针
	var p *[3]int

	// 3. 指针指向数组
	p = &arr

	// 4. 打印指针的值
	fmt.Println(*p) // [1 2 3]
}

数组指针初始化过程(即自动推导)

package main

import "fmt"

func main() {

	// 1. 定义长度为 3 的数组
	arr := [3]int{1, 2, 3}

	// 2. 指针指向数组
	p := &arr

	// 3. 打印指针的值
	fmt.Println(*p) // [1 2 3]
}

数组指针的使用

语法:(*)数组指针名[索引项] = 值 OR 数组指针名[索引项] = 值

package main

import "fmt"

func main() {

	// 1. 定义长度为 3 的数组
	arr := [3]int{1, 2, 3}

	// 2. 指针指向数组
	p := &arr

	// 3. 使用数组指针
	(*p)[0] = 100
	p[1] = 200

	// 4. 打印数组指针
	fmt.Println(*p) // [100 200 3]
}

数组指针作为函数形参

重点:地址传递

package main

import "fmt"

func Test(p *[3]int) {
	p[1] = 100
}

func main() {

	arr := [3]int{1, 2, 3}

	fmt.Println(arr) // [1 2 3]

	Test(&arr)

	fmt.Println(arr) // [1 100 3]
}

指针数组

简单形式

package main

import "fmt"

func main() {

	num1, num2, num3 := 1, 2, 3

	var p [3]*int = [3]*int{&num1, &num2, &num3}

	fmt.Println(p) // [0xc0000ac058 0xc0000ac070 0xc0000ac078]

	fmt.Println(*p[0]) // 1
	fmt.Println(*p[1]) // 2
	fmt.Println(*p[2]) // 3
}

复杂形式

package main

import "fmt"

func main() {

	arr1, arr2, arr3 := [3]int{1, 2, 3}, [3]int{4, 5, 6}, [3]int{7, 8, 9}

	var p [3]*[3]int = [3]*[3]int{&arr1, &arr2, &arr3}

	fmt.Println(p) // [0xc0000141c8 0xc0000141e0 0xc0000141f8]

	fmt.Println(*p[0]) // [1 2 3]
	fmt.Println(*p[1]) // [4 5 6]
	fmt.Println(*p[2]) // [7 8 9]
}

切片指针

切片指针初始化过程(即自动推导)

package main

import "fmt"

func main() {

	slice_p := &[]int{1, 2, 3}

	fmt.Println(*slice_p) // [1 2 3]

	*slice_p = append(*slice_p, 4, 5, 6)

	fmt.Println(*slice_p) // [1 2 3 4 5 6]
}

切片指针作为函数形参

重点:地址传递

package main

import "fmt"

func Test(p *[]int) {
	*p = append(*p, 4, 5, 6)
}

func main() {

	slice_p := &[]int{1, 2, 3}

	Test(slice_p)

	fmt.Println(*slice_p) // [1 2 3 4 5 6]
}

结构体指针

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func main() {

	// 自动推导
	struct_p := &Student{1, 100}

	fmt.Println(*struct_p) // {1 100}

	// 声明及赋值
	var struct_p1 *Student = &Student{2, 90}

	fmt.Println(*struct_p1) // {2 90}
}

结构体指针的使用

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func main() {

	// 声明及赋值
	var struct_p1 *Student = &Student{2, 90}

	fmt.Println(*struct_p1) // {2 90}

	// 通过指针间接改变结构体内的属性
	(*struct_p1).score = 1000
	// 通过指针直接改变结构体内的属性
	struct_p1.id = 10

	fmt.Println(*struct_p1) // {10 1000}
}

结构体指针作为函数形参

重点:地址传递

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func Test(struct_p *Student) {
	struct_p.score = 72
}

func main() {

	// 声明及赋值
	var struct_p1 *Student = &Student{2, 90}

	fmt.Println(*struct_p1) // {2 90}

	Test(struct_p1)

	fmt.Println(*struct_p1) // {2 72}
}

结构体数组指针

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func main() {

	struct_p := &[3]Student{
		{1, 100},
		{1, 100},
		{1, 100},
	}

	fmt.Println(*struct_p) // [{1 100} {1 100} {1 100}]

	struct_p[0].score = 1000

	fmt.Println(*struct_p) // [{1 1000} {1 100} {1 100}]
}

map 类型的结构体指针

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func main() {

	// 字典的键为整数
	// 字典的值为 结构体类型的数组指针
	m := make(map[int]*[3]Student)

	m[1] = &[3]Student{
		{1, 100},
		{2, 200},
		{3, 300},
	}

	fmt.Println(*(m[1])) // [{1 100} {2 200} {3 300}]
}

多级指针

package main

import "fmt"

func main() {

	// 一级指针 -- 指向变量的地址
	num1 := 1
	p := &num1
	fmt.Println(*p) // 1

	// 二级指针 -- 指向一级指针的地址
	pp := &p
	fmt.Println(pp)   // 0xc0000d8028 -- 二级指针的地址
	fmt.Println(*pp)  // 0xc000016098 -- 一级指针的地址
	fmt.Println(**pp) // 1 -- 一级指针指向的值
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是我来晚了!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值