泛型指標 void 的妙用

2021-10-04 13:34:05 字數 1951 閱讀 5348

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指標...