這篇c語言指標學習經驗總結主要是我入職以來學習c指標過程中的點滴記錄。文件裡面就不重複書上說得很清楚的概念性東西,只把一些說得不清楚或理解起來比較費解的東西做一下講解,希望能達到以下三個目的
1.通過寫這些東西,把我腦袋中關於c的模糊的知識清晰化。
2.給初轉c的同事們一點提示和幫助。
3.也希望各位前輩檢查一下文件中是否有理解偏差的地方。
1 指標的概念分解
指標是乙個特殊的變數,它裡面儲存的數值被解釋成為記憶體裡的乙個位址。 要搞清乙個指標需要搞清指標的四方面的內容:
1.指標的型別
2.指標所指向的型別
3.指標的值或者叫指標所指向的記憶體區
4.還有指標本身所佔據的記憶體區
先宣告幾個指標放著做例子:
例一:(1)int *ptr;
(2)char *ptr;
(3)int **ptr;
(4)int (*ptr)[3];
(5)int *(*ptr)[4];
1.1 指標的型別
從語法的角度看,你只要把指標宣告語句裡的指標名字去掉,剩下的部分就是這個指標的型別。這是指標本身所具有的型別。所以分析下例一中各個指標的型別:
(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.2 指標所指向的型別
當你通過指標來訪問指標所指向的記憶體區時,指標所指向的型別決定了編譯器將把那片記憶體區里的內容當做什麼來看待。從語法上看,你只須把指標宣告語句中的指標名字和名字左邊的指標宣告符 *去掉,剩下的就是指標所指向的型別。例如:
(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語言中的精華是什麼,答曰指標,這也是c語言中唯一的難點。
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的一切屬性都沒有被修改。
另外,乙個函式如果使用了指標作為形參, 那麼在函式呼叫語句的實參和形參的結合過程中,也必須保證型別一致 ,否則需要強制轉換。
《C語言的精華 指標》 基礎理解
c語言的精華 指標 位址形象化的稱為 指標 即指標就是位址。記憶體區的每乙個位元組都有乙個編號,即為 位址 include intmain 執行結果 6487580 process exited after 5.69 seconds with return value 7 請按任意鍵繼續.2.1 指...
c語言中認識指標
位址和變數的概念 指標作用 1 表示複雜的資料結果 eg 鍊錶 樹 2 能動態分配記憶體 3 方便的使用字串 4 有效而方便使用字串 5 有效而方便的使用陣列 呼叫函式的時候能夠獲得1 個以上的結果。6 能夠直接處理單元位址等 總結 可以看到可以很直接的接觸到計算機的硬體的內容進行操作。1 資料的儲...
C 語言中的指標
指標是 c 語言中的精華,正確靈活的運用指標,可以表示複雜的資料結構,動態分配記憶體,方便使用字串和陣列,呼叫函式返回多結果,直接處理記憶體單元等等。位址就是記憶體的編號,如果拿旅店作為記憶體,那麼每個房間號其實就相當於位址了。當程式編譯時,就會對變數分配記憶體單元,分配時按變數型別分配大小。經過編...