int
*p;
上面的定義我們可以知道, p 稱之為指標變數,而並不是指標,而 *p 我們才稱之為指標。
所以也就有了如下的操作:
int
*p;int a =10;
p =&a;
printf
("the value of p is:%p\n"
,p);
printf
("the value of *p is:%d\n"
,*p)
;
上述的操作簡單地說明了指標的用法,即將 a 的位址賦值給了 p 指標變數,所以 p 裡面所儲存的記憶體位址處的記憶體就是 p 所指向的記憶體。通過 *p 解引用就可以獲得指標變數指向的記憶體的值。因此上述**第乙個輸出的是 a 的位址,而第二行輸出的是 10
另外上述也有簡單的寫法,就是這樣:
int a =10;
int*p =
&a;printf
("the value of p is:%p\n"
,p);
printf
("the value of *p is:%d\n"
,*p)
;
理解上述也不難,只需知道對於 p 來講,我們只是定義了乙個int * 型別的指標變數,然後對 p 進行了賦值。
乙個對於初學比較容易懵的是下面這樣的乙個概念:
int a =10;
int*p =
&a;*p =20;
printf
("the value of *p id:%d\n"
,*p)
;printf
("the value of a is:%d\n"
,a);
第一條的輸出語句我想大家都能明白,因為將指標賦值為 20 ,那輸出自然是 20 ,但是對於第二條輸出語句可能會誤以為還是 10 ,因為我們也沒有在程式中看到**改變了 a 的值。正確答案是 a 的值是 20 。因為第二條語句 p 已經指向了 a 的位址,雖然我們改變了 *p 的值,但是對於 p 的值沒有改變,所以說 p 所指向的記憶體位址沒變,但是記憶體位址裡面的內容已經變了,而 a 的位址和 p 的值是一樣的。所以 a 的值也就相應發生了改變。
泛型指標
介紹了指標的大致概念後,我們回過頭來想,指標的型別是什麼,因為變數是有型別的,那麼相應的指標也應該有型別。所以有了如下定義:
int
*p;char
*cp;
float
*fp;
p 的型別就是 int * ,cp 的型別就是 char * ,fp 的型別就是 float * ,我們知道不同型別的變數在賦值時,需要進行強制轉換,對於指標來說也是這樣,但是指標相對於變數來講,有乙個特殊的型別,就是 void * ,我們稱之為泛型指標,同樣也被我們稱之為萬能指標。
在引入萬能指標的應用之前,我們看乙個初學者都會接觸過的例子,就是資料的交換:
void
swap
(int
*p1,
int*p2)
但是這個資料交換存在乙個侷限性,只能應用於整型資料的交換,那麼如何設計乙個能夠適用於任何資料型別的交換程式呢,這裡就需要適用我們之前提到的泛型指標。
int
swap
(void
*p1,
void
*p2,
int size)
上面就是對於 void * 的應用,能夠接收不同型別的資料進行交換,當然裡面也應用了 memcpy() 函式,memcpy 可以複製任何一段資料,它的作用是將資料從記憶體中的乙個地方拷貝到另乙個地方。對於上述程式中的 malloc 是用於給 temp 分配乙個記憶體,防止其成為野指標,最後再將其分配的記憶體釋放掉。 void 型指標的小小trick
指標的概念還是有很多tricks的,這裡的p如果宣告為int 型的指標,則 2 p sizeof int 則是p的位址加上sizeof int 個int型大小的位址增量 include typedef struct test int first int second mytype int main ...
C 泛型方法結合反射的妙用
反射是一種動態引導程式集中所定義型別的過程,當然也包括它自身所在的程式集。這裡繼續沿用上篇文章的例子,總結在泛型方法中結合反射思想,從而優化 上篇文章處理了通過返回的中文列舉結果,翻譯為對應中文的方式,從而便於最後展示為英文。由於只有乙個後台,而該後台又是中文,客戶端又是英文,所以這裡在提交之前,還...
void指標 void 的用法
指標有兩個屬性 指向變數 物件的位址和長度 但是指標只儲存位址,長度則取決於指標的型別 編譯器根據指標的型別從指標指向的位址向後定址 指標型別不同則定址範圍也不同,比如 int 從指定位址向後尋找4位元組作為變數的儲存單元 double 從指定位址向後尋找8位元組作為變數的儲存單元 1.void指標...