1. 程式人生 > ><C和指針---讀書筆記6>

<C和指針---讀書筆記6>

返回值 log enter val 其他 9.png 筆記 align eight

指針

指針是一種變量,和int、float、char一樣,是一種基本的變量。只不過它比較抽象一些。

我們知道在C語言中,聲明一個變量a、b,編譯器會為其分配一個物理地址 addr_1 、addr_2,在之後的C語言中,a =1操作,是把數值1存入該 addr_1,就等價於a值變為1。b = b+1 ,是先讀取 addr_2的內容,加1操作後,再寫會 addr_2內。

可以這樣理解: 變量出現在 =右側,一般是 讀 addr_x的內容,變量是左值,一般是 存入 addr_x。 在C語言中變量實質上就是 物理地址的代號。對變量名的操作本質上就是對 物理地址的操作。

所以 a =1 ,b=b+1,都無非是 地址的讀寫操作。 像float、int、char這類變量,變量名等價於物理地址,a = "address 1" b= "address 2"

訪問a就是訪問 address1. address1/2裏面的內容就是a、b的值,沒有其他特別的意義。

int *p 聲明了一個指針變量p, 依然存在 p = "address 3" 的映射。但是p裏面的內容是一個特別得信息。它是地址 "address n“。

C語言使用 *p 間接的訪問 ”address n“ 使用p訪問 "address 3",

聲明和初始化

(1) int *p ; p = &a (2) float *p = &b ;

方法1,首先聲明p是一個 "指向int"的指針變量。 然後 p = &a ,把a的地址,存入 p內。 即 p內存儲的值 = address_a

方法2, 聲明p是一個 "指向float"的指針變量。 是一個縮寫形式。

一定要理解: 變量p自己有一個物理地址addr_p,只不過(addr_p) = &a.

未初始化和非法指針

因為我們經常需要對 指針變量進行間接訪問,一定要保證指向的地址是一個安全可靠的。比如指針變量指向了一個未知的地址,後續盲目的

對該地址進行間接讀寫,很可能出現大問題。所以要保證指針--->安全地址。

非常可惜的是: 編譯器對於未明確指定的指針變量不會進行分配。那我們分配到哪?最好有一個 絕對安全的地址供我們使用。

NULL指針: NULL值在stdio.h文件有明確 #define NULL ( (void *) 0 ) 把整型0強制轉為指針型,並指向void類型數據。

int *p = NULL ; int *p = (void *) 0 相當於 指針變量p = 0,並指向了 void。

指針變量的間接訪問 和直接訪問

int *p = &a ; 這時候 p = 10 ;這是非法的,本質原因是: 10是整型變量,p是 指針型變量,不能對等。 可以 p = (int *) 10; 把10也變為

指向整數的指針變量。

&p: 同樣對變量p取地址,獲得的是p的物理地址。該操作合情合法。

*p : 左值,表示存入 (P)----> address 內。 右值,取(P)----> address內的數據。

* &a = 25 , 即 * (address a) = 25 即存入 a地址內。

指針的指針

既然指針是一個變量,自己擁有自己的地址,那完全可以再用指針指向它,。 這就是指向指針的指針,簡稱指針的指針

技術分享

怎麽聲明? int **pp ;

怎麽表明指向的規則? int *p = &a ; int **pp = &p 即可。

那麽如何通過指針的指針 訪問 整型變量a?

pp = &p

*pp 是對 指針變量p的間接操作。 *p 是完成對 整型a的間接訪問。

**pp 才是最終對a的間接訪問。

指針表達式實例

Char ch =’a’;

Char *cp = &ch;

表達式形式

左值

右值

&ch

獲得ch變量的地址

cp

修改cp的內容,則指向位置將會變化

讀取cp的內容,即獲得某個間接地址

&cp

獲得指針變量cp自己的地址

*cp

把數據存入 間接地址內

獲取 間接地址 的內容

*cp+1

非法

獲取 間接地址 的內容,並加1操作

*(cp+1)

把數據存入 (間接地址+1)內

獲取 (間接地址+1) 的內容,

++cp

非法

Cp值加1,再返回新cp值,

同時 指針的指向位置變化

Cp++

Cp值加1,返回舊cp值

同時 指針的指向位置變化

*++cp

把數據存入(間接地址+1)內,

同時 指針的指向位置變化

獲取 (間接地址+1) 的內容,

同時 指針的指向位置變化

*cp++

因為返回的是舊cp值,故而

把數據存入(間接地址)內,

同時指針的指向位置變化

因為返回的是舊cp值,故而

獲取 間接地址 的內容

同時,指針的指向位置變化

++*cp

獲取 間接地址 的內容,+1之後,返回值

指針的指向位置不會變化

(*cp)++

獲取 間接地址 的內容,並返回。

指針的指向位置不會變化

++*cp++

獲得間接地址 的內容+1,並返回

指針的指向位置變化

++*++cp

獲得 間接地址+1 的內容,並對其加1,再返回,

指針的指向位置變化

這只是一個表格,描述了各種運算的結果。只為加深理解。

指針的運算

指針變量主要用於 間接操作,一般對指針變量本身的操作,並不是很多,主要就是加法運算。

float a[10] ;

float *p = a;

定義了一組浮點型數組,並把數組首地址賦給p。我們知道一個float 型會占用 4 bytes空間。

技術分享

P = Address_of_a[0]. 如果我們執行p+1,本質上是想 P = Address_of_a[1]. 那麽p+1 應該是 p + 1* sizeof(float)

慶幸的是,C編譯器為我們進行了這個處理,使得我們可以更加方便的使用指針變量+1.

這也是我們聲明指針時,為什麽要說明指針指向的是什麽數據類型。它其實是為了編譯器處理 sizeof(xxx)操作、

<C和指針---讀書筆記6>