本文爲原創,歡迎轉發!數組
最近在研讀C primer plus 5版中文版,老外寫的,仍是很經典的,推薦給讀者們,有須要的朋友能夠在這裏購買:C primer plus 5版中文版函數
指針,傳說中是C語言中的一個難點,且是難點中的難點。本文在教材的基礎上,再詳細地談談「指針」這個東東,力爭讓你們能理解它。操作系統
1、指針的概念指針
關於指針的定義,不少教材通常給出「它是一個地址」,「存儲的是變量的地址」,「指向了一個值」等等描述。這樣描述其實也沒錯,可是就是不那麼好理解。我以爲要理解指針,無需給出什麼定義,只需講透以下5個點,我認爲基本就能夠理解一個指針了。這5個點我總結以下:code
1. 指針是一個普通的變量;blog
2. 既然指針是變量,那麼確定有本身的類型;ip
3. 既然指針是變量,那麼確定有本身的值;內存
4. 只不過指針的值跟通常變量的值不太同樣,指針的值是一個「地址」。get
5. 指針指向的數據string
爲了講透這5個點,下面列舉一段代碼,以下。
2、代碼來講明
請欣賞如下代碼
#include <stdio.h> #include <string.h> int main(void) { char string[15] = "ShiXP love C!"; char c = string[0]; char *pointer; pointer = &string[0]; printf("指針pointer的值是%p \n", pointer); for(int index = 0;index < strlen(string); index++) { printf("第%d個字符是:%c \n", index + 1, *(pointer + index)); } return 0; }運行結果是:
3、下面結合代碼我來談談那5個點:
1. 指針是一個普通的變量
本例中,有一個字符變量「c」,它的值是string[0],也就是「S」,這個你們都很好理解。
還有一個指針「pointer」,注意,它也是一個變量,和字符「c」同樣,就是一個普通的變量而已,它也有一個值,它的值是「&string[0]」,從運行結果來看,就是「0022FED9」,這是一個16進制的數。
2. 指針本身的類型
本例中,字符變量「c」的類型是「char」,數組string的類型也是「char」,那麼指針「pointer」的類型也是「char」。不過與c和string的類型char相比,pointer類型的char卻有一點小區別。
變量c的類型char說明了c的值「S」是一個字符數據,數組string的類型char說明了其每個數組元素也是字符數據,可是指針pointer的類型char是否是也說明「0022FED9」是一個字符數據呢?傻子都知道固然不是啦!那麼pointer的char類型究竟是在說誰呢?這就是指針的一個詭異的地方。等講完第5點指針指向的數據你就知道了。
3. 指針本身的值
上面已經說了,指針既然也是一個變量,那麼確定有本身的值,在本例中,指針本身的值就是「0022FED9」,是一個16進制的數,這個值哪來的?是「&string[0]」賦予給指針的。
「0022FED9」這個東東也是不少教材中提到的「地址」。不少人會想,你告訴我「0022FED9」是一個值我還好理解,你告訴我它仍是一個什麼地址,這就讓人暈菜了,下面第4點就來講說這個「0022FED9」。
4. 指針的值
不知你們發現沒有,在C程序中,若是定義了int,char等變量,那麼在代碼中不少地方都會用到這些變量的值。好比在本例中,定義了數組string,則接下來的代碼就用到了數組的元素,也就是printf函數輸出來。若是定義了一個指針變量,可能你們不多看到在代碼中會用到指針的值,好比在本例中,你們就沒有看到用到「0022FED9」。
確實,相比通常類型變量的值被頻繁使用而言,指針的值不多會被直接用到。注意,這裏說的不多被直接用到,是指寫代碼的人,也就是程序猿會不多用到,但有一個角色用指針的值用的很是多,就是操做系統。
好比在本例中,輸出數組的每個元素時,我表面上是用的*(pointer + index)來輸出的,其實在背後,操做系統在執行這個語句時,都是利用指針的值「0022FED9」來找到數組的每個元素的,因此程序最終能正確輸出數組的每個字符。
上面也說了,「0022FED9」是被系統用的最多,爲啥被系統用的最多呢?由於「0022FED9」是一個地址,是string數組的第一個元素「S」的地址。說的再通俗一點,字符「S」放在一個大小爲1BYTE的內存塊裏,這個內存塊的地址就是「0022FED9」。
5. 指針指向的數據
在第4點說到,字符「S」放在一個大小爲1BYTE的內存塊裏,這個內存塊的地址就是「0022FED9」,那麼,咱們就說,指針「pointer」的值是「0022FED9」,在地址爲「0022FED9」的地方放了一個字符「S」,這個「S」就是指針「pointer」指向的數據,且經過「*pointer」這種寫法來獲取「S」,從某種意義上來講:
pointer 等於 0022FED9;
*pointer等於「S」,加上*號,就是直搗黃龍,拿到「S」。
此時咱們能夠說說第2點中提到的指針的類型是來修飾誰的問題了。在本例中,pointer的類型char顯然不是來修飾「0022FED9」的,它是來告訴操做系統,我pointer認爲「0022FED9」這個地方存放的是字符,是字符,是字符,且佔1個BYTE的大小。
若是pointer的類型改成int,我pointer就認爲「0022FED9」這個地方存放的是整數,是整數,是整數字符,且佔4個BYTE的大小。