C語言指標剖析一 指標的宣告與訪問

2021-10-11 01:31:31 字數 2927 閱讀 4743

前言

1:指標的定義

2:指標變數

2.1:const關鍵字

3:指標的指標

在計算機中,所有的資料都是存放在儲存器中的,一般把儲存器的乙個位元組稱為乙個記憶體單元。不同的資料型別占用的記憶體單元是不同的。為了快速、準確的訪問這些記憶體單元,計算機為每乙個記憶體單元進行編號,記憶體單元的編號也就是記憶體單元的位址。c 語言中,把這個位址叫做指標。

指標的宣告:型別 * 指標變數名;//如 int * pnum;「*」表示語句宣告的是乙個指標變數,型別指定了指標所指的記憶體單元的資料型別。可以將int*理解成一種復合型別,是指向 int 型資料的指標。

指標的初始化:宣告指標變數時,c 並不會自動對其進行初始化,我們通過取位址符(&)給指標變數賦值是個有效的手段,實際上,可以在宣告乙個指標變數的同時完成其初始化。例如:int num=1; int *pn=#對於無處可指的指標變數,也要將其初始化為 null(即 0,空指標)。如:int *pa = null;

指標的引用:兩個有關的運算子:

1) &:取位址運算子。

2) *:指標運算子(或稱「間接訪問」 運算子)。

既然&inum是指向變數inum的指標,那麼存放指標&inum的變數就是「指標變數」。從根本上來看,指標變數是乙個值為記憶體位址的變數。如果有以下定義:

int inum=0x64;

int *ptr =&inum;

其中,「*」將變數宣告為指標,這是乙個過載過的符號。顯然,過載就是為某個操作符定義新的含義,因為*用於乘法和間接訪問或解引用指標時,其意義完全不一樣。

inum變數設定為0x64,在宣告ptr的同時將它初始化為inum的位址。當宣告乙個指標時,僅僅只是為指標本身分配了空間,並沒有為指標所引用的資料分配空間。通常該宣告被解讀為ptr是指向int的變數inum的指標,「int*」型別名被解讀為指向int的變數inum的指標型別。雖然ptr與&um的值相等,但它們的型別不一樣。ptr的型別為int*,&inum的型別為int*const即&inum是乙個指向非常量的常量指標,雖然指標不可變,但它所指向的資料可變。比如:

int inum =0x64;

int const ptr=&inum;

有了這個宣告,則ptr必須被初始化為指向非常量變數,雖然不能修改ptr,但可以修改ptr指向的資料。如果試圖初始化ptr使其指向常量num,則ptr就成為了乙個指向常量的指標,即不能通過指標修改它所引用的值。比如:

const int inum =0x64;

int * const ptr = &inum;

這樣的話就會出現乙個警告,因為常量不能被修改

雖然指標&inum是指記憶體位址本身,指標變數ptr是指儲存記憶體位址的變數,但兩者之間的區別並不重要。因為傳遞乙個指標變數給函式,其實就是在傳遞該指標的值一—記憶體地

址。通常在討論乙個記憶體位址時,將它稱為位址;而在討論乙個儲存記憶體位址的變數時,才會將它稱為指標。當乙個變數儲存另乙個變數的位址時,通常會說它指向了某個變數。

無論怎樣, const修飾的是緊跟在它後面的單詞。比如,使用「const int a[2]=;是將陣列a的元素修飾為唯讀(它的值保持不變),而不是將變數a修飾為唯讀。注意,int const與 const int是等價的。既然可以用 const修飾變數,當然也可以用 const修飾指標變數。比如,「char* const src」是將src自身修飾為唯讀,而「const char* const src」是src和src指向的物件(變數的值)都修飾為唯讀。此外還有 const char*sc和 char const*src,其效果是一樣的。注意,當指標作為傳遞引數時, const常用於將指標指向的物件設定為唯讀。注意,唯讀變數與指令一起儲存在「唯讀段」中,而變數儲存在「讀寫段」中。具有儲存器保護功能的作業系統可能將唯讀段保護起來,不讓程式修改值。類似 cortex--m0+這樣的mcu,其唯讀段與讀寫段是分別分配在 flash與ram中的,因此無法改變唯讀變數的值。由於 flash比ram便宜很多,且容量大很多,因此建議盡量將變數定義為唯讀變數,以達到節省儲存空間的目的。

有如下定義:

int inum =0x64;

int *ptr =&inum;

當在「int*ptr;」定義前新增 typedef:

typedef int *ptr;

此時,ptr等同於int*。為了便於理解,通常將型別名ptr替換為ptit比如:

typedef int *ptr_int;

顯然有了 ptr int型別,即可構造指向 ptr int型別的指標變數pptr.即

其中,pptr是指向ptrnt*的指標變數,ptr_int的型別為int*,pptr是指向int**的指標變數,那麼pptr就成了儲存int型ptr位址的雙重指標

其中,指標的型別為int**,指標指向的物件的型別為int*,只要看到*就應該想到指標變數。由於*的結合方式是從右到左的,該定義相當於:

int * *pptr)=&ptr;

即*pptr是乙個一級指標變數。接著第乙個*與(*ptr)結合成為「一級指標變數」,這同樣是在定義乙個指向指標型別資料的指標變數,即二級指標變數。在雙重指標變數前,既可加乙個或兩個指標運算子*,也可以加取位址運算子&。則以

下關係恆成立:

*pptr ==*(&ptr) == ptr == &inum

**pptr == *ptr == *(&inum) == inum

c語言與指標 (一)指標與變數

寫在前面 指標是學習c語言時,最讓人頭痛的乙個難題。但是指標不僅是c語言的精髓,它還貫穿整個計算機底層儲存與訪問方式。指標實際上就是位址,指標變數用來存放指標 位址 指標變數也是一種變數,它和不同的變數同樣要佔一定的儲存空間。但指標變數與不同的變數不同之處在於,指標的儲存空間存放的不是不同的資料,而...

c語言指標初探 一 指標與陣列

一 陣列名指標 c 編譯器將陣列名解釋為指標 include using namespace std int main cout sz 編譯器將陣列名解釋為陣列記憶體區域的首位址,對一維陣列來說要實現對某個元素的訪問,既可以用陣列名 下標的形式,也可以用間接引用 陣列名 偏移 陣列元素的指標形式 指...

C語言指標初探 一 指標與函式

1.通過指標引數申請動態記憶體。2 利用函式返回值申請動態記憶體。3 返回棧記憶體的 或靜態儲存區的 指標或引用。以上知識請參考 記憶體管理。4 函式引數的三種傳遞方式 1 值傳遞 這個應該簡單吧,來看個經典程式 include include using namespace std void sw...