日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

C/C++ 中的0長數(shù)組(柔性數(shù)組)

 zhouADNjj 2014-04-14

在標(biāo)準(zhǔn)CC++0長數(shù)組如charArray[0]是不允許使用的,因為這從語義邏輯上看,是完全沒有意義的。

但是,GUN中卻允許使用,而且,很多時候,應(yīng)用在了變長結(jié)構(gòu)體中,如:

StructPacket

{

Int state;

Int len;

Char cData[0]; //這里的0長結(jié)構(gòu)體就為變長結(jié)構(gòu)體提供了非常好的支持

};

 

首先對0長數(shù)組做一個解釋:

用途 :長度為0的數(shù)組的主要用途是為了滿足需要變長度的結(jié)構(gòu)體。

用法 :在一個結(jié)構(gòu)體的最后 ,申明一個長度為0的數(shù)組,就可以使得這個結(jié)構(gòu)體是可變長的。對于編譯器來說,此時長度為0的數(shù)組并不占用空間,因為數(shù)組名本身不占空間,它只是一個偏移量, 數(shù)組名這個符號本身代 表了一個不可修改的地址常量 (注意:數(shù)組名永遠(yuǎn)都不會是指針! ),但對于這個數(shù)組的大小,我們可以進(jìn)行動態(tài)分配

 

請仔細(xì)理解后半部分,對于編譯器而言,數(shù)組名僅僅是一個符號,它不會占用任何空間,它在結(jié)構(gòu)體中,只是代表了一個偏移量,代表一個不可修改的地址常量!

 

對于0長數(shù)組的這個特點,很容易構(gòu)造出變成結(jié)構(gòu)體,如緩沖區(qū),數(shù)據(jù)包等等:

Struct Buffer

{

Int len;

Char cData[0];

};

這樣的變長數(shù)組常用于網(wǎng)絡(luò)通信中構(gòu)造不定長數(shù)據(jù)包,不會浪費(fèi)空間浪費(fèi)網(wǎng)絡(luò)流量,比如我要發(fā)送1024字節(jié)的數(shù)據(jù),如果用定長包,假設(shè)定長包的長度為2048,就會浪費(fèi)1024個字節(jié)的空間,也會造成不必要的流量浪費(fèi)

Struct packet

{

    char data[2048];

}

packet p;

memcpy(p.data,"1024 datas.........",1024)

send(socket,(char*)&p,sizeof(p));

由于考慮到數(shù)據(jù)的溢出,變長數(shù)據(jù)包中的data數(shù)組長度一般會設(shè)置得足夠長足以容納最大的數(shù)據(jù),因此packet中的data數(shù)組很多情況下都沒有填滿數(shù)據(jù),因此造成了浪費(fèi),而如果我們用變長數(shù)組來進(jìn)行封包的話,就不會造成浪費(fèi)(最多會造成4個字節(jié)的浪費(fèi),包頭的int型的len不屬于數(shù)據(jù)因此算是浪費(fèi)),如前面的Buffer結(jié)構(gòu)體,假如我們要發(fā)送1024個字節(jié),我們?nèi)绾螛?gòu)造這個數(shù)據(jù)包呢:

char *tmp = (char*)malloc(sizeof(Buffer)+1024) //這句代碼的作用是申請一塊連續(xù)的內(nèi)存空間,這塊內(nèi)存空間的長度是Buffer的大小加上1024數(shù)據(jù)的大小,由兩部分構(gòu)成,sizeof(Buffer)和1024,如果仔細(xì)觀察的話,會發(fā)現(xiàn)這種申請方法比第一種多了一段sizeof(Buffer)大小的空間,原因何在?如下

Buffer *p = (Buffer*)tmp;

p->len = 1024;

memcpy(p.cData,"1024 datas............",1024);

如上三行代碼,首先做一個強(qiáng)制類型轉(zhuǎn)換,Buffer類型的指針指向內(nèi)存的起始位置,這段內(nèi)存要分兩部分使用,前部分4個字節(jié)p->len,作為包頭(就是多出來的那部分),這個包頭是用來描述緊接著包頭后面的數(shù)據(jù)部分的長度,這里是1024,所以前四個字節(jié)賦值為1024(既然我們要構(gòu)造不定長數(shù)據(jù)包,那么這個包到底有多長呢,因此,我們就必須通過一個變量來表明這個數(shù)據(jù)包的長度,這就是len的作用),而緊接其后的內(nèi)存是真正的數(shù)據(jù)部分,通過p->cData定位到該部分的起始地址,最后,進(jìn)行一個memcpy()內(nèi)存拷貝,把要發(fā)送的數(shù)據(jù)填入到這段內(nèi)存當(dāng)中,最后:

send(socket,p,sizeof(Buffer)+1024);發(fā)送數(shù)據(jù)

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多