chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何理解C++中的void?

jf_78858299 ? 來源:小余的自習(xí)室 ? 作者:小余的自習(xí)室 ? 2023-03-30 15:01 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.定義

首先void*中的void代表一個任意的數(shù)據(jù)類型,"星號"代表一個指針,所以其就是一個任意數(shù)據(jù)類型的指針。

對于指定數(shù)據(jù)類型的指針如int* ,double*等,他們的sizeof都是4個字節(jié),因為都是一個指針,只是指針指向的數(shù)據(jù)類型不一致。

C語言是一個強類型的語言, 那么他們之間有什么區(qū)別呢 ?前面一篇文章我們說過, 指針+1和-1是和指向數(shù)據(jù)類型有關(guān)的 。

假設(shè)指針值為0x00000001,指針類型為int類型,整數(shù)為n,則計算出來的結(jié)果為0x00000001+ n乘以4,這里的4是因為指針類型為int,如果是double,則為0x00000001+ n乘以8. 所以我們使用double類型指針+1,地址移動了8位,而用int指針+1,地址移動了4位,就是這個道理。

這說起來其實和數(shù)據(jù)內(nèi)存對齊有關(guān)。你可以把這里的4和8理解為跳躍力。

那對于void*呢? 其實就是一個未指定跳躍力的指針 。

那void*的跳躍力又什么時候指定?在需要使用的時候指定就可以了,好處: 可以實現(xiàn)泛型編程,節(jié)省代碼 。

2.void*使用場景

2.1:當(dāng)函數(shù)傳參時不確定數(shù)據(jù)類型時或者支持多種數(shù)據(jù)類型傳遞時。

代碼如下:

void say(int type,void* pArgs) {
    switch (type) 
    {
        case 0:
        {
            double* d = (double*)pArgs;
            break;
        }   
        case 1:
        {
            int* i = (int*)pArgs;
            break;
        }       
    }
}

該函數(shù)使用一個type來表示當(dāng)前參數(shù)void*的類型,內(nèi)部通過type判斷轉(zhuǎn)換的類型。

2.2:函數(shù)返回值不需要考慮類型,只關(guān)心返回的大小。

如malloc函數(shù):

原型:

void* malloc(size_t size)

代碼使用:

int* a = nullptr;
double* b = nullptr;
b = (double*)malloc(sizeof(double));
a = (int*)malloc(sizeof(double));

可以看到malloc返回值類型為void*,其只返回分配內(nèi)存的大小,不關(guān)心分配后的內(nèi)存你是使用int還是double類型進(jìn)行劃分.

注意:函數(shù)外部在接收到void*格式的返回值時,需要強轉(zhuǎn)為自己的數(shù)據(jù)類型才能使用。

3.void*使用中的注意點:

1.使用賦值運算符“=”時,void*只能作為左值不能作為右值。

void*作為一個未指定數(shù)據(jù)類型的指針,可以指向任何一個數(shù)據(jù)類型的指針,但是有數(shù)據(jù)類型的指針,不能指向一個void* 的指針。

代碼如下:

int i = 5;
int* pi = &i;
void* pv = pi;
int* pi1 = pv;//編譯錯誤,void*類型的指針不能初始化為指定類型的指針

這其實是可以理解的:

假設(shè)void*指定了一個非int類型的數(shù)據(jù),如果此時賦值給int*類型的指針,則會發(fā)生嚴(yán)重的bug**。

2.void*類型必須強轉(zhuǎn)為指定類型的數(shù)據(jù)才能使用。

void 在未指定類型的情況下,是不能直接使用的, 只有在轉(zhuǎn)換為顯示類型后才能使用 。 *

代碼如下:

int i = 5;
int* pi = &i;
void* pv = pi;
//cout << *pv << endl;//表達(dá)式必須是指向完整對象類型的指針
cout << *(int*)pv << endl;

代碼中可以看出在未強轉(zhuǎn)為顯示類型前,使用void*會報表達(dá)式必須是指向完整對象類型的指針.

說明void*一定要強轉(zhuǎn)后才能使用.

沒有強轉(zhuǎn)的void*是沒有意義的。

那可能有同學(xué)要問了,假設(shè)我們并不知道當(dāng)前void*數(shù)據(jù)類型,強轉(zhuǎn)錯誤了會發(fā)生什么事。

int i = 5;
int* pi = &i;
void* pv = pi;

cout<<"(int*)pv:" << (int*)pv << endl;
cout<<"(double*)pv:" << (double*)pv << endl;
cout <<"*(int*)pv:" << *(int*)pv << endl;
cout <<"*(double*)pv:" << *(double*)pv << endl;

運行結(jié)果:
(int*)pv:0043F724
(double*)pv:0043F724
*(int*)pv:5
*(double*)pv:-9.25596e+61

此時可以看到雖然pv強轉(zhuǎn)為double后,指針指向的地址和強轉(zhuǎn)為int類型指針指向地址是一樣的都是0x0043F724。但是取值后就發(fā)生了異常,因為double占用的是8個字節(jié),所以取值的是后8位字節(jié),所以取到的是一個錯誤的值,實際只有4個字節(jié)是有效的。

我們在使用void*強轉(zhuǎn)的時候一定要注意這點 、

3.C++中使用(void*)0表示空指針。

在C語言中空指針定義方式:

#define NULL ((void*)0)

在C++語言中:

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else 
        #define NULL ((void*)0)
    #endif
#endif
可以看到在C語言中NULL代表(void*)0,而在C++中NULL代表的是0,使用nullptr來表示(void*)0空指針,
所以在C++中推薦使用新標(biāo)準(zhǔn)的nullptr來初始化一個空指針。

4.當(dāng)void*作為函數(shù)的參數(shù)類型或者返回值類型時,說明該函數(shù)可以接收或者返回任意類型的指針。

代碼如下:

void* _say(void* pArgs) {
    return pArgs;
}
int  main()
{
    int _a = 5;
    float f = 10.8;
    int* _pi = &_a;
    float* pf = &f;

    cout << *(int*)_say(_pi) << endl;
    cout << *(float*)_say(pf) << endl;

}
運行結(jié)果:
5
10.8

代碼中可以看出參數(shù)void* pArgs可以使用任意類型的實參,返回值也可以返回任意類型的指針,但是最終需要轉(zhuǎn)換為具體類型才能使用。

void*在C++中的作用其實就是為了實現(xiàn)泛型編程,和Java中使用Object來表示是一樣的,所以又稱為通用指針和泛指針,不過 C++中大部分情況下會使用模板編程來實現(xiàn)泛型 。

上面_say函數(shù)代碼可以使用下面模板函數(shù)代替:

T _say(T t) {
    return t;
}

區(qū)別在于: 模板編程不需要將強制轉(zhuǎn)換為具體類型 ,其使用方式如下:

int _a = 5;
float f = 10.8;
int* _pi = &_a;
float* pf = &f;

cout <<*_say(_pi) << endl;
cout << *_say(pf) << endl;

未強轉(zhuǎn)也可以直接得出結(jié)果,這是因為模板編程會在編譯器幫我們生成具體的函數(shù)。

調(diào)用了兩次_say會分別實現(xiàn):

float* _say(float* t) {
    return t;
}
int* _say(int* t) {
    return t;
}

所以運行的時候是調(diào)用了不同的函數(shù),而使用void*的泛型只調(diào)用一個函數(shù)。

總結(jié)

  • 1.void*是一個過渡型的指針狀態(tài),可以代表任意類型的指針,取值的時候需要轉(zhuǎn)換為具體類型才能取值。其是處于數(shù)據(jù)類型頂端的狀態(tài):

    圖片

  • 2.void* 使用賦值運算符“=”賦值時,只能將具體類型賦值給void星,不能將void*賦值給具體類型。

  • 3.void*一般作為參數(shù)或者返回值來實現(xiàn)泛型編程,但是C++中一般考慮使用模板編程來實現(xiàn)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7292

    瀏覽量

    93381
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2120

    瀏覽量

    76452
  • void
    +關(guān)注

    關(guān)注

    0

    文章

    23

    瀏覽量

    10166
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    C++的結(jié)構(gòu)和類

    C++ 仍然是嵌入式開發(fā)的少數(shù)??語言,但當(dāng)項目變得太大而無法有效使用 C 時,開發(fā)人員通常會采用 C++。這些開發(fā)人員通常從 C 過渡到 C++
    發(fā)表于 07-18 17:37 ?1086次閱讀

    C語言和C++那些不同的地方

    ++11標(biāo)準(zhǔn)。根據(jù)不同的標(biāo)準(zhǔn),它們的功能也會有所不同,但是越新的版本支持的編譯器越少,所以本文在討論的時候使用的C語言標(biāo)準(zhǔn)是C89,C++標(biāo)準(zhǔn)是C++99.我們來介紹
    的頭像 發(fā)表于 12-07 14:29 ?1859次閱讀
    <b class='flag-5'>C</b>語言和<b class='flag-5'>C++</b><b class='flag-5'>中</b>那些不同的地方

    void(*isr)(void)__irq怎么理解

    void(*isr)(void)__irq怎么理解,求高手指教!
    發(fā)表于 08-10 14:12

    C++筆記003:C++從一個小程序開始

    ,暫且這樣理解。<<這個左移操作符,我們發(fā)現(xiàn)已經(jīng)“變味”了,在C++里面已經(jīng)進(jìn)行功能的改造,跟以前C語言的左移操作符用法不一樣了,這就是C++
    發(fā)表于 03-05 12:51

    C++筆記004:C++類通俗點說—— C結(jié)構(gòu)體復(fù)習(xí)

    的程序設(shè)計,對象具有屬性(狀態(tài))和行為,屬性保存在成員變量,行為通過成員方法(函數(shù))來實現(xiàn)。成員方法又是什么?其實方法和函數(shù)可以理解為一回事。只是在C++
    發(fā)表于 03-05 12:53

    C/C++程序員實用大全配套代碼

    CC++程序員實用大全》配套代碼  [涉及平臺] VC++ [作者] void [文件大小] 629KB  [更新日期] 2005-10-28
    發(fā)表于 02-09 11:18 ?28次下載

    C++簡介 ppt

    C++簡介 目錄1.0  本科程在專業(yè)學(xué)習(xí)的地位1.1  程序設(shè)計語言 1.2  C++前史 1.3  C++ 1.4 
    發(fā)表于 02-24 09:34 ?28次下載

    C語言voidvoid指針深層探索

    1.概述 本文將對void關(guān)鍵字的深刻含義進(jìn)行解說,并詳述voidvoid指針類型的使用方法與技巧。 2.void的含義 void的字面意
    發(fā)表于 09-21 11:36 ?166次下載

    EE-128:C++的DSP:從C++調(diào)用匯編類成員函數(shù)

    EE-128:C++的DSP:從C++調(diào)用匯編類成員函數(shù)
    發(fā)表于 04-16 17:04 ?2次下載
    EE-128:<b class='flag-5'>C++</b><b class='flag-5'>中</b>的DSP:從<b class='flag-5'>C++</b>調(diào)用匯編類成員函數(shù)

    淺析C++this指針的理解以及作用

    01 C++程序到C程序的翻譯 想要理解C++語言中的this指針,下面我們做一個舉例,我們要先把下面的C++代碼轉(zhuǎn)換成
    的頭像 發(fā)表于 06-27 11:24 ?3311次閱讀
    淺析<b class='flag-5'>C++</b><b class='flag-5'>中</b>this指針的<b class='flag-5'>理解</b>以及作用

    C++如何用虛函數(shù)實現(xiàn)多態(tài)

    01 — C++虛函數(shù)探索 C++是一門面向?qū)ο笳Z言,在C++里運行時多態(tài)是由虛函數(shù)和純虛函數(shù)實現(xiàn)的,現(xiàn)在我們看下在C++如何用虛函數(shù)實現(xiàn)
    的頭像 發(fā)表于 09-29 14:18 ?2039次閱讀

    C++的Edison IoT黑盒

    電子發(fā)燒友網(wǎng)站提供《C++的Edison IoT黑盒.zip》資料免費下載
    發(fā)表于 10-21 14:20 ?0次下載
    <b class='flag-5'>C++</b><b class='flag-5'>中</b>的Edison IoT黑盒

    C++struct和class的區(qū)別?

    C++struct和class的區(qū)別是什么?C++struct和class的最大區(qū)別在于: ? ? ? ? struct的成員默認(rèn)是公有的, 而class的成員默認(rèn)是私有的,
    的頭像 發(fā)表于 03-10 17:41 ?1078次閱讀

    C++簡史:C++是如何開始的

    的 MISRA C++:2023 博客系列的第二部分。 在這篇博客,我們將深入探討 C++ 的歷史、編程語言多年來的發(fā)展歷程以及它的下一步發(fā)展方向。
    的頭像 發(fā)表于 01-11 09:00 ?1247次閱讀
    <b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的

    C++實現(xiàn)類似instanceof的方法

    函數(shù),可實際上C++沒有。但是別著急,其實C++中有兩種簡單的方法可以實現(xiàn)類似Java的instanceof的功能。 在 C++
    的頭像 發(fā)表于 07-18 10:16 ?1118次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>中</b>實現(xiàn)類似instanceof的方法