C语言 void和void *(无类型指针)
void 關鍵字
void的字面意思是“無類型”,void *則為“無類型指針”,void *可以指向任何類型的數據。
void幾乎只有“注釋”和限制程序的作用,因為從來沒有人會定義一個void變量,讓我們試著來定義:
void a;這行語句編譯時會出錯,提示“illegal use of type ‘void’”。不過,即使void a的編譯不會出錯,它也沒有任何實際意義。
void真正發揮的作用在于:
當函數不需要返回值時,必須使用void限定。例如: void func(int, int)
當函數不允許接受參數時,必須使用void限定。例如:int func(void)
void 指針
void的意思就是“無類型”,void指針則為“無類型指針”,void指針可以指向任何類型的數據。所以void指針一般被稱為通用指針或者泛指針,或者叫做萬能指針。
void指針使用規范
1、void指針可以指向任意類型的數據,即可用任意數據類型的指針對void指針賦值。例如
int *pint ; void *pvoid ; //它沒有類型,或者說這個類型不能判斷出指向對象的長度 pvoid = pint ; //只獲得變量/對象地址而不獲得大小,但是不能 pint=pvoid;在C語言中,可以把任何類型的指針(包括函數指針)賦值給void*指針而無須進行強制類型轉換。
在C++中,對這個轉換做了更嚴格的限制:只有非常量指針才能賦值給void*指針。
C++示例代碼:
2、如果要將pvoid賦給其他類型指針,則需要強制類型轉換如:
pint = (int *)pvoid; //轉換類型也就是獲得指向變量/對象大小注意:在C++編譯器中必須轉換 pint = (int*)pvoid 否則報錯; 但在C編譯器中可以寫成 pint = pvoid;
3、void指針在強制轉換成具體類型前,不能解引用(即取內容的意思);
*pvoid //錯誤要想復引用一個指針,或者使用“->”運算符復引用一部分,都要有對于指針指向的內存的解釋規則。
例如,int *p;
那么,當你后面復印用p的時候,編譯器就會把從p指向的地址開始的四個字節看作一個整數的補碼。
因為void指針只知道指向變量/對象的起始地址,而不知道指向變量/對象的大小(占幾個字節)所以無法正確引用
4、void指針不能參與指針運算,除非進行轉換。
按照ANSI(AmericanNationalStandardsInstitute)標準,不能對void指針進行算法操作,即下列操作都是不合法的:
ANSI標準之所以這樣認定,是因為它堅持:進行算法操作的指針必須是確定知道其指向數據類型大小的。
例如:
pint++的結果是使其增大sizeof(int)。
但是大名鼎鼎的GNU(GNU’s Not Unix的縮寫)則不這么認定,它指定void * 的算法操作與char * 一致。
因此下列語句在GNU編譯器中皆正確:
pvoid++的執行結果是其增大了1。
在實際的程序設計中,為迎合ANSI標準,并提高程序的可移植性,我們可以這樣編寫實現同樣功能的代碼:
(type*)vp++; //等價于:vp=vp+sizeof(type) type為任意數據類型
GNU和ANSI還有一些區別,總體而言,GNU較ANSI更“開放”,提供了對更多語法的支持。但是我們在真實設計時,還是應該盡可能地迎合ANSI標準。
void指針的應用
當進行純粹的內存操作的時候,或者傳遞一個指向未定類型的指針時,可以使用void指針;
典型的如內存操作函數memcpy和memset的函數原型分別為:
這樣,任何類型的指針都可以傳入memcpy和memset中,這也真實地體現了內存操作函數的意義,因為它操作的對象僅僅是一片內存,而不論這片內存是什么類型。
注意memcpy和memset函數返回的也是void*類型。
由于void * 可以和任何指針直接做變換,除了函數指針外,在C編譯器下,我們知道malloc函數的返回類型是void*,所以下面2句是等價的
int *p =(int*)malloc(100*sizeof(int));int *p =malloc(100*sizeof(int));但在C++編譯器下,第二句由于沒有強制轉換將報錯。
參考鳴謝:
https://blog.csdn.net/weixin_30268071/article/details/97432128
https://blog.csdn.net/qq_29924041/article/details/54882135
https://blog.csdn.net/qq_38916259/article/details/88105739
https://blog.csdn.net/guo_guo_cai/article/details/78144364
總結
以上是生活随笔為你收集整理的C语言 void和void *(无类型指针)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言 内联函数
- 下一篇: STM32 CAN过滤器