一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

無(wú)類(lèi)型指針void*的學(xué)習(xí)與使用

 黃南山 2018-01-18

關(guān)于指針

C/C++中的指針通常來(lái)說(shuō)有兩個(gè)屬性:

 1. 指向變量
 2. 指向?qū)ο蟮牡刂泛烷L(zhǎng)度
  • 1
  • 2

指針其實(shí)就是存儲(chǔ)被指向變量的地址,并不保存其長(zhǎng)度;
而且存的這個(gè)地址僅是變量的首地址,并不是該變量占據(jù)內(nèi)存的所有地址空間。如:

int a=3;
int *p=&a;
  • 1
  • 2

內(nèi)存分配圖示
目前大多數(shù)的C/C++編譯環(huán)境中,整型int數(shù)據(jù)占4個(gè)字節(jié)的空間,如上圖所示。所以指針p存儲(chǔ)的地址(即指向的地址)為1號(hào)內(nèi)存單元(首地址)。
當(dāng)需要讀取一個(gè)例如int型數(shù)據(jù)時(shí),編譯器根據(jù)指針的類(lèi)型從指針指向的地址開(kāi)始向后尋址。指針類(lèi)型不同則尋址范圍也不同,比如:
int*從指定地址向后尋找4字節(jié)作為變量的存儲(chǔ)單元;
double*從指定地址向后尋找8字節(jié)作為變量的存儲(chǔ)單元。

說(shuō)到這里可能大家就會(huì)有一個(gè)問(wèn)題:由于計(jì)算機(jī)內(nèi)部的地址是整型數(shù)字,那么為什么不干脆用一個(gè)整型變量存儲(chǔ)地址,還要發(fā)明指針變量呢?
如果我們從指針實(shí)現(xiàn)的角度講,指針就是一個(gè)整型變量,它存儲(chǔ)的是一個(gè)地址值,沒(méi)有任何附加信息。目前為止貌似沒(méi)有什么問(wèn)題,其實(shí)不然。
就拿上述的代碼:如果用一個(gè)整型變量b存儲(chǔ)a的地址,即int b=&a。當(dāng)對(duì)b加1時(shí),得到的新的地址相當(dāng)于對(duì)a的首地址加1,即&a+1,由于int占連續(xù)的四個(gè)存儲(chǔ)單元(默認(rèn)),此時(shí)b存儲(chǔ)的是第二塊存儲(chǔ)單元的地址,所以根據(jù)變量b存儲(chǔ)的地址,將無(wú)法完整的讀出變量a的值,導(dǎo)致錯(cuò)誤。而通過(guò)指針變量,可以解決這類(lèi)問(wèn)題:如果對(duì)上述代碼中的指針p加1的話(huà),實(shí)際上是p+sizeof(int),一次性增加了4個(gè)存儲(chǔ)單元。

PS.指針本身所占據(jù)的內(nèi)存區(qū) :
  指針本身占了多大的內(nèi)存?你只要用函數(shù)sizeof(指針的類(lèi)型)測(cè)一下就知道了。
  指針的作用是用來(lái)對(duì)內(nèi)存空間進(jìn)行尋址,在32位機(jī)上,所有指針類(lèi)型變量占用內(nèi)存字節(jié)數(shù)都為4,因?yàn)?2位機(jī)是按32位尋址的。如果在64位機(jī)上,指針占用內(nèi)存大小就是:8個(gè)字節(jié)。

無(wú)類(lèi)型指針void*

void *vp;
  • 1

void*是一種特別的指針,因?yàn)樗鼪](méi)有指向的類(lèi)型,或者說(shuō)不能根據(jù)這個(gè)類(lèi)型判斷出指向?qū)ο蟮拈L(zhǎng)度。void *指針具有以下特點(diǎn):

  1. 任何指針(包括函數(shù)指針)都可以賦值給void指針;
 type *p;
  vp=p;
  • 1
  • 2

//不需轉(zhuǎn)換
//只獲得變量/對(duì)象地址而不獲得大小
2. void指針賦值給其他類(lèi)型的指針時(shí)都要進(jìn)行轉(zhuǎn)換;

type * p=(type *)vp;
  • 1

//轉(zhuǎn)換類(lèi)型也就是獲得指向變量/對(duì)象大小
3. void指針在強(qiáng)制轉(zhuǎn)換成具體類(lèi)型前,不能解引用;

 *vp
  • 1

//錯(cuò)誤
//因?yàn)関oid指針只知道,指向變量/對(duì)象的起始地址
//而不知道指向變量/對(duì)象的大小(占幾個(gè)字節(jié))所以無(wú)法正確引用
4. void指針不能參與指針運(yùn)算,除非進(jìn)行轉(zhuǎn)換。

(type*)vp++;
  • 1

//等價(jià)于:vp=vp+sizeof(type)
void*的作用

  1. 傳參:通用類(lèi)型
    可以作為函數(shù)模板,鏈表等參數(shù)的通用參數(shù)。在使用時(shí),只需要強(qiáng)制類(lèi)型轉(zhuǎn)換就可以。
    例如內(nèi)存操作函數(shù)memcpy和memset的函數(shù)原型分別為:
void* memcpy(void *dest, constvoid *src, size_t len);   
void* memset(void *buffer, int c, size_t num);
  • 1
  • 2

這樣,任何類(lèi)型的指針都可以傳入memcpy和memset中,這也真實(shí)地體現(xiàn)了內(nèi)存操作函數(shù)的意義,因?yàn)樗僮鞯膶?duì)象僅僅是一片內(nèi)存,而不論這片內(nèi)存是什么類(lèi)型。

  1. 強(qiáng)制類(lèi)型轉(zhuǎn)換
    有時(shí)候由于重載等的干擾,導(dǎo)致需要轉(zhuǎn)換成void *,來(lái)進(jìn)行取地址。
    例如,(void *)obj.member,就可以取到member的地址;直接&(obj.member)取到的實(shí)際上是obj的開(kāi)始地址。
  2. 指向0的地址
    (void *)0,指向全是0的地址,相當(dāng)于NULL。

下面舉一個(gè)使用void*指針的demo:

#include<iostream>
#include<string>
using namespace std;

typedef struct tag_st
{
    string id;
    float fa[2];
}ST;

int main()
{
    ST* P = new ST;
    P->id = "hello!";
    P->fa[0] = 1.1;
    P->fa[1] = 2.1;

    ST* Q = new ST;
    Q->id = "world!";
    Q->fa[0] = 3.1;
    Q->fa[1] = 4.1;

    void * plink = P;
    *(ST*)(plink) = *Q;  //plink要先強(qiáng)制轉(zhuǎn)換一下,目的是為了讓它先知道要覆蓋的大小
    //P的內(nèi)容被Q的內(nèi)容覆蓋
    cout << P->id << " " << P->fa[0] << " " << P->fa[1] << endl;  
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在寫(xiě)這個(gè)例子的時(shí)候發(fā)生一點(diǎn)小插曲:把第24行:* (ST * )(plink) = * Q; 寫(xiě)成了(ST * )(plink) = Q;結(jié)果編譯報(bào)錯(cuò),剛開(kāi)始以為是void *指針不能被兩次賦值而引發(fā)的錯(cuò)誤。經(jīng)過(guò)研究,得知是因?yàn)閺?qiáng)制類(lèi)型轉(zhuǎn)化操作(目標(biāo)類(lèi)型是引用時(shí)除外)不能作為左值,所以編譯器才會(huì)報(bào)錯(cuò)。另附上一篇介紹左值和右值的博客helloworld的博客

注:關(guān)于void*指針的介紹,參考于wangicter的博客WangIcter的專(zhuān)欄

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    搡老妇女老熟女一区二区| 熟妇久久人妻中文字幕| 免费大片黄在线观看日本| 亚洲av日韩av高潮无打码| 日本精品中文字幕在线视频| 国产级别精品一区二区视频| 亚洲av熟女国产一区二区三区站| 国产av一二三区在线观看| 日本一级特黄大片国产| 国产高清一区二区不卡| 日韩精品一区二区三区av在线| 日韩av欧美中文字幕| 婷婷伊人综合中文字幕| 日韩欧美一区二区不卡看片| 欧美日韩亚洲巨色人妻| 久久精品久久久精品久久| 亚洲国产精品av在线观看| 91偷拍与自偷拍精品| 日韩精品毛片视频免费看| 欧美不卡午夜中文字幕| 国产精品一区二区丝袜| 精品少妇人妻av一区二区蜜桃| 中文字幕五月婷婷免费| 国产精品熟女在线视频| 美女被后入视频在线观看| 日韩欧美高清国内精品| 美女被后入福利在线观看| 九九热国产这里只有精品 | 国产日本欧美特黄在线观看| 狠狠干狠狠操亚洲综合| 日韩精品免费一区二区三区 | 东京热男人的天堂一二三区| 亚洲熟女精品一区二区成人| 国产精品一区欧美二区| 国产内射一级二级三级| 色偷偷亚洲女人天堂观看| 国产午夜精品美女露脸视频| 99日韩在线视频精品免费| 午夜精品久久久99热连载| 麻豆果冻传媒一二三区| 黄色国产一区二区三区|