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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言 void和void *(无类型指针)

發布時間:2024/1/23 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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++示例代碼:

    const char pp[10] = {0}; const char* str = "aaa";void* pv = NULL; pv = pp;//錯誤 pv = str;//錯誤 不能將常量指針賦值給void *指針

    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指針進行算法操作,即下列操作都是不合法的:

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

    ANSI標準之所以這樣認定,是因為它堅持:進行算法操作的指針必須是確定知道其指向數據類型大小的。
    例如:

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

    pint++的結果是使其增大sizeof(int)。

    但是大名鼎鼎的GNU(GNU’s Not Unix的縮寫)則不這么認定,它指定void * 的算法操作與char * 一致。
    因此下列語句在GNU編譯器中皆正確:

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

    pvoid++的執行結果是其增大了1。
      在實際的程序設計中,為迎合ANSI標準,并提高程序的可移植性,我們可以這樣編寫實現同樣功能的代碼:
    (type*)vp++; //等價于:vp=vp+sizeof(type) type為任意數據類型

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

    GNU和ANSI還有一些區別,總體而言,GNU較ANSI更“開放”,提供了對更多語法的支持。但是我們在真實設計時,還是應該盡可能地迎合ANSI標準。

    void指針的應用

    當進行純粹的內存操作的時候,或者傳遞一個指向未定類型的指針時,可以使用void指針;
    典型的如內存操作函數memcpy和memset的函數原型分別為:

    void * memcpy(void *dest,constvoid * src,size_tlen); void * memset(void * buffer,intc,size_tnum);

    這樣,任何類型的指針都可以傳入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 *(无类型指针)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。