看完这个,我彻底了解了golang的指针

golang中一个非常鲜明的特点就是引入了指针的使用,这个在py、php、java中都是不支持的,但是很多读者都反馈说对指针不是很了解,所以今天写了这篇文章,当然我尽量用通俗的语言,希望对您有用。

什么是指针

想了解什么是指针,你先得了解数据是怎么取到的

func main() {
    var a int
    a = 1
    fmt.Println("a的值为", a)
}

上述代码非常简单,我相信不会golang的读者应该也能看懂。但是他底层究竟干嘛了?你真的了解过么?接下来咱们逐一解释

var a int

首先这一步,是给变量a,在内存中开辟了一块空间,因为是int类型,所以空间大小为4个字节,那么问题来了,这块空间开在内存哪个位置? 首先这块位置是系统随机分配的一块。另外给这块内存做了一个标记,方便下次找到,这个标记就在这块内存的起始的位置

a = 1

接下来给变量a赋值为1。那么系统如何赋值的呢?首先总得找到a这块内存在哪吧?如何找到给a分配的那块内存的呢?当然是通过之前给a变量做的那个标记。通过标记找到这块内存所在的位置,然后直接在开辟好的内存空间存下给a赋值的数据就可以了。

fmt.Println("a的值为", a)

这段代码,我们暂且先不用去了解fmt.Println是怎么实现的,只用关心a是怎么取到的,当然是先找到a之前所做的那个标记,找到对应的内存所在的位置,直接往后偏移4个位置把值取出来就行。

这下是不是感觉清晰明了了?

我们在上述过程中,所说的标记,就是指针.所以指针其实就是一个标记数据所在位置的数据类型而已,只不过他有一些自己特殊的语法而已,而且是一种新的数据类型。这么来看,就很简单了。

指针的定义

指针是一种数据类型,用于表示数据的内存地址

如何使用指针

我们来看下面几个例子感受一下

case1

var a string  //声明一个字符串类型的变量,初始值为""
var b *string //声明一个字符串指针类型的变量,初始值为nil,声明指针类
fmt.Println("a:", a, " b:", b)
//输出结果为 
//a:   b: <nil>
注意:
  • 声明指针的类型,只需要在前面加上一个*就可以了,这是固定的语法
  • 不管什么指针类型(*int, *string, *float),初始值都为nil

case2

var name string = "小饭"   //声明一个name为string类型,并且赋值为"小饭"
var p_name *string = &name //声明一个p_name为*string(字符串的指针类型),并且赋值为&a(在a前面加上一个&的意思是取a的首地址)
fmt.Println("name:", name, "name的内存地址", &name, " p_name:", p_name, "p_name的具体值:", *p_name)
//输出结果为 
//name: 小饭 name的内存地址 0x14000010240  p_name: 0x14000010240 p_name的具体值: 小饭
注意
  • 取变量name的首地址,也就是指针的值,需要用&name表示,而取出来的值也只能用指针这种变量类型来保存,所以var p_name *string = &name这段代码是合理的
  • p_name的具体值是随机分配的一个16进制的值,0x14000010240,知道这个代表的是指针的值就行了,因为是随机分配的,所以不同设备是不一样的。
  • 要取一个指针类型指向的具体值,用 * (对应的指针类型的变量名)就能直接取到,比如上面的例子,对应的指针类型的变量名为p_name,所以用p_name就能直接取到指针p_name所指向的具体值*。
说明

上面我们通过&name获取到了name的内存空间的地址是0x14000010240,p_name的变量的值实际上是name变量的内存空间的值,p_name也是一个变量
那么p_name变量所存放值的地方,是不是也会有一个内存空间呢?是的,p_name这个指针变量也会指向一个内存空间

var name string = "小饭"
    var p_name *string = &name

    fmt.Println("name:", name, "p_name的值", p_name, " p_name指针变量的内存地址:", &p_name)
  //输出
  //name: 小饭 p_name的值 0x14000010240  p_name指针变量的内存地址: 0x1400000e028

指针在数组中的应用

大家首先得区分一个概念,数组指针指针数组的区别。

数组指针

简单说数组指针就是整个数组都为指针

  a, b, c := 1, 2, 3
    arr := [3]int{a, b, c}
    var ptrArr *[3]int  
    ptrArr = &arr
    arr[1] = 200   //改变数组的值,并不会影响到对应数组元素的变量本身
    fmt.Println(b)
    fmt.Println(arr[1])
    fmt.Println((*ptrArr)[1]) // 可以简单写为:ptrArr[1]
  //结果输出为
  //2
  //200
  //200
直接改变数组的某个元素,不会影响到对应元素的变量。

指针数组

简单说就是数组每个元素都为指针

  a, b, c := 1, 2, 3
    arr := [3]int{a, b, c}
    arr[1] = 2 // 修改普通数组中的值
    // 定义指针数组
    var ptrArr [3]*int  //每个元素为一个指针
    ptrArr = [3]*int{&a, &b, &c}
    *ptrArr[1] = 200 //修改某个元素的指,不会影响到数组本身
    fmt.Println(b)
    fmt.Println(arr[1])
    fmt.Println(*ptrArr[1])
  //结果输出
  //200
  //2
  //200

当然指针数组和数组指针有很多细节需要注意,如果这篇文章阅读量还可以,咱们后面专门会开一篇讲解这个问题。在这里有个简单的认识即可。希望大家记得多多转发和点赞哦。

指针在函数中的应用

case1

func main() {
    var a int = 123
    changeData(a)
    fmt.Println(a)
}
func changeData(b int) {
    b = 456
}
//输出结果
//123

大家想象一下最终打印出来的a是123 还是456,当然是123.为什么会这样呢?因为运行到changeData中,把a传进去之后,相当于执行了一步

var b int
b = 1

所以自然对b进行任何修改都不会影响到a,输出的自然是123

case2

func main() {
    var a int = 123
    changeData(&a)
    fmt.Println(a)
}
func changeData(b *int) {
    *b = 456
}

在这一次函数参数传递中,相当于执行了

var b *int
b = &a

b就是指向a的指针,所以*b修改了,a自然也会跟着修改。

golang指针和c语言指针的区别

大家知道C语言之所以强大,就是因为c语言支持指针,而且权限特别大,c语言可以对计算机中任何内存的指针进行操作,这样自然而然也会带来一些不安全的因素,所以在golang中,取消了对指针的一些偏移,翻转等算术运算(+、-、++、--)所以使用起来更安全。

本文由mdnice多平台发布

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容