c語言中的精華是指標,這也是c語言中唯一的難點。
c是對底層操作非常方便的語言,而底層操作中用到最多的就是指標,以後從事嵌入式開發的朋友們,指標將陪伴我們終身。
1.指標型別分析
分析指標,可以從變數名處起,根據運算子優先順序結合,一步一步分析.
int p; //這是乙個普通的整型變數
int *p; //首先從 p 處開始,先與 * 結合, 所以說明 p 是乙個指標,然後再與 int 結合,說明指標所指向的內容的型別為 int 型.所以 p 是乙個返回整型資料的指標
int p[3]; //首先從 p 處開始, 先與結合,說明 p 是乙個陣列, 然後與 int 結合, 說明陣列裡的元素是整型的, 所以 p 是乙個由整型資料組成的陣列
int *p[3]; //首先從p處開始,先與結合,因為其優先順序比*高,所以p是乙個陣列,然後再與*結合,說明陣列裡的元素是指標型別,然後再與int結合,說明指標所指向的內容的型別是整型的,所以是乙個由返回整型資料的指標所組成的陣列
int (*p)[3]; //首先從 p 處開始,先與*結合, 說明 p 是乙個指標然後再與 結合與 "()" 這步可以忽略,只是為了改變優先順序),說明指標所指向的內容是乙個陣列,然後再與 int 結合,說明陣列裡的元素是整型的.所以 p 是乙個指向由整型資料組成的陣列的指標
int **p; //首先從 p 開始,先與 * 結合,說明 p 是乙個指標,然後再與 * 結合,說明指標所指向的元素是指標,然後再與 int 結合,說明該指標所指向的元素是整型資料. 所以 p 是乙個返回指向整型資料的指標的指標
int p(int); //從 p 處起,先與()結合,說明p是乙個函式,然後進入()裡分析,說明該函式有乙個整型變數的引數然後再與外面的 int 結合, 說明函式的返回值是乙個整型資料.所以 p 是乙個有整型引數且返回型別為整型的函式
int (*p)(int); //從 p 處開始,先與指標結合,說明 p 是乙個指標,然後與()結合,說明指標指向的是乙個函式,然後再與()裡的 int 結合,說明函式有乙個 int 型的引數,再與最外層的 int 結合,說明函式的返回型別是整型,所以 p 是乙個指向有乙個整型引數且返回型別為整型的函式的指標
int *(*p(int))[3]; //從 p 開始,先與 () 結合,說明 p 是乙個函式,然後進入 () 裡面,與 int 結合,說明函式有乙個整型變數引數,然後再與外面的 * 結合, 說明函式返回的是乙個指標,然後到最外面一層,先與結合,說明返回的指標指向的是乙個陣列,然後再與*結合,說明陣列裡的元素是指標,然後再與 int 結合,說明指標指向的內容是整型資料.所以 p 是乙個引數為乙個整數且返回乙個指向由整型指標變數組成的陣列的指標變數的函式
2.指標分析
指標是乙個特殊的變數,它裡面儲存的數值被解釋成為記憶體裡的乙個位址。
要搞清乙個指標需要搞清指標的四方面的內容:指標的型別、指標所指向的型別、指標的值或者叫指標所指向的記憶體區、指標本身所佔據的記憶體區。
指標的型別:把指標宣告語句裡的指標名字去掉,剩下的部分就是這個指標的型別
指標所指向的型別:把指標宣告語句中的指標名字和名字左邊的指標宣告符 * 去掉,剩下的就是指標所指向的型別(在指標的算術運算中,指標所指向的型別有很大的作用)
指標所指向的記憶體區:從指標的值所代表的那個記憶體位址開始,長度為sizeof(指標所指向的型別)的一片記憶體區。(乙個指標指向了某塊記憶體區域,就相當於說該指標的值是這塊記憶體區域的首位址)
指標本身所佔據的記憶體區:用函式sizeof(指標的型別)可以測出指標本身所佔據的記憶體區(在 32位平台裡,指標本身佔據了 4個位元組的長度)
3.指標的算術運算
指標和整數進行加減:乙個指標 ptrold加(減)乙個整數 n 後,結果是乙個新的指標ptrnew,ptrnew 的型別和 ptrold 的型別相同,ptrnew 所指向的型別和 ptrold所指向的型別也相同,ptrnew的值將比 ptrold 的值增加(減少)了n乘sizeof(ptrold所指向的型別)個位元組
指標和指標進行加減:兩個指標不能進行加法運算,這是非法操作;兩個指標可以進行減法操作,但必須型別相同,一般用在陣列方面
4. 運算子&和*
&是取位址運算子,*是間接運算子。
&a的運算結果是乙個指標,指標的型別是a的型別加個*,指標所指向的型別是a的型別,指標所指向的位址嘛,那就是a的位址。
*p的運算結果就五花八門了,總之*p 的結果是 p 所指向的東西,這個東西有這些特點:它的型別是 p指向的型別,它所占用的位址是p所指向的位址。
5. 陣列和指標的關係
陣列的陣列名其實可以看作乙個指標。
宣告了乙個陣列 type array[n],則陣列名稱array就有了兩重含義:
第一,它代表整個陣列,它的型別是 type[n];
第二 ,它是乙個常量指標,該指標的型別是type*,該指標指向的型別是type,也就是陣列單元的型別,該指標指向的記憶體區就是陣列第0號單元,該指標自己占有單獨的記憶體區,注意它和陣列第0號單元佔據的記憶體區是不同的。該指標的值是不能修改的,即類似 array++ 的表示式是錯誤的。
6. 指標和結構型別的關係
假設我們定義了乙個結構體,struct mystruct;
同時定義結構體的結構物件並初始化,struct mystructss=;
那麼我們如何通過指標ptr 來訪問 ss的三個成員變數呢?
答案就是,我們先定義乙個指向結構物件 ss的指標,struct mystruct *ptr=&ss; 然後,使用指向運算子->便可實現對結構物件ss成員的訪問。
ptr->a; //或者可以這們(*ptr).a,建議使用前者
ptr->b;
ptr->c;
7. 指標和函式的關係
可以把乙個指標宣告成為乙個指向函式的指標,從而通過函式指標呼叫函式。讓我們舉乙個例子來說明以下吧。
int fun(char *, int);
int (*pfun)(char *, int);
pfun = fun;
int a = (*pfun)("abcdefg", 7);
例中,定義了乙個指向函式fun的指標pfun,把pfun作為函式的形參。把指標表示式作為實參,從而實現了對函式fun的呼叫。
8. 指標型別轉換
當我們初始化乙個指標或給乙個指標賦值時,賦值號的左邊是乙個指標,賦值號的右邊是乙個指標表示式,這就要求兩邊的型別一致,所指向的型別也一致,如果不一致的話,需要進行強制型別轉換。語法格式是:(type *)p;
這樣強制型別轉換的結果是乙個新指標,該新指標的型別是type *,它指向的型別是type,它指向的位址就是原指標指向的位址。要注意的是,原來的指標p的一切屬性都沒有被修改。
另外,乙個函式如果使用了指標作為形參, 那麼在函式呼叫語句的實參和形參的結合過程中,也必須保證型別一致 ,否則需要強制轉換。
9.指標常量和常量指標
常量指標,表述為「是常量的指標」,它首先應該是乙個指標。
指標常量,表述為「是指標的常量」,它首先應該是乙個常量。
常量指標就是指向常量的指標,指標所指向的位址的內容是不可修改的。
指標常量就是是指標的常量,它是不可改變位址的指標,但是可以對它所指向的內容進行修改
C語言指標總結
2012 03 07 07 22 標籤 c語言 分類 pointer c語言中的精華是指標,這也是c語言中唯一的難點。c是對底層操作非常方便的語言,而底層操作中用到最多的就是指標,以後從事嵌入式開發的朋友們,指標將陪伴我們終身。1.指標型別分析 分析指標,可以從變數名處起,根據運算子優先順序結合,一...
C語言指標總結
指標分析 指標的型別 把指標宣告語句裡的指標名字去掉,剩下的部分就是這個指標的型別 指標所指向的型別 把指標宣告語句中的指標名字和名字左邊的指標宣告符 去掉,剩下的就是指標所指向的型別 在指標的算術運算中,指標所指向的型別有很大的作用 指標本身所佔據的記憶體區 用函式sizeof 指標的型別 可以測...
C語言指標總結
c語言中的精華是什麼,答曰指標,這也是c語言中唯一的難點。c是對底層操作非常方便的語言,而底層操作中用到最多的就是指標,以後從事嵌入式開發的朋友們,指標將陪伴我們終身。本文將從八個常見的方面來透視c語言中的指標,當然,還有其他沒有具體提到的方面,像指標表示式 指標安全等問題,以後有機會我再慢慢補充。...