Go语言指针

释放双眼,带上耳机,听听看~!

文章目录

  • 什么是指针
  • 指针声明
  • 如何使用指针
  • 关于空指针
  • 指针作为函数参数使用
  • 不常用的new函数

什么是指针

写代码的时候,我们通过变量就可以操作存储在内存中的值,进行赋值、加减运算等。大家有没有想过,变量代表什么呢?其实,一个变量对应一段内存空间,这段空间就存储了该变量相对应类型的值。指针的值就对应变量的地址,只通过指针,就可以更新或者读取变量的值,而不需要用到变量名。


1
2
3
4
5
6
7
8
1var i int = 10      //声明变量i,并初始化为10
2var ptr *int = &i
3fmt.Println(ptr,*ptr)
4// 0xc000018060 10  指针变量ptr存储的是i地址,*ptr对应指针指向的变量的值
5*ptr = 12                  // i=12  更新指针指向的变量的值
6fmt.Println(*ptr,i)        // 12 12
7
8

上面这段代码,声明了*int 类型的指针变量 ptr ,通过取址运算符&获得指向整型变量 i 的地址。可以说,指针ptr指向变量i,或者说ptr指针保存了变量i的地址。

指针声明

通过上面一段话的解释,相信大家对指针有了比较清晰的认识:指针指向一个变量的内存地址。要想使用指针,必须先声明,格式如下:


1
2
3
4
5
6
7
8
9
10
11
1var var_name *var_type
2// var_name 指针名称,var_type 指针所指向的变量的类型
3var i int = 10
4str := "go"
5var ip *int         // *int类型的指针
6var pstr *string    // *string类型的指针
7ip = &i
8pstr = &str
9fmt.Println(*ip,*pstr)     // 10 go
10
11

注意:*int类型的指针,说明该指针指向的一定是int类型的变量,*string类型也类似。


1
2
3
4
5
1str := "go"
2var ip *int
3ip = &str  // 编译不会通过
4
5

*int 类型的指针,指向的变量若是string类型的,编译器编译的时候就会报错:


1
2
3
1cannot use &str (type *string) as type *int in assignment
2
3

如何使用指针

文章写到这里,关于如何使用指针,其实上文已经列出来了,主要经过三个步骤:声明、赋值和访问指针指向的变量的值


1
2
3
4
5
6
7
1x,y := 1,"go"
2var px *int = &x        // 1、声明并初始化
3var py = &y                // 2、省略指针类型,编译器自动判断
4//px,py := &x,&y        // 3、使用 :=
5fmt.Println(*px,*py)     // 1 go   访问
6
7

关于空指针

一个指针已声明而没有赋值时,称为空指针,为 nil 。任何类型的指针的零值都是 nil。


1
2
3
4
5
1var ip *int
2fmt.Println(ip)                            // nil
3fmt.Printf("ip 的值为:%x", ip)            // ip 的值为:0
4
5

如果ip != nil 为真,那么p是指向某个有效变量。指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是nil时才相等。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
11、指向同一个变量 true
2x,_ := 1,1
3px,py := &x,&x
4fmt.Println(px == py)
5
62、指向不同变量 false
7x,y := 1,1
8px,py := &x,&y
9fmt.Println(px == py)
10
113、两个nil指针 true
12var px *int
13var py *int
14fmt.Println(px == py)
15
16

指针作为函数参数使用

指针包含的是一个变量的地址,如果将一个指针作为参数传递给函数,就可以通过指针来更新变量的值。


1
2
3
4
5
6
7
8
9
10
1func a(p *int){
2    *p++
3}
4
5i := 10
6fmt.Println(i)      // 10
7a(&i);
8fmt.Println(i)        // 11
9
10

不常用的new函数

给大家介绍下new函数,内建的new函数也是一种创建变量的方法,new(type)表示创建一个type类型的匿名变量,并初始化为type类型的零值,返回变量的地址,指针类型为*type。


1
2
3
4
5
6
1p := new(int)       // p, *int 类型, 指向匿名的 int 变量
2fmt.Println(*p)     // 0
3*p = 2              // 设置 int 匿名变量的值为 2
4fmt.Println(*p)     // 2
5
6

用new函数创建变量和普通变量声明语句方式创建变量没有什么区别,除了不需要声明一个临时变量的名字外。
下面的两个函数有着相同的行为:创建变量,并返回变量地址


1
2
3
4
5
6
7
8
9
1func newA() *int {
2    return new(int)
3}
4func newB() *int {
5    var i int
6    return &i
7}
8
9

每次调用new函数都会返回新的变量的地址:


1
2
3
4
5
1p := new(int)
2q := new(int)
3fmt.Println(p,q)   // 0xc000018060 0xc000018068
4
5

new函数使用的比较少,不过觉得挺有意思的,就在这给大家分享下!实际编程,多的还是使用具体类型创建变量,毕竟更方便,是吧!

给TA打赏
共{{data.count}}人
人已打赏
安全技术

c++ vector

2022-1-11 12:36:11

安全技术

php获取指定日期,前一天、前一周、前一个月、前一年,后一天,后一周,前一个月,前一年

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索