Go的指针 &和*的区别

指针基础知识

package main

import "fmt"

func main() {
	var p *int
	p = new(int)
	*p = 1
	fmt.Println(p, &p, *p)
}

输出
0xc04204a080  0xc042068018  1

  • 在 Go 中 * 代表取指针地址中存的值,& 代表取一个值的地址

  • 对于指针,我们一定要明白指针储存的是一个值的地址,但本身这个指针也需要地址来储存

  1. 如上 p 是一个指针,他的值为内存地址 0xc04204a080

  2. 而 p 的内存地址为 0xc042068018

  3. 内存地址 0xc04204a080 储存的值为 1

  • 错误实例

在 golang 中如果我们定义一个指针并像普通变量那样给他赋值,例如下方的代码

package main

import "fmt"
func main() {
	var i *int
	*i = 1
    fmt.Println(i, &i, *i)
}
  • 就会报这样的一个错误
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x498025]
  • 报这个错的原因是 go 初始化指针的时候会为指针 i 的值赋为 nil ,但 i 的值代表的是 *i 的地址, nil 的话系统还并没有给 *i 分配地址,所以这时给 *i 赋值肯定会出错
  • 解决这个问题非常简单,在给指针赋值前可以先创建一块内存分配给赋值对象即可
package main

import "fmt"
func main() {
	var i *int
	i = new(int)
	*i = 1
	fmt.Println(i, &i, *i)
}

*和&的区别 :

& 是取地址符号 , 即取得某个变量的地址 , 如 ; &a
*是指针运算符 , 可以表示一个变量是指针类型 , 也可以表示一个指针变量所指向的存储单元 , 也就是这个地址所存储的 .

从代码中验证 :

先构建一个Rect类型 : 
这里写图片描述 
1. &是取地址符号, 取到Rect类型对象的地址 
这里写图片描述 
2. *可以表示一个变量是指针类型(r是一个指针变量): 
这里写图片描述 
3.*也可以表示指针类型变量所指向的存储单元 ,也就是这个地址所指向的值 
这里写图片描述 
4.查看这个指针变量的地址 , 基本数据类型直接打印地址 
这里写图片描述

从代码中验证 :

//先构建一个Person类型 : 
package main 
import "fmt" 
type Person struct{
    name string  
    age int 
}
func (r *Person) hello() string{
    return r.name ; 
}

func main(){
 fmt.Println(&Person{"liu",10})                //&{liu 10}
 var r  = &Person{"liu",10}
 fmt.Println(r)                                //&{liu 10}
 fmt.Println(*r)                               //{liu 10}
 fmt.Println(&r)                               //0xc000006030
 var r2 *Person =  &Person{"liu2",10}
 fmt.Println(r2)                               //&{liu2 10}
}

1.&是取地址符号, 取到Person类型对象的地址               &Person{"liu",10}- -->   &{liu 10}

2.*可以表示一个变量是指针类型(r是一个指针变量):

3.*也可以表示指针类型变量所指向的存储单元 ,也就是这个地址所指向的值             fmt.Println(*r)  ----> {liu 10}

4.查看这个指针变量的地址 , 基本数据类型直接打印地址                        fmt.Println(&r)   --->  0xc000006030


经常会见到: p . *p , &p 三个符号
p是一个指针变量的名字,表示此指针变量指向的内存地址,如果使用%p来输出的话,它将是一个16进制数。

而*p表示此指针指向的内存地址中存放的内容,一般是一个和指针类型一致的变量或者常量。


而我们知道,&是取地址运算符,&p就是取指针p的地址。等会,怎么又来了个地址,它到底和p有什么区别?

区别在于,指针p同时也是个变量,既然是变量,编译器肯定要为其分配内存地址,就像程序中定义了一个int型的变量i,编译器要为其分配一块内存空间一样。

而&p就表示编译器为变量p分配的内存地址,而因为p是一个指针变量,这种特殊的身份注定了它要指向另外一个内存地址,程序员按照程序的需要让它指向一个内存地址,这个它指向的内存地址就用p表示。而且,p指向的地址中的内容就用*p表示
 

指针的理解

  • 我的理解指针(Point),一个变量指向内存中存储某个值得地址,那么这个变量是一个指针变量,个人是如此理解也就是说指针指的是地址,不是值
  • 百度百科的定义,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。

go的指针

在go中指针有两个概念

指针变量

一个指针变量是可以指向任何一个值的内存地址,

指针变量也是占用存储空间的,在32位系统中占用4个字节,在64位系统中占用8个字节,与这个地址存储的值的大小没有关系

指针类型

指针类型和指针变量一块出现,指的是这个指针变量的类型是什么,

比如我们声明了一个temp int = 1,那么temp变量的这个类型是 int,同时指针变量也是有指针类型的,用 T表示,T是type的意思,代表具体的类型,

比如 `pointTemp int = &temp`, 代表 pointTemp这个变量是指针变量,类型是*int我们看下面一段代码

func PointStudy()  {   
    // 每一个变量在运行时都有一个地址(这个地址存储着这个变量对应的值)  
    var temp int = 1   
    //  go语言得取地址符, temp 变量,通过&符号来获取temp这个变量在内    存中的地址,我们将获取到的或者地址赋值给一个指针变量 pointTemp ,类型*int   
    var pointTemp *int= &temp
   fmt.Println(temp)   
   fmt.Println(pointTemp)
}
//输出结果
1
0xc00005a2d0

指针变量也是变量,

变量、指针和地址三者的关系是:

每一个变量都有自己地址,每一个指针的值就是地址(也就是这个指针通过fmt.Println输出后一个地址)

Image.png

如何获取指针对应的地址的值:go语言中通过 &符号 获取变量地址,通过 * 来获取地址存储的值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值