自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

看完這個,我徹底理解了Golang的指針

開發(fā) 前端
大家知道C語言之所以強(qiáng)大,就是因?yàn)閏語言支持指針,而且權(quán)限特別大,c語言可以對計算機(jī)中任何內(nèi)存的指針進(jìn)行操作,這樣自然而然也會帶來一些不安全的因素,所以在golang中,「取消了對指針的一些偏移,翻轉(zhuǎn)等算術(shù)運(yùn)算」(+、-、++、--)所以使用起來更安全。

golang中一個非常鮮明的特點(diǎn)就是引入了指針的使用,這個在py、php、java中都是不支持的,但是很多讀者都反饋說對指針不是很了解,所以今天寫了這篇文章,當(dāng)然我盡量用通俗的語言,希望對您有用。

什么是指針

想了解什么是指針,你先得了解數(shù)據(jù)是怎么取到的

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

上述代碼非常簡單,我相信不會golang的讀者應(yīng)該也能看懂。但是他底層究竟干嘛了?你真的了解過么?接下來咱們逐一解釋

var a int

首先這一步,是給變量a,在內(nèi)存中開辟了一塊空間,因?yàn)槭莍nt類型,所以空間大小為4個字節(jié),那么問題來了,「這塊空間開在內(nèi)存哪個位置?」 首先這塊位置是系統(tǒng)「隨機(jī)分配」的一塊。另外給這塊內(nèi)存做了一個「標(biāo)記」,方便下次找到,「這個標(biāo)記就在這塊內(nèi)存的起始的位置」

a = 1

接下來給變量a賦值為1。那么系統(tǒng)如何賦值的呢?首先總得找到a這塊內(nèi)存在哪吧?「如何找到給a分配的那塊內(nèi)存的呢?」當(dāng)然是通過之前給a變量做的那個「標(biāo)記」。通過標(biāo)記找到這塊內(nèi)存所在的位置,然后直接在開辟好的內(nèi)存空間存下給a賦值的數(shù)據(jù)就可以了。

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

這段代碼,我們暫且先不用去了解fmt.Println是怎么實(shí)現(xiàn)的,只用關(guān)心a是怎么取到的,當(dāng)然是先「找到a之前所做的那個標(biāo)記」,找到對應(yīng)的內(nèi)存所在的位置,直接往后偏移4個位置把值取出來就行。

這下是不是感覺清晰明了了?

我們在上述過程中,所說的「標(biāo)記」,就是「指針」.所以指針其實(shí)就是一個「標(biāo)記數(shù)據(jù)所在位置的數(shù)據(jù)類型而已」,只不過他有一些自己特殊的語法而已,而且是一種新的數(shù)據(jù)類型。這么來看,就很簡單了。

指針的定義

指針是一種「數(shù)據(jù)類型」,用于表示數(shù)據(jù)的「內(nèi)存地址」。

如何使用指針

我們來看下面幾個例子感受一下

case1

var a string  //聲明一個字符串類型的變量,初始值為""
var b *string //聲明一個字符串指針類型的變量,初始值為nil,聲明指針類
fmt.Println("a:", a, " b:", b)
//輸出結(jié)果為
//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的內(nèi)存地址", &name, " p_name:", p_name, "p_name的具體值:", *p_name)
//輸出結(jié)果為
//name: 小飯 name的內(nèi)存地址 0x14000010240 p_name: 0x14000010240 p_name的具體值:

注意

  • 取變量name的首地址,也就是指針的值,需要用&name表示,而取出來的值也只能用指針這種變量類型來保存,所以var p_name *string = &name這段代碼是合理的
  • p_name的具體值是隨機(jī)分配的一個16進(jìn)制的值,0x14000010240,知道這個代表的是指針的值就行了,因?yàn)槭请S機(jī)分配的,所以不同設(shè)備是不一樣的。
  • 要取一個指針類型指向的具體值,用 * (對應(yīng)的指針類型的變量名)就能直接取到,比如上面的例子,「對應(yīng)的指針類型的變量名為p_name,所以用*p_name就能直接取到指針p_name所指向的具體值」。

說明

上面我們通過&name獲取到了name的內(nèi)存空間的地址是0x14000010240,p_name的變量的值實(shí)際上是name變量的內(nèi)存空間的值,p_name也是一個變量 那么p_name變量所存放值的地方,是不是也會有一個內(nèi)存空間呢?是的,p_name這個指針變量也會指向一個內(nèi)存空間

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

fmt.Println("name:", name, "p_name的值", p_name, " p_name指針變量的內(nèi)存地址:", &p_name)
//輸出
//name: 小飯 p_name的值 0x14000010240 p_name指針變量的內(nèi)存地址: 0x1400000e028

指針在數(shù)組中的應(yīng)用

大家首先得區(qū)分一個概念,「數(shù)組指針」和「指針數(shù)組」的區(qū)別。

數(shù)組指針

簡單說數(shù)組指針就是整個數(shù)組都為指針

, b, c := 1, 2, 3
arr := [3]int{a, b, c}
var ptrArr *[3]int
ptrArr = &arr
arr[1] = 200 //改變數(shù)組的值,并不會影響到對應(yīng)數(shù)組元素的變量本身
fmt.Println(b)
fmt.Println(arr[1])
fmt.Println((*ptrArr)[1]) // 可以簡單寫為:ptrArr[1]
//結(jié)果輸出為
//2
//200
//200

直接改變數(shù)組的某個元素,不會影響到對應(yīng)元素的變量。

指針數(shù)組

簡單說就是數(shù)組每個元素都為指針

, b, c := 1, 2, 3
arr := [3]int{a, b, c}
arr[1] = 2 // 修改普通數(shù)組中的值
// 定義指針數(shù)組
var ptrArr [3]*int //每個元素為一個指針
ptrArr = [3]*int{&a, &b, &c}
*ptrArr[1] = 200 //修改某個元素的指,不會影響到數(shù)組本身
fmt.Println(b)
fmt.Println(arr[1])
fmt.Println(*ptrArr[1])
//結(jié)果輸出
//200
//2
//200

當(dāng)然指針數(shù)組和數(shù)組指針有很多細(xì)節(jié)需要注意,如果這篇文章閱讀量還可以,咱們后面專門會開一篇講解這個問題。在這里有個簡單的認(rèn)識即可。希望大家記得多多轉(zhuǎn)發(fā)和點(diǎn)贊哦。

指針在函數(shù)中的應(yīng)用

case1

func main() {
var a int = 123
changeData(a)
fmt.Println(a)
}
func changeData(b int) {
b = 456
}
//輸出結(jié)果
//123

大家想象一下最終打印出來的a是123 還是456,當(dāng)然是123.為什么會這樣呢?因?yàn)檫\(yùn)行到changeData中,把a(bǔ)傳進(jìn)去之后,相當(dāng)于執(zhí)行了一步

var b int
b = 1

所以自然對b進(jìn)行任何修改都不會影響到a,輸出的自然是123

case2

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

在這一次函數(shù)參數(shù)傳遞中,相當(dāng)于執(zhí)行了

var b *int
b = &a

b就是指向a的指針,所以*b修改了,a自然也會跟著修改。

golang指針和c語言指針的區(qū)別

大家知道C語言之所以強(qiáng)大,就是因?yàn)閏語言支持指針,而且權(quán)限特別大,c語言可以對計算機(jī)中任何內(nèi)存的指針進(jìn)行操作,這樣自然而然也會帶來一些不安全的因素,所以在golang中,「取消了對指針的一些偏移,翻轉(zhuǎn)等算術(shù)運(yùn)算」(+、-、++、--)所以使用起來更安全。

責(zé)任編輯:武曉燕 來源: 程序員小飯
相關(guān)推薦

2024-03-15 08:23:26

異步編程函數(shù)

2019-12-26 09:15:44

網(wǎng)絡(luò)IOLinux

2022-03-27 09:06:25

vuexActionsMutations

2023-10-27 11:21:20

C語言Multics語言

2021-12-06 11:19:47

語言指針內(nèi)存

2022-01-06 14:25:24

C語言指針內(nèi)存

2019-12-10 13:55:10

Go指針存儲

2020-08-19 08:20:23

Python開發(fā)GitHub

2022-05-03 00:03:11

狀態(tài)管理前端開發(fā)

2020-04-16 10:55:03

Java虛擬機(jī)字節(jié)碼

2021-03-09 08:00:13

設(shè)計秒殺TPS

2023-11-08 08:27:30

泛型Java

2022-02-21 07:45:29

面向?qū)ο?/a>代碼依賴倒置

2021-09-07 07:55:22

Linux CPULinux 系統(tǒng)

2020-07-08 15:13:04

開源技術(shù) 趨勢

2024-11-25 07:39:48

2014-08-22 13:27:59

物聯(lián)網(wǎng)

2023-10-26 07:09:30

Golangrune字符

2021-05-13 08:55:33

Android架構(gòu)功能

2012-11-30 11:19:02

JavaScript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號