C語言指標詳解

2021-09-16 12:01:43 字數 3766 閱讀 4180

c語言指標應用

一、指標是什麼

指標是乙個特殊的變數,它存的是記憶體裡的乙個位址。

指標四要素:

1.指標的型別

把指標名字去掉,剩下的部分就是這個指標的型別。這是指標本身所具有的型別如下:

(1)int * p;//指標的型別是int *

(2)char * p;//指標的型別是char *

(3)int * * p;//指標的型別是int * *

(4)int( * p)[3];//指標的型別是int( * )[3]

(5)int * ( * p)[4];//指標的型別是int * ( * )[4]

2.指標所指向的型別

從語法上看,你只須把指標宣告語句中的指標名字和名字左邊的指標宣告符 * 去掉,剩下的就是指標所指向的型別。例如:

(1)int * p; //指標所指向的型別是int

(2)char * p; //指標所指向的的型別是char

(3)int * * p; //指標所指向的的型別是int *

(4)int( * p)[3]; //指標所指向的的型別是int()[3]

(5)int * ( * p)[4]; //指標所指向的的型別是int * ()[4]

在指標的算術運算中,指標所指向的型別有很大的作用。

3.指標的值----或者叫指標所指向的記憶體區或位址

指標的值是指標本身儲存的數值,這個值將被編譯器當作乙個位址,而不是乙個一般的數值。

指標所指向的記憶體區就是從指標的值所代表的那個記憶體位址開始,長度為sizeof(指標所指向的型別)的一片記憶體區。

如果說指標的值是a,就相當於說該指標指向了以a為首位址的一片記憶體區域;說指標指向了某塊記憶體區域,就相當於說該指標的值是這塊記憶體區域的首位址。

每看**每遇到乙個指標,都應該想到:這個指標的型別?指標指的型別?該指標指向了**?(重點注意)

4 指標本身所佔據的記憶體區

指標本身佔了多大的記憶體?你只要用函式sizeof(指標的型別)測一下就知道了。在32 位平台裡,指標本身佔據了4 個位元組的長度。指標本身佔據的記憶體這個概念在判斷乙個指標表示式是否是左值時很有用。

二、指標的算術運算

指標可以加上或減去乙個整數。指標的這種運算的意義和通常的數值的加減運算的意義是不一樣的,以單元為單位。例如:

例:char a[20];

int * ptr=(int * )a; //強制型別轉換並不會改變a 的型別

ptr++;

在上例中,指標ptr 的型別是int * ,它指向的型別是int,它被初始化為指向整型變數a。接下來的第3句中,指標ptr被加了1,編譯器是這樣處理的:它把指標ptr 的值加上了sizeof(int),在32 位程式中,是被加上了4,因為在32 位程式中,int 佔4 個位元組。由於位址是用位元組做單位的,故ptr 所指向的位址由原來的變數a 的位址向高位址方向增加了4 個位元組。由於char 型別的長度是乙個位元組,所以,原來ptr 是指向陣列a 的第0 號單元開始的四個位元組,此時指向了陣列a 中從第4 號單元開始的四個位元組。我們可以用乙個指標和乙個迴圈來遍歷乙個陣列,看例子:

例:int array[20]=;

int * ptr=array;

for(i=0;i<20;i++)

這個例子將整型陣列中各個單元的值加1。由於每次迴圈都將指標ptr加1 個單元,所以每次迴圈都能訪問陣列的下乙個單元。

總結一下:

乙個指標ptrold 加(減)乙個整數n 後,結果是乙個新的指標ptrnew,ptrnew 的型別和ptrold 的型別相同,ptrnew 所指向的型別和ptrold所指向的型別也相同。ptrnew 的值將比ptrold 的值增加(減少)了n 乘sizeof(ptrold 所指向的型別)個位元組。就是說,ptrnew 所指向的記憶體區將比ptrold 所指向的記憶體區向高(低)位址方向移動了n 乘sizeof(ptrold 所指向的型別)個位元組。

三、運算子&和 *

這裡&是取位址運算子, * 是間接運算子。

&a 的運算結果是乙個指標,指標的型別是a ,指標所指向的型別是a 的型別,指標所指向的位址嘛,那就是a 的位址。

四、指標表示式

乙個表示式的結果如果是乙個指標,那麼這個表示式就叫指標表式。

下面是一些指標表示式的例子:

例:int a;

int * pa;

pa=&a; //&a 是乙個指標表示式。

int * * ptr=&pa; //&pa 也是乙個指標表示式。

當乙個指標表示式的結果指標已經明確地具有了指標自身佔據的記憶體的話,這個指標表示式就是乙個左值,否則就不是乙個左值。在例七中,&a 不是乙個左值,因為它還沒有佔據明確的記憶體。

五、陣列和指標的關係

陣列的陣列名其實可以看作乙個指標。看下例:

例:int array[10]=,value;

value=array[0]; //也可寫成:value= * array;

value=array[3]; //也可寫成:value= * (array+3);

value=array[4]; //也可寫成:value= * (array+4);

陣列指標:指向陣列的指標

例:int ( * p)[10] p 是指向陣列的指標

指標陣列: 陣列的元素都是指標。

例:char * str[3]=;

上例中,str 是乙個三單元的陣列,該陣列的每個單元都是乙個指標,這些指標各指向乙個字串。把指標陣列名str 當作乙個指標的話,它指向陣列的第0 號單元,它的型別是char * * ,它指向的型別是char * 。

六、指標和結構型別的關係

可以宣告乙個指向結構型別物件的指標。

例:struct mystruct

;struct mystruct ss=;

//宣告了結構物件ss,並把ss 的成員初始化為20,30 和40。

struct mystruct * ptr=&ss;

//宣告了乙個指向結構物件ss 的指標。它的型別是

//mystruct * ,它指向的型別是mystruct。

通過指標ptr 來訪問ss 的三個成員變數?

答案:ptr->a; //指向運算子,或者可以這們( * ptr).a,建議使用前者

ptr->b;

ptr->c;

七、指標和函式的關係

函式指標:

其本質是乙個指標變數,該指標指向這個函式。總結來說,函式指標就是指向函式的指標。

宣告格式:型別說明符 ( * 函式名) (引數)

如下:int ( * fun)(int x,int y);

函式指標是需要把乙個函式的位址賦值給它,有兩種寫法:

fun = &function;

fun = function;

指標函式:

就是乙個返回指標的函式,其本質是乙個函式,而該函式的返回值是乙個指標。

宣告格式為: * 型別識別符號 函式名(參數列)

看看下面這個函式宣告:

int fun(int x,int y);

這種函式應該都很熟悉,其實就是乙個函式,然後返回值是乙個 int 型別,是乙個數值。

接著看下面這個函式宣告:

int * fun(int x,int y);

這和上面那個函式唯一的區別就是在函式名前面多了乙個 * 號,而這個函式就是乙個指標函式。其返回值是乙個 int 型別的指標,是乙個位址。

指標函式的寫法

int * fun(int x,int y);

int * fun(int x,int y);

int * fun(int x,int y);

八、指標的安全問題

注意指標四要素要符合。

c語言指標詳解

一.指標的概念 指標是乙個特殊的變數,它裡面儲存的數值被解釋成為記憶體裡的乙個位址。要搞清乙個指標需要搞清指標的四方面的內容 指標的型別,指標所指向的型別,指標的值或者叫指標所指向的記憶體區,還有指標本身所佔據的記憶體區。1.指標的型別 從語法的角度看,你只要把指標宣告語句裡的指標名字去掉,剩下的部...

C語言指標詳解

類似於 int p char p 或者自定義型別的 person p struct p 這些都是基本的指標變數,不管什麼型別的指標變數都是乙個存位址的變數,所以它們的大小都是四個位元組 還有一種void p 型別,類似於 js 或者 c 的 var 可以傳入任何型別變數的位址,也可以轉換成任何型別變...

C語言指標詳解

以下講解是按照如下這個程式的執行順序來講解的 int a,b 這是乙個普通的整型變數 int p 這是乙個整形的指標 a 3 b 4 指標p定義的時候沒有進行初始化,所以在這裡,p的初始值是不確定的。當然也可以在p定義的時候賦初值,這樣p的初始值就是確定的了。p 1 一元運算子 可用於取乙個物件的位...