理解C 的指標

2021-08-21 08:14:50 字數 2120 閱讀 2732

本文是新手零基礎學習c++對指標、陣列和結構的理解和筆記,有些凌亂和語無倫次,只是將想法記錄下來,在以後忘了或者概念不清的時候看看。如理解有誤,敬請各位請前輩不吝指教,不勝感激。

在c++基礎教程中指標一般被定義為:存放位址的變數。

我們可以把指標變數看做乙個向量,它有大小(sizeof 運算子可查位元組),有方向(從棧出發,指向堆的乙個位址)。宣告指標,就是為它指定大小;指標的賦值,就是給它指定方向。指標的大小並不是真的佔了多大空間,而是由它的型別來決定大小,例如存放乙個位元組 char 型別的字元指標,佔據的記憶體空間為 4 位元組(32位)。

指標在賦值時用引用 & 加乙個變數,所以引用是右值,它僅僅是乙個變數的位址;指標是左值也可以是右值,它不僅僅是乙個位址,還包括了位址所指資料所佔空間的大小。所以,引用可以被看為是半指標,或者叫單位向量,有方向沒大小的指標。

理解了指標,在函式的引數傳遞中,傳值、傳引用、傳指標概念就清楚了。

函式值傳遞就是右值傳遞,由被調函式的形參來接收右值,建立主調函式中變數的乙個副本,可以理解為形參的「例項化」。有時候右值很大,比如讀取乙個10mb檔案第80個位元組處儲存的 8 位元組資料。在形參例項化時,被調函式將在記憶體中建立乙個10mb檔案的拷貝,這將非常浪費時間,此時就需要傳引用。傳引用只需要將這個檔案的首位址傳遞給被調函式,由函式將這個位址向後偏移80個位元組,再讀入8位元組資料即可。這樣操作,程式的開銷會非常小,cpu對付的都是位元組級別的運算,而不是10mb(十億位元組)的運算。這就是在lisp中用activex物件操作大檔案的效率,遠低於dwx讀入檔案效率的原因,因為dwx直接傳遞位址給windows api,在被調函式中偏移這個位址即可讀入需要的資料。由於傳引用沒有建立副本,所以如果改變了形參的值,也就改變了實參的值。相當於在主調和被調函式中建立了乙個雙向資料通道,而值傳遞是單項的。

引用傳遞和指標傳遞容易混淆的地方,他們的效果幾乎相同,具有引數傳遞的雙向性,具有引數傳遞的高效性–傳遞的內容都是位址。區別是傳指標就相當於全域性變數,在被調函式對指標的任何操作,和在主調函式中操作變數沒有區別;而傳引用,僅僅傳遞的是位址,位址可以進行偏移運算,但不能對主調函式中的變數直接操作,需要時還得按位址載入固定位元組的資料,建立副本後進行間接操作,因為引用只是半指標,它沒大沒小。

另外指標可以為null,即有大小沒方向;而引用不能為空,它本身沒大小,再沒有方向就什麼也不是了。指標是左值,引用是右值,右值可以賦值給左值,左值不能複製給右值。

棧屬於cpu的快取記憶體,比記憶體快1000倍,被優化為兩個指令:壓入和彈出。它的空間有限,分配給乙個執行緒的空間更加有限。函式指標和引用傳遞一次,佔據了乙個單位棧空間,當函式呼叫完畢原路返回後,才會釋放棧空間。但是在遞迴呼叫時,未達到遞迴終止條件前,函式不會原路返回,占用的棧空間也不會釋放,所以遞迴函式巢狀或迴圈次數超過一定數量,就會出現堆疊溢位的錯誤。windows 棧空間一般為 2mb,乙個位址佔據 8 位元組(64位),所以遞迴迴圈的次數一般不會超過 200000/8 的上限,棧空間分配給函式的大小可以調整。

理解了指標,可以用位址的偏移來直接遍歷多維陣列和結構。陣列和結構在記憶體裡是按一維連續儲存的,所以指標也是連續的。陣列和結構的指標指向第乙個資料的位址,這裡為什麼不說是陣列的引用,因為這個位址每增加1,就會指向陣列或結構的下乙個值,說明這個位址具有大小的屬性,那麼它就是指標。如果是引用,引用增加1(向右偏移1)只是指向記憶體的下乙個位元組,乙個 int 型別的資料,佔 4 個位元組,需要引用 + 4 的操作才能相當於指標 +1,而指標 +1 不必關心資料型別,它總是指向下乙個資料單元(堆空間的儲存是從低位址到高位址方向,所以讀取資料是位址的加法操作。)

下面我用一維 for 迴圈來遍歷多維陣列,這樣的好處是不必擔心陣列的越界操作。

#include 

void main()

,,}; //陣列初始化

int* piarry = &iarry[0][0]; //陣列的指標

int lengtharry = sizeof(iarry) / sizeof(piarry); //陣列元素個數

for (int i = 0; i < lengtharry; ++i) //單層for迴圈

//指標+1,遍歷陣列

}

這樣,我們不必關心陣列的維數以及每一維陣列的長度,用指標就可以直接遍歷操作,包括陣列的讀取與儲存。

C 指標的理解

1.記憶體長成啥樣?物理記憶體條由連續排列晶元組構成,在計算機中記憶體模型也被抽象為一組連續的儲存空間,每個空間都能夠儲存若干位元組的資料,每一塊儲存空間也有乙個特定的序號,從0到n。備註 為了便於理解,此處,將記憶體儲存空間橫向排列 實際橫縱排列的意義相同 0000 0001 0002 0003 ...

C 指標的理解

一.c 位址指標的基本概念在計算機中,所有的資料都是存放在儲存器中的。一般把儲存器中的乙個位元組稱為乙個記憶體單元,不同的資料型別所占用的記憶體單元數不等,如整型量佔2個單元,字元量佔1個單元等,在前面已有詳細的介紹。為了正確地訪問這些記憶體單元,必須為每個記憶體單元編上號。根據乙個記憶體單元的編號...

c指標的理解

指標,將某個變數值賦值給指標,實際上就是將這個變數的位址賦值給指標,或者反過來說,指標中儲存了這個變數的記憶體位址,指向了這個變數,通過指標就能找到這個變數。結構體 記憶體對齊 struct data1 struct data2data1佔8位元組,data2佔12位元組,因為data2中b占用了第...