如何系統學習C 語言(中)之 指標篇
談到指標,我們可能會想到鐘錶上的指標,但這裡的指標不是現實生活中看得見摸得著的鐘表上的指標,c 語言中的指標只存在於邏輯思維中,物理上並不存在。
同時,指標也是C 語言中最精華的部分,通過靈活地運用指標,可以寫出獨具匠心、構思巧妙的程式。
指標基礎
c 語言中指標的實質就是地址
記憶體地址
對於計算機中的記憶體,都會以位元組為單位,逐一地編上號碼,這個編號就是記憶體的地址,如下圖:
圖中,按位元組給記憶體依次編上了號碼,其中每個數字對應著1位元組的記憶體空間,而數字就是記憶體的地址。
取地址運算子"&"
C 語言中,可以用"&"符號來獲取一個變數的記憶體地址。只要在變數名前加上"&"符號就可以獲取變數名所表示的記憶體地址。當獲取到變數的記憶體地址後,就相當於得到了一個指向該變數的指標。簡單的總結一下:
&變數名 == 該變數的記憶體地址 == 指向該變數的指標
解引用運算子“*”
既然可以通過取地址符獲取一個指向變數的指標。那怎麼通過這個指標再找回原來的變數呢?
這時候就有了一個和取地址相逆的操作,我們把它稱為解引用,解引用需要用到星號“ * ” ,它的使用格式為:
*指標
另外,C 語言中,還允許定義專門用於儲存記憶體地址型別的變數,我們將其稱為地址變數,又被稱為指標變數。
指標、指標變數與記憶體地址小區分
首先記憶體地址是記憶體單元的一個編號,可以把它當成一個常量看待;指標變數是一個能夠存放記憶體地址的容器,它是一個變數;指標是無形的,我們可以把它想象成一個帶箭頭的長線,線尾連著指標變數,而箭頭指向了指標變數所儲存的記憶體地址處的資料
指標進階淺談
由於指標學起來涉及的內容比較多,難度相比其他的也較大,所以下面我只是簡單的談一談指標變數、指標與陣列,指標與字串、指標與函式、二級指標,權且當做給大家提個醒,理一理邏輯,要具體學習還得自己再程式設計實戰中去體悟。
1,指標變數
指標變數也是變數的一種,但它與普通變數有所不同,普通變數儲存的是資料,指標變數儲存的是記憶體地址。
//指標變數的定義格式
資料型別 *變數名;
定義指標變數後,不要直接去使用,因為使用賦予確定記憶體地址的"野指標"可能會出大問題。
2,指標與陣列
C 語言中,陣列名所對應的值就是第一個陣列元素的記憶體地址,即可以把陣列名看為指向陣列首元素的指標。通過下面程式碼片段理解:
int a[3]={10,20,30};
printf("The first element value: %d\n",*a); //輸出為:The first element value: 10
還有什麼很多諸如陣列指標,指標陣列等等各種定義,我覺得單純的記他們沒有什麼必要,本身用的就不多,就算到了用的時候,直接問問”度娘“就ok 了
3,指標與字串
字串是常量,常量是C 語言中最簡單的表示式,而所有的表示式都是有值的,那字串常量的值是什麼呢?字串常量的值就是字串中首字元的記憶體地址。例如 apple 這個字串常量的值就是第一個字元 a 的記憶體地址。因此我們可以用一個char 型別的指標來指向這個字串。
char *ptr = "apple";
4,指標與函式
函式時擁有特定功能的語句的集合,是構成程式的基本模組。在函式的定義過程中,可以將指標作為函式的引數,也可以將指標作為函式的返回值,甚至可以用指標來指向一個函式。
限於篇幅限制,這裡就簡單的提示一下,具體的區別或找一些具體例子來體會,大家很容易在網上搜集到的~ ~。
5,二級指標
所謂的二級指標就是指向指標的指標。其定義格式如下:
資料型別 **變數名
指標的實質就是記憶體地址,由於指標變數是可以儲存記憶體地址的變數,因此也可將其視作指標。而指標變數本身也是變數,需要佔用記憶體空間,因此也有記憶體地址。如果將這個記憶體地址在儲存到另一個指標變數中,就形成了一個指向指標的指標,即指向指標的指標就是二級指標。
定義好二級指標後就需要對它進行初始化與賦值了
int a = 10; //定義一個int 型別的變數a,並初始化為10
int *pi = &a; //定義一個int 型別的指標變數pi,並初始化其值為a 的記憶體地址
有了指標變數pi ,下面就可以定義一個二級指標並對其進行初始化了,如下:
int **ppi = π //定義二級指標ppi,並通過取地址符獲取指標變數pi 的記憶體地址,將其初始化給二級指標ppi
6,特殊指標
指標是C 語言的精髓和靈魂。其中有兩種相對特殊的指標,一個是空指標,另一個是void 型別的指標。
int *pi=NULL; //空指標
void *pv; //void型別的指標,任何型別的指標都可以被隱式地轉換為void型別的指標。因此,它通常作為函式的引數出現。