指標難學,那是因為你對地址不瞭解!!!!!
go語言 指標
前言
我是以b站某個視訊來學習指標的,看完後我對指標的理解和鞏固如下
學習指標中的疑問
- 指標是什麼?
- 指標的用處又是什麼?
- 空指標和野指標又是什麼?
- 值傳遞和引用傳遞又是什麼?
- 陣列指標和指標陣列又是什麼?
指標
看了很多部落格,但是都沒有大致的介紹指標到底是什麼?不過看了c語言的指標才明白什麼叫指標
其實很容易理解,不專業的將指標==地址,我這裡打個常見的比方,假設記憶體是旅館,那麼指標就是門牌號,切記只是門牌號而是整個房間,也就是說指標就是一個標誌或者說標記
模擬場景
小明失戀了,所以借酒消愁,愁更愁.一不小心就喝到12點,這時小明家離小明喝酒的地方很遠,所以小明只能住旅館了,到達旅館前臺,“老闆,給我開間房”,老闆很快通過電腦查了一下,看有無可用房間,發現有者標記該房間為小明所住下,然後並給小明房卡
在上面的描述中,房卡就是指標,標記該房間為小明所住下表示該指標(地址)的內容為小明
c和golang 的指標還是有區別的
- c的指標可以進行運算,例如*(p+1)代表當前地址的下一個地址,golang為什麼不讓指標進行運算可能考慮到記憶體溢位或者訪問到其他地址導致資訊洩露問題
- golang將->全部轉化成了.
棧和堆
這裡是個題外話,但是也挺重要的,如果學久了計算機,就很容易聽到堆疊
其實通俗易懂的話就是他們的出現是為了記憶體更好的分配
首先講棧主要存什麼?
- 最先要說明的是棧會存函式,而且會給函式分配一個指定的空間,而這個空間又會儲存區域性變數,形參,記憶體欄位描述值
- 棧有一個特點就是棧會自動產生和自動釋放,當你用完這個函式就會自動釋放
當函式1使用完後會自動釋放掉函式1在棧所佔用的空間,並讓函式2向上移動,變成如下
注意:函式2的記憶體空間不變
在說堆之前先說一下他們之間的區別吧
可以看出棧明細比堆好那麼多,但為什麼還要引用堆呢,那是因為棧在被記憶體分配的空間很少一般1M-16M,而堆隨著你的記憶體大小在加上你的管理可能達到無限,沒辦法,你在少我也只能用那麼一點點資源,所以我們是被迫選擇用堆,雖然堆的壞處那麼多不過人為了不屈服所以建立了GC(垃圾回收機制)來克服堆帶來的問題,這樣我們 就可以隨便用堆了
指標的作用
其實指標的作用我也不是很清楚但是感覺還是蠻重要的,畢竟房卡還是很重要的,沒用房卡我們可能都不知道我們要住那一間,萬一亂進到一間讓人羞羞的房間那豈不是賺了,個人用指標用的最多的可能還是連結串列,資料結構,一個指標指向另一個指標,也就是我不單單隻知道我在那個房間,我還在知道我朋友在那個房間
空指標和野指標
空指標通俗易懂的話就是老闆沒有給你房卡,所以你根本不知道你應該入住那個房間,野指標也很好理解就是老闆的孩子無理取鬧隨便給你了一個可能已經有入住的或者不存在的房卡給你,導致你出現了出乎意料的事情
值傳遞和引用傳遞
值傳遞
值傳遞其實很好理解,就是小明有一個長得一模一樣的兄弟二明,小明先入住分配到一個房間,但是二明在入住時並不會因為你和小明張的一樣就分配到小明的房間裡面而是重新分配一個新的房間給你,所以二明在自己的房間裡做什麼都不會影響小明.
package main
import "fmt"
func test(x int){
fmt.Println("二明的房卡為:",&x);
}
func main() {
x:=100;
fmt.Printf("小明的房卡為%p\n",&x);
test(x);
}
引用傳遞
引用傳遞就是共享的意思,如同某個人和你合租一間房.
package main
import "fmt"
func main() {
x:=100;
//和小明進行合租,新客戶獲取小明房卡
var p *int =&x;
fmt.Println("設計前房子的內容為",x);
//客戶進行重新設計
*p=200
fmt.Println("客戶重新設計房子後的內容為",x);
fmt.Println("客戶重新設計房子後的內容為",*p);
//小明再次改進房子
x=300
fmt.Println("小明改進房子後的內容為",*p);
fmt.Println("小明改進房子後的內容為",x);
}
簡單易懂的話就是隻要獲取某個值的地址你就可以隨意改變這個地址裡面的值
指標陣列和陣列指標
在理解指標陣列和陣列指標前我最先想到的是這二個玩意要怎麼表示
//指標陣列
var p [...] *int;
//陣列指標
var p2 *[...] int
看到這個情況很好區分二者
你可以進行切割法
p[…]和 *int分別表示陣列和int指標,二者進行結合就變成了數組裡儲存int指標
p2 *和[…]int 分別表示指標和int陣列,二者進行結合就變成了以指標的形式的int陣列(解決了如何以指標為資料型別的陣列)