void 似乎只有”注釋”和限制程序的作用,當然,這里的”注釋”不是為我們人提供注釋,而是為編譯器提供一種所謂的注釋。
一般我們常見的就是這兩種情況:
\1. void 指針可以指向任意類型的數據,就是說可以用任意類型的指針對 void 指針對 void 指針賦值。例如:
int*a;void*p;p=a;
如果要將 void 指針 p 賦給其他類型的指針,則需要強制類型轉換,就本例而言:a=(int *)p。在內存的分配中我們可以見到 void 指針使用:內存分配函數 malloc 函數返回的指針就是 void * 型,用戶在使用這個指針的時候,要進行強制類型轉換,也就是顯式說明該指針指向的內存中是存放的什么類型的數據 (int )malloc(1024) 表示強制規定 malloc 返回的 void 指針指向的內存中存放的是一個個的 int 型數據。
\2. 在 ANSI C 標準中,不允許對 void 指針進行一些算術運算如 p++ 或 p+=1 等,因為既然 void 是無類型,那么每次算術運算我們就不知道該操作幾個字節,例如 char 型操作 sizeof(char) 字節,而 int 則要操作 sizeof(int) 字節。而在 GNU 中則允許,因為在默認情況下,GNU 認為 void * 和 char * 一樣,既然是確定的,當然可以進行一些算術操作,在這里sizeof(*p)==sizeof(char)。
void 幾乎只有”注釋”和限制程序的作用,因為從來沒有人會定義一個 void 變量,讓我們試著來定義:
voida;
這行語句編譯時會出錯,提示”illegal use of type ‘void'”。即使 void a 的編譯不會出錯,它也沒有任何實際意義。
眾所周知,如果指針 p1 和 p2 的類型相同,那么我們可以直接在 p1 和 p2 間互相賦值;如果 p1 和 p2 指向不同的數據類型,則必須使用強制類型轉換運算符把賦值運算符右邊的指針類型轉換為左邊指針的類型。
float*p1;int*p2;p1=p2;//其中p1=p2語句會編譯出錯,//提示“'=':cannotconvertfrom'int*'to'float*'”,必須改為:p1=(float*)p2;
而 void * 則不同,任何類型的指針都可以直接賦值給它,無需進行強制類型轉換。
void*p1;int*p2;p1=p2;
但這并不意味著,void * 也可以無需強制類型轉換地賦給其它類型的指針。因為”無類型”可以包容”有類型”,而”有類型”則不能包容”無類型”。
小心使用 void 指針類型:
按照 ANSI(American National Standards Institute) 標準,不能對 void 指針進行算法操作,即下列操作都是不合法的:
void*pvoid;pvoid++;//ANSI:錯誤pvoid+=1;//ANSI:錯誤//ANSI標準之所以這樣認定,是因為它堅持:進行算法操作的指針必須是確定知道其指向數據類型大小的。//例如:int*pint;pint++;//ANSI:正確
pint++ 的結果是使其增大 sizeof(int)。 但是 GNU 則不這么認定,它指定 void * 的算法操作與 char * 一致。因此下列語句在 GNU 編譯器中皆正確:
pvoid++;//GNU:正確pvoid+=1;//GNU:正確
pvoid++ 的執行結果是其增大了 1。
在實際的程序設計中,為迎合 ANSI 標準,并提高程序的可移植性,我們可以這樣編寫實現同樣功能的代碼:
void*pvoid;((char*)pvoid)++;//ANSI:錯誤;GNU:正確(char*)pvoid+=1;//ANSI:錯誤;GNU:正確
GNU 和 ANSI 還有一些區別,總體而言,GNU 較 ANSI 更”開放”,提供了對更多語法的支持。但是我們在真實設計時,還是應該盡可能地迎合 ANSI 標準。 如果函數的參數可以是任意類型指針,那么應聲明其參數為void *。
注:void 指針可以任意類型的數據,可以在程序中給我們帶來一些好處,函數中形為指針類型時,我們可以將其定義為 void 指針,這樣函數就可以接受任意類型的指針。如:
典型的如內存操作函數 memcpy 和 memset 的函數原型分別為:
void*memcpy(void*dest,constvoid*src,size_tlen);void*memset(void*buffer,intc,size_tnum);
這樣,任何類型的指針都可以傳入 memcpy 和 memset 中,這也真實地體現了內存操作函數的意義,因為它操作的對象僅僅是一片內存,而不論這片內存是什么類型(參見 C 語言實現泛型編程)。如果 memcpy 和 memset 的參數類型不是 void *,而是 char *,那才叫真的奇怪了!這樣的 memcpy 和 memset 明顯不是一個”純粹的,脫離低級趣味的”函數!void 的出現只是為了一種抽象的需要,如果你正確地理解了面向對象中”抽象基類”的概念,也很容易理解 void 數據類型。正如不能給抽象基類定義一個實例,我們也不能定義一個 void(讓我們類比的稱 void 為”抽象數據類型”)變量。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“C語言中void有什么用”這篇文章對大家有幫助,同時也希望大家多多支持本站,關注本站行業資訊頻道,更多相關知識等著你來學習!
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...
2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...
:喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...
(資料圖)最近這段時間總有小伙伴問小編羥基酪醇的作用是什么,小編為此在網上搜尋了一些有關于羥基酪醇的作用的知識送給大家,希望能解答各位小伙伴的疑惑。1、能有效增強皮膚彈性和潤澤,具除皺抗衰老之功效。2、有助于人體對礦物質的吸收,保持骨密度,減少骨骼疏松,同時提高內分泌系統功能,促進新陳代謝,促進傷口愈合,消除體內自由基,恢復人體臟腑器官的健康狀態,防止腦衰。3、可以防治肺癌,乳腺癌,子宮癌,前列腺...
深圳農商行是不是深圳農村商業銀行?深圳農商行就是深圳農村商業銀行。深圳農商行在原深圳農村信用社委員會和1 8家鄉村農村信用社的根基上,不斷演化發展,以深圳市本地企業、民營企業、原鄉村農村信用社組員和員工作為最初的發起者,按照規定注入資本,創建了這樣一家股份合作制農商銀行。農村商業銀行又叫什么?農村商業銀行又叫農村信用社。通稱:農商銀行,是由轄內農戶、鄉村個體工商戶、公司法人和別的經濟機構一同入股投...
中國喬丹改名叫中喬體育股份有限公司,大家也稱之為中喬體育。中喬也就是原喬丹體育在2000年就創立了,距今以及21年的歷史了,也算是伴隨一代國人記憶的品牌了,不過這個記憶還真不一定是什么好記憶,就拿我自己的經歷來說,我的第一雙籃球鞋就是中國喬丹的籃球鞋,那雙鞋也伴隨我從初中升到高中,我那時真的以為喬丹體育真的是邁克爾喬丹的品牌!中國喬丹和美國喬丹區別1、創辦者不同中國喬丹是由福建喬丹體育用品公司創立...