日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言中 void* 详解及应用

發(fā)布時間:2025/4/5 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言中 void* 详解及应用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

void在英文中作為名詞的解釋為“空虛;空間;空隙”;而在C語言中,void被翻譯為“無類型”,相應(yīng)的void *為“無類型指針”。void似乎只有“注釋”和限制程序的作用,當(dāng)然,這里的“注釋”不是為我們?nèi)颂峁┳⑨?#xff0c;而是為編譯器提供一種所謂的注釋。

本文地址:http://www.cnblogs.com/archimedes/p/c-void-point.html,轉(zhuǎn)載請注明源地址。

void的作用:
1.對函數(shù)返回的限定,這種情況我們比較常見。

2.對函數(shù)參數(shù)的限定,這種情況也是比較常見的。

一般我們常見的就是這兩種情況:

當(dāng)函數(shù)不需要返回值值時,必須使用void限定,這就是我們所說的第一種情況。例如:void func(int a,char *b)。

當(dāng)函數(shù)不允許接受參數(shù)時,必須使用void限定,這就是我們所說的第二種情況。例如:int func(void)。

void指針的使用規(guī)則:
1.void指針可以指向任意類型的數(shù)據(jù),就是說可以用任意類型的指針對void指針對void指針賦值。例如:

int *a;void *p;p=a;

如果要將void指針p賦給其他類型的指針,則需要強(qiáng)制類型轉(zhuǎn)換,就本例而言:a=(int *)p。在內(nèi)存的分配中我們可以見到void指針使用:內(nèi)存分配函數(shù)malloc函數(shù)返回的指針就是void *型,用戶在使用這個指針的時候,要進(jìn)行強(qiáng)制類型轉(zhuǎn)換,也就是顯式說明該指針指向的內(nèi)存中是存放的什么類型的數(shù)據(jù)(int )malloc(1024)表示強(qiáng)制規(guī)定malloc返回的void指針指向的內(nèi)存中存放的是一個個的int型數(shù)據(jù)。

2.在ANSI C標(biāo)準(zhǔn)中,不允許對void指針進(jìn)行一些算術(shù)運算如p++或p+=1等,因為既然void是無類型,那么每次算術(shù)運算我們就不知道該操作幾個字節(jié),例如char型操作sizeof(char)字節(jié),而int則要操作sizeof(int)字節(jié)。而在GNU中則允許,因為在缺省情況下,GNU 認(rèn)為void *和char *一樣,既然是確定的,當(dāng)然可以進(jìn)行一些算術(shù)操作,在這里sizeof(*p)==sizeof(char)。

void幾乎只有“注釋”和限制程序的作用,因為從來沒有人會定義一個void變量,讓我們試著來定義:

void a;

這行語句編譯時會出錯,提示“illegal use of type ‘void’”。即使void a的編譯不會出錯,它也沒有任何實際意義。

眾所周知,如果指針p1和p2的類型相同,那么我們可以直接在p1和p2間互相賦值;如果p1和p2指向不同的數(shù)據(jù)類型,則必須使用強(qiáng)制類型轉(zhuǎn)換運算符把賦值運算符右邊的指針類型轉(zhuǎn)換為左邊指針的類型。

float *p1;int *p2;p1 = p2;

//其中p1 = p2語句會編譯出錯,
//提示“’=’ : cannot convert from ‘int *’ to ‘float *’”,必須改為:
p1 = (float *)p2;
而void *則不同,任何類型的指針都可以直接賦值給它,無需進(jìn)行強(qiáng)制類型轉(zhuǎn)換

void *p1; int *p2; p1 = p2;

但這并不意味著,void *也可以無需強(qiáng)制類型轉(zhuǎn)換地賦給其它類型的指針。因為“無類型”可以包容“有類型”,而“有類型”則不能包容“無類型”。

小心使用void指針類型:

按照ANSI(American National Standards Institute)標(biāo)準(zhǔn),不能對void指針進(jìn)行算法操作,即下列操作都是不合法的:

void * pvoid; pvoid++; //ANSI:錯誤 pvoid += 1; //ANSI:錯誤

//ANSI標(biāo)準(zhǔn)之所以這樣認(rèn)定,是因為它堅持:進(jìn)行算法操作的指針必須是確定知道其指向數(shù)據(jù)類型大小的。
//例如:

int *pint; pint++; //ANSI:正確

pint++的結(jié)果是使其增大sizeof(int)。
但是GNU則不這么認(rèn)定,它指定void *的算法操作與char *一致。因此下列語句在GNU編譯器中皆正確:

pvoid++; //GNU:正確 pvoid += 1; //GNU:正確

pvoid++的執(zhí)行結(jié)果是其增大了1
在實際的程序設(shè)計中,為迎合ANSI標(biāo)準(zhǔn),并提高程序的可移植性,我們可以這樣編寫實現(xiàn)同樣功能的代碼:

void * pvoid; ((char *)pvoid)++; //ANSI:錯誤;GNU:正確 (char *)pvoid += 1; //ANSI:錯誤;GNU:正確

GNU和ANSI還有一些區(qū)別,總體而言,GNU較ANSI更“開放”,提供了對更多語法的支持。但是我們在真實設(shè)計時,還是應(yīng)該盡可能地迎合ANSI標(biāo)準(zhǔn)。 如果函數(shù)的參數(shù)可以是任意類型指針,那么應(yīng)聲明其參數(shù)為void *

注:void指針可以任意類型的數(shù)據(jù),可以在程序中給我們帶來一些好處,函數(shù)中形為指針類型時,我們可以將其定義為void指針,這樣函數(shù)就可以接受任意類型的指針。如:

典型的如內(nèi)存操作函數(shù)memcpy和memset的函數(shù)原型分別為:

void * memcpy(void *dest, const void *src, size_t len); void * memset ( void * buffer, int c, size_t num );

這樣,任何類型的指針都可以傳入memcpy和memset中,這也真實地體現(xiàn)了內(nèi)存操作函數(shù)的意義,因為它操作的對象僅僅是一片內(nèi)存,而不論這片內(nèi)存是什么類型(參見C語言實現(xiàn)泛型編程)。如果memcpy和memset的參數(shù)類型不是void *,而是char *,那才叫真的奇怪了!這樣的memcpy和memset明顯不是一個“純粹的,脫離低級趣味的”函數(shù)!void的出現(xiàn)只是為了一種抽象的需要,如果你正確地理解了面向?qū)ο笾小俺橄蠡悺钡母拍?#xff0c;也很容易理解void數(shù)據(jù)類型。正如不能給抽象基類定義一個實例,我們也不能定義一個void(讓我們類比的稱void為“抽象數(shù)據(jù)類型”)變量。

轉(zhuǎn)載自:https://www.cnblogs.com/wuyudong/p/c-void-point.html

總結(jié)

以上是生活随笔為你收集整理的C语言中 void* 详解及应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。