近在學習golang的過程中,發現乙個有意思的事情,有的文章說函式呼叫傳參時slice是引用傳遞,有的說是值傳遞。為什麼同乙個東西大家會不同認識?為了搞清楚其本質,我進行了以下內容的研究:
變數的變數名、變數值、變數位址在記憶體中是怎麼樣的?
指標的定義是什麼?引用的定義是什麼?二者有什麼關係?
函式傳參中值傳遞、指標傳遞與引用傳遞到底有什麼不一樣?
go中slice在傳入函式時到底是不是引用傳遞?如果不是,在函式內為什麼能修改其值?
上學的時候,老師講變數是存在記憶體中的,記憶體就像一排排抽屜組成的,每個抽屜上面有個編號,我們定義乙個變數,就是把想放的東西放到這個對應編號的抽屜裡。比如: int a = 10,用圖來表示下:
這裡:變數的名字叫a,變數的值是:10,變數的位址是:0x 00000001。
那麼問題來了,變數的值我們知道是放在了抽屜裡(記憶體中),每個抽屜有編號(位址),但是變數的名字a存放在**呢?或者說它會存在於記憶體中嗎?
大家想乙個問題,如果變數的名字要存放在記憶體中,那麼肯定分配乙個空間給他,儲存它的空間有個位址,這個位址是不是又得有個地方存起來程式才能找到?如果真是這樣設計,那麼**根本沒發寫、無法執行了。
其實變數名僅僅是寫給程式設計師看的,讓我們寫**的時候知道這個變數有什麼用,能夠通過名字呼叫變數的值。因為如果直接給你乙個位址 0x 23004123,你知道這是要幹嘛嗎?**經過編譯後,最終都會轉換成機器碼,我們定義的變數名就都不存在了,存在的只有位址跟值。
有了上面的理解,再來乙個特殊的變數:指標變數。什麼叫指標變數呢?其實就是這個變數裡邊存放的是乙個變數的位址,通過這個位址,機器可以找到對應變數的值,例如:int pa = &a,就表示變數pa抽屜裡放的是a的位址,它的型別是:int,繼續看圖:
繼續談引用,引用與指標我們經常傻傻分不清,因為它們的行為確實非常詭異,看起來效果非常相似,看**:
由於引用的概念是在 c++ 中引入的,因此下面的**使用c++,僅僅是一些列印而已,放心看下去
int main()
通過上面的**我們發現,指標與引用都能達到乙個效果:都有能力修改a的值,指標前面講過了,因為它儲存了a的位址,通過解引用操作後,實際上就是開啟了a的抽屜,因此可以進行修改。那麼引用又是怎麼辦到的?這裡注意乙個細節:pa = 20; c = 30;a = 40。我們看到操作c的時候與操作a是一樣的方式:直接使用變數名,但是pa要想改變a的值,必須進行 pa 操作(解引用),如果直接 pa=20,這僅僅是改變的pa的值,讓他指向了另外乙個位址。
為什麼引用與變數是一樣的操作方式?先來看一下引用的定義:
引用就是某一變數的乙個別名,對引用的操作與對變數直接操作完全一樣。那麼別名是什麼意思呢?繼續看圖,一看就懂
通過上面的分析不知道你理解了幾分?或者你是不是對指標與引用還是半信半疑?沒關係,寫點**證明一下即可,我們要證明的是:
int main()
獲得輸出:
10 // 變數a的值
0x7ffee3c7a768 // 變數a的位址
0x7ffee3c7a768 // 指標的值,是變數a的位址
0x7ffee3c7a760 // 指標變數自己的位址
10 // 變數a的值
0x7ffee3c7a768 // 引用變數c的位址,與變數a的位址完全一樣
在上面如果指標想要列印變數a的值,需要解引用操作:printf(「%dn」, *b);變數名實際上只是給程式設計師看的,編譯後的**中並不存在變數名;
指標變數就是乙個變數儲存了另外乙個變數的位址,系統也會為他分配記憶體空間來儲存這個位址;
引用實際是變數的別名,他跟變數有相同的位址。
我對「使用者產生內容」產生了懷疑
本文 最近一段時間,我一直在反思。反思的結果是我開始越來越懷疑 使用者產生的內容 的商業價值。我現在繞不過去的一道坎是個特別簡單的問題 我為什麼要去關心大街上隨便乙個張三李四王二麻子的日常生活?我得閒到什麼程度才能有時間去看乙個完全不認識的人 除非他 她已經成為某種意義上的公眾人物 的搞笑搞怪或者激...
用php mysql批量產生啟用碼
第一次寫這種程式的時候表示相當蛋疼,因為光靠隨機數不能保證批量產生的時候不重複,也許可以從 控制,不過這牽扯到字串的比對 操作起來還是蠻麻煩的,而且相當耗記憶體,控制,又不耗記憶體那是大神們的事了,但是如果加上資料庫本身的功能,就可以讓這個工作變得相當easy了。因為在資料庫中可以把字段屬性設定成u...
用php mysql批量產生啟用碼
第一次寫這種程式的時候表示相當蛋疼,因為光靠隨機數不能保證批量產生的時候不重複,也許可以從 控制,不過這牽扯到字串的比對 操作起來還是蠻麻煩的,而且相當耗記憶體,控制,又不耗記憶體那是大神們的事了,但是如果加上資料庫本身的功能,就可以讓這個工作變得相當easy了。因為在資料庫中可以把字段屬性設定成u...