指標的應用方法

2021-06-17 20:33:55 字數 2907 閱讀 1517

指標是乙個特殊的變數,它裡面儲存的數值被解釋成為記憶體裡的乙個位址。 要搞清乙個指標需要搞清指標的四方面的內容:指標的型別,指標所指向的 型別,指標的值或者叫指標所指向的記憶體區,還有指標本身所佔據的記憶體區。讓我們分別說明。 先宣告幾個指標放著做例子:

例一: (1)int*ptr; (2)char*ptr; (3)int**ptr; (4)int(*ptr)[3]; (5)int*(*ptr)[4];

如果看不懂後幾個例子的話,請參閱我前段時間貼出的文章《如何理解c和c ++的複雜型別宣告》。

指標的型別 從語法的角度看,你只要把指標宣告語句裡的指標名字去掉,剩下的部分就是這個指標的型別。這是指標本身所具有的型別。讓我們看看例一中各個指標的型別:

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

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

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

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

//指標的型別是int*(*)[4] 怎麼樣?找出指標的型別的方法是不是很簡單?

指標所指向的型別 當你通過指標來訪問指標所指向的記憶體區時,指標所指向的型別決定了編譯器將把那片記憶體區里的內容當做什麼來看待。 從語法上看,你只須把指標宣告語句中的指標名字和名字左邊的指標宣告符*去掉,剩下的就是指標所指向的型別。

例如: (1)int*ptr;//指標所指向的型別是int

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

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

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

/指標所指向的的型別是int*()[4] 在指標的算術運算中,指標所指向的型別有很大的作用。 指標的型別(即指標本身的型別)和指標所指向的型別是兩個概念。

當你對c越來越熟悉時,你會發現,把與指標攪和在一起的"型別"這個概念分成"指標的型別"和"指標所指向的型別"兩個概念,是精通指標的關鍵點之一。

指標的值,或者叫指標所指向的記憶體區或位址 指標的值是指標本身儲存的數值,這個值將被編譯器當作乙個位址,而不是乙個一般的數值。在32位程式裡,所有型別的指標的值都是乙個32位整數,因為32位程式裡記憶體位址全都是32位長。

指標所指向的記憶體區就是從指標的值所代表的那個記憶體位址開始,長度為si zeof(指標所指向的型別)的一片記憶體區。以後,我們說乙個指標的值是xx,就相當於說該指標指向了以xx為首位址的一片記憶體區域;我們說乙個指標指向了某塊記憶體區域,就相當於說該指標的值是這塊記憶體區域的首位址。

指標所指向的記憶體區和指標所指向的型別是兩個完全不同的概念。在例一中,指標所指向的型別已經有了,但由於指標還未初始化,所以它所指向的記憶體區是不存在的,或者說是無意義的。 以後,每遇到乙個指標,都應該問問:這個指標的型別是什麼?指標指的型別是什麼?該指標指向了**? 指標本身所佔據的記憶體區 指標本身佔了多大的記憶體?你只要用函式sizeof(指標的型別)測一下就知道了。在32位平台裡,指標本身佔據了4個位元組的長度。 指標本身佔據的記憶體這個概念在判斷乙個指標表示式是否是左值時很有用。

指標的算術運算 指標可以加上或減去乙個整數。指標的這種運算的意義和通常的數值的加減運算的意義是不一樣的。

例如: 例二: 1、chara[20];

2、int*ptr=a; ... ...

3、ptr++;

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

例三: intarray[20]; int*ptr=array; ...

//此處略去為整型陣列賦值的**。

... for(i=0;i<20;i++) 這個例子將整型陣列中各個單元的值加1。由於每次迴圈都將指標ptr加1,所以每次迴圈都能訪問陣列的下乙個單元。 再看例子:

例四:

1、chara[20];

2、int*ptr=a; ... ...

3、ptr+=5;

在這個例子中,ptr被加上了5,編譯器是這樣處理的:

將指標ptr的值加上5乘sizeof(int),在32位程式中就是加上了5乘4=20。由於位址的單位是位元組,故現在的ptr所指向的位址比起加5後的ptr所指向的位址來說,向高位址方向移動了20個位元組。在這個例子中,沒加5前的ptr指向陣列a的第0號單元開始的四個位元組,加5後,ptr已經指向了陣列a的合法範圍之外了。雖然這種情況在應用上會出問題,但在語法上卻是可以的。這也體現出了指標的靈活性。

讓我們再來看一例:

例十八:

1、chara;

2、int*ptr=&a; ... ...

3、ptr++; 4、*ptr=115;

該例子完全可以通過編譯,並能執行。但是看到沒有?第3句對指標ptr進行自加1運算後,ptr指向了和整形變數a相鄰的高位址方向的一塊儲存區。這塊儲存區里是什麼?我們不知道。有可能它是乙個非常重要的資料,甚至可能是一條**。而第4句竟然往這片儲存區里寫入乙個資料!這是嚴重的錯誤。所以在使用指標時,程式設計師心裡必須非常清楚:我的指標究竟指向了**。在用指標訪問陣列的時候,也要注意不要超出陣列的低端和高階界限,否則也會造成類似的錯誤。

在指標的強制型別轉換:ptr1=(type*)ptr2中,如果sizeof(ptr2的型別)大於sizeof(ptr1的型別),那麼在使用指標ptr1來訪問ptr2所指向的儲存區時是安全的。如果sizeof(ptr2的型別)小於sizeof(ptr1的型別),那麼在使用指標ptr1來訪問ptr2所指向的儲存區時是不安全的。

指標的應用

用指標方式實現計算字串長度 int strlength const char s return count 空字元 0 也有值,為0 字元指標與字元陣列 char p programming 1 定義了乙個字元指標變數p 2 建立了乙個字串常量 programming 是字元陣列,後面有乙個空字元 ...

指標的應用

左值 放在 符號的左邊,使用的是寫許可權 取位址符,例如 a則獲取a的位址 指標 位址 int p 定義乙個整型位址 指標 變數 int p a 等價,int p p a p 100 解引用 指標變數比普通變數只多了乙個解引用的能力 門牌的寬度由房間數量決定 指標的大小 在32位平台,x86,指標4...

指標和指標應用的區別

指標引數的傳遞,傳遞的是對指標的拷貝值,如果在函式中對指標的值進行修改,不會影響到主函式中的值,因為在函式執行完成後,執行這個函式產生區域性變數的棧區就會清空.指標傳遞引數本質上是值傳遞的方式,它所傳遞的是乙個位址值。值傳遞過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在棧中開闢了記憶體...