void及void指針含義的深刻解析_第1頁
void及void指針含義的深刻解析_第2頁
void及void指針含義的深刻解析_第3頁
void及void指針含義的深刻解析_第4頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、void的含義void即“無類型”,void*則為“無類型指針”,可以指向任何數據類型。void指針使用規范void指針可以指向任意類型的數據,亦即可用任意數據類型的指針對void指針賦值。例如:int*pint;void*pvoid;pvoid=pint;/*不過不能pint=pvoid;*/如果要將pvoid賦給其他類型指針,則需要強制類型轉換如:pint=(int*)pvoid;在ANSIC標準中,不允許對void指針進行算術運算如pvoid+或pvoid+=l等,而在GNU中則允許,因為在缺省情況下,GNU認為void*與char*樣。sizeoff*pvoid)=sizeoffcha

2、r).void的作用對函數返回的限定。對函數參數的限定。當函數不需要返回值時,必須使用void限定。例如:voidfunc(int,int);當函數不允許接受參數時,必須使用void限定。例如:intfunc(void)。由于void指針可以指向任意類型的數據,亦即可用任意數據類型的指針對void指針賦值,因此還可以用void指針來作為函數形參,這樣函數就可以接受任意數據類型的指針作為參數。例如:void*memcpy(void*dest,constvoid*src,size_tlen);void*memset(void*buffer;intc,size_tnum);許多初學者對C/C+語言中

3、的void及void指針類型不其理解,因此在使用上出現了一些錯誤。本文將對void關鍵字的深刻含義進行解說,并詳述void及void指針類型的使用方法與技巧。void的含義void的字面意思是“無類型”,void*則為“無類型指針”,void*可以指向任何類型的數據。void兒乎只有“注釋”和限制程序的作用,因為從來沒有人會定義一個void變量,讓我們試著來定義:voida;這行語句編譯時會出錯,提示illegaluseoftypevoid。不過,即使voida的編譯不會出錯,它也沒有任何實際意義。void真正發揮的作用在于:對函數返回的限定;對函數參數的限定。眾所周知,如果指針pl和P2的類

4、型相同,那么我們可以直接在pl和P2間互相賦值;如果pl和p2指向不同的數據類型,則必須使用強制類型轉換運算符把賦值運算符右邊的指針類型轉換為左邊指針的類型。例如:float*pl;int*p2;Pl=P2;其中pl=p2語句會編譯出錯,提示=:cannotconvertfromint*tofloat*”,必須改為:pl=(float*)p2;而void*則不同,任何類型的指針都可以直接賦值給它,無需進行強制類型轉換:void*pl;int*p2;Pl=P2;但這并不意味著,void*也可以無需強制類型轉換地賦給其它類型的指針。因為“無類型”可以包容“有類型”,而“有類型”則不能包容“無類型”

5、。道理很簡單,我們可以說“男人和女人都是人”,但不能說“人是男人”或者“人是女人”。下面的語句編譯出錯:void*pl;int*p2;P2=pl;提示=:cannotconvertfromvoid*toint*。3.void的使用下面給出void關鍵字的使用規則:規則一如果函數沒有返回值,那么應聲明為void類型在C語言中,凡不加返回值類型限定的函數,就會被編譯器作為返回整型值處理。但是許多程序員卻誤以為其為void類型。例如:add(inta,intb)returna+b;intmainfintargc,char*argv)printf(2+3=%d,add(2,3);程序運行的結果為輸出:

6、2+3=5這說明不加返回值說明的函數的確為int函數。林銳博士高質量C/C+編程中提到:“C+語言有很嚴格的類型安全檢查,不允許上述情況(指函數不加類型聲明)發生”。可是編譯器并不一定這么認定,譬如在VisualC+6.0中上述add函數的編譯無錯也無警告且運行正確,所以不能寄希望于編譯器會做嚴格的類型檢查。因此,為了避免混亂,我們在編寫C/C+程序時,對于任何函數都必須一個不漏地指定其類型。如果函數沒有返回值,一定要聲明為void類型。這既是程序良好可讀性的需要,也是編程規范性的要求。另外,加上void類型聲明后,也可以發揮代碼的“自注釋”作用。代碼的“自注釋”即代碼能自己注釋自己。Page

7、規則二如果函數無參數,那么應聲明其參數為void在C+語言中聲明一個這樣的函數:intfunction(void)return1;則進行下面的調用是不合法的:function(2);因為在C+中,函數參數為void的意思是這個函數不接受任何參數。我們在TurboC2.0中編譯:tfinclude”stdio.h”fun()return1;main()printftVdVJunfZ);getcharf);編譯正確且輸出1,這說明,在(:語言中,可以給無參數的函數傳送任意類型的參數,但是在C+編譯器中編譯同樣的代碼則會出錯。在C+中,不能向無參數的函數傳送任何參數,出錯提示fun:function

8、doesnottake1parametersVo所以,無論在C還是C+中,若函數不接受任何參數,一定要指明參數為void。規則三小心使用void指針類型按照ANSI(AmericanNationalStandardsInstitute)標準,不能對void指針進彳亍算法操作,即下列操作都是不合法的:void*pvoid;pvoid+;/ANSI:錯誤pvoid+=1;/ANSI:錯誤/ANSI標準之所以這樣認定,是因為它堅持:進行算法操作的指針必須是確定知道其指向數據類型大小的。例如:int*pint;pint+;/ANSI:正確pint+的結果是使其增大sizeof(int)o但是大名鼎鼎的

9、GNU(GNUsNotUnix的縮寫)則不這么認定,它指定void*的算法操作與char*一致。因此下列語句在GNU編譯器中皆正確:pvoid+;/GNU:正確pvoid+=1;/GNU:正確pvoid+的執行結果是其增大了lo在實際的程序設計中,為迎合ANSI標準,并提高程序的可移植性,我們可以這樣編寫實現同樣功能的代碼:void*pvoid;(char*)pvoid+;/ANSI:正確;GNU:正確(char*)pvoid+=1;/ANSI:錯誤;GNU:正確GNU和ANSI還有一些區別,總體而言,GNU較ANSI更“開放”,提供了對更多語法的支持。但是我們在真實設計時,還是應該盡可能地迎

10、合ANSI標準。規則四如果函數的參數可以是任意類型指針,那么應聲明其參數為void*典型的如內存操作函數memcpy和memset的函數原型分別為:void*memcpyfvoid*dest,constvoid*src,size_tlen);void*memset(void*buffer;intc,size_tnum);這樣,任何類型的指針都可以傳入memcpy和memset中,這也真實地體現了內存操作函數的意義,因為它操作的對象僅僅是一片內存,而不論這片內存是什么類型。如果memcpy和memset的參數類型不是void*,而是char*,那才叫真的奇怪了!這樣的memcpy和memset明

11、顯不是一個“純粹的,脫離低級趣味的”函數!下面的代碼執行正確:示例:memset接受任意類型指針intintarray100;Pagememset(intarray,0,100*sizeof(int);/將intarray清0示例:memcpy接受任意類型指針intintarrayl100,intarray2100;memcpy(intarrayl,intarray乙100*sizeof(int);/將intarrayZ拷貝給intarrayl有趣的是,memcpy和memset函數返回的也是void*類型,標準庫函數的編寫者是多么地富有學問啊!規則五void不能代表一個真實的變量下面代碼都企圖讓void代表一個真實的變量,因此都是錯誤的代碼:voida;錯誤function(voida);/錯誤void體現了一種抽象,這個世界上的變量都是“有類型”的,譬如一個人不是男人就是

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論