免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
位段類型

1.什么是位段

在前面各章中, 我們已經(jīng)討論過(guò)字節(jié)概念了。在大多數(shù)的計(jì)算機(jī)系統(tǒng)中, 一個(gè)字節(jié)是由八個(gè)更小的, 稱作為位的單位組成的。位是比字節(jié)更小的單位。位只有兩個(gè)值, 10 。因此, 存儲(chǔ)在計(jì)算機(jī)存儲(chǔ)器中的一個(gè)字節(jié)可以看成由八個(gè)二進(jìn)制數(shù)字形成的串。

例如, 一個(gè)存放值 36 的字節(jié)是八個(gè)二進(jìn)制數(shù)字的串: 可以表示成 00100100。 存入值24 的字節(jié)可以表示成 00010100。

有時(shí), 我們希望不僅對(duì)字節(jié)進(jìn)行操作, 也要能對(duì)位進(jìn)行操作。例如, 用布爾真或假條件表示的標(biāo)志, 在計(jì)算機(jī)中可用位來(lái)表示。

但是, 說(shuō)明一個(gè)用作標(biāo)志的普通變量至少要用一個(gè)字節(jié)---8 位, 而在某些計(jì)算機(jī)系統(tǒng)中則可能是 16 位。 如果我們想在一個(gè)很大的表中存儲(chǔ)很多標(biāo)志, 那么 "被浪費(fèi)" 的內(nèi)存空間是很可觀的。在 C 語(yǔ)言中, 一種方法是用叫做位段的構(gòu)造類型來(lái)定義一個(gè)壓縮信息的結(jié)構(gòu)。

什么是位段呢? 位段是 C 語(yǔ)言特有的數(shù)據(jù)結(jié)構(gòu), 它允許我們定義一個(gè)由位組成的段, 并可為它賦以一個(gè)名字。

返回頁(yè)首


2.位段的用法

我們已經(jīng)了解什么是位段了, 現(xiàn)在我們繼續(xù)討論位段的使用方法。

先看一個(gè)例子: 我們需要用到五個(gè)變量。 假定, 其中三個(gè)用作標(biāo)志, 稱為 f1, f2 和 f3。
第四個(gè)稱為 type, 取值范圍為 1 至 12。 最后一個(gè)變量稱為 index, 值的范圍為 0 至 500。

通常, 我們用下面的語(yǔ)句來(lái)說(shuō)明這些變量:
char f1,f2,f3;
unsigned int type;
unsigned int index;

但是, 實(shí)際上標(biāo)志 f1, f2, f3 分別只需要 1 位。變量 type 只需要 4 位, 而變量 index 只需要 9 位。 總共是 16位 ---- 2 個(gè)字節(jié)。我們用兩個(gè)字節(jié)就夠了。

我們可這樣來(lái)做:
struct packed_struct
{
    unsigned int f1 :1;
    unsigned int f2 :1;
    unsigned int f3 :1;
    unsigned int type :4;
    unsigned int index :9;
};


該例中, 我們定義了一個(gè)結(jié)構(gòu) packed_struct。該結(jié)構(gòu)定義了五個(gè)成員。第一個(gè)成員叫做 f1, 是 unsigned int 類型的。緊跟在該成員名之后的 :1 規(guī)定了它以 1 位存放。類似地, 標(biāo)志 f2 和 f3 被定義為長(zhǎng)度只有 1 位的。定義成員 type 占有 4 位。定義成員 index 占有 9 位。C 編譯器自動(dòng)地把上面的位段定義壓縮在一起。位段的劃分如圖所示。packed_struct 總共使用了 16 位。

這種方法的好處是, 定義成 packed_struct 類型的變量的位段, 可以如引用一般的結(jié)構(gòu)成員一樣方便地引用。同時(shí), 使用了更少的內(nèi)存單元數(shù)。

我們已經(jīng)定義了一個(gè)稱作為 packed_struct 的包含著位段的結(jié)構(gòu)?,F(xiàn)在, 我們象下面那樣定義一個(gè)稱作為 packet_data 的變量: struct packed_struct packed_data; 于是, 我們就可以用簡(jiǎn)單的語(yǔ)句, 把 packed_data 的 type 位段設(shè)置為 7:
packed_data.type = 7; 類似地, 我們可以用下面的語(yǔ)句把這個(gè)位段的值設(shè)為 n:
packed_data.type = n; 我們不必?fù)?dān)心 n 的值太長(zhǎng), 以致不能放入 type 位段中, C 編譯器會(huì)自動(dòng)地僅取出 n 的低四位, 把它賦值給 packed_data.type。取出位段的值也自動(dòng)地處理的, 因此語(yǔ)句 n = packed_data.type; 將從 packed_data 中取出 type 位段, 并把它的值賦給 n。

在一般的表達(dá)式中可以使用位段, 此時(shí), 位段自動(dòng)地轉(zhuǎn)換成整數(shù)。因此, 表達(dá)式
i = packed_data.index/5+1; 是完全有效的。

在包含位段的結(jié)構(gòu)中, 也可以包括 "通常的" 數(shù)據(jù)類型。因此, 如果我們想定義一個(gè)結(jié)構(gòu), 它包含一個(gè) int, 一個(gè) char, 和二個(gè) 1 位的標(biāo)志, 那么, 下面的定義是有效的:
struct table_entry
{
    int     count ;
    char     c;
    unsigned int f1 :1;
    unsigned int f2 :1;
};


當(dāng)位段出現(xiàn)在結(jié)構(gòu)定義中時(shí), 它們就被壓縮成字。如果某個(gè)位段無(wú)法放入一個(gè)字中, 那么該字的剩余部分跳過(guò)不用, 該位段被放入下一個(gè)字中。

使用位段時(shí), 必須注意下列事項(xiàng):

  • 在某些機(jī)器上, 位段總是作為 unsigned 處理, 而不管它們是否被說(shuō)明成 unsigned 的。
  • 大多數(shù)C 編譯器都不支持超過(guò)一個(gè)字長(zhǎng)的位段。
  • 位段不可標(biāo)明維數(shù); 即, 不能說(shuō)明位段數(shù)組, 例如 flag:l[2]。
  • 最后, 不可以取位段地址。原因是, 在這種情況不, 顯然沒(méi)有稱作為 "位段指針" 類型的變量。

這里, 我們?cè)偕钊胗懻撘幌挛欢?。如果使用下面的結(jié)構(gòu)定義:

struct bits
{
    unsigned int f1:1;
    int     word;
    unsigned int f3:1;
};

那么, 位段是怎樣壓縮的呢? 由于成員 word 出現(xiàn)于其間, 故 f1, f3 不會(huì)壓縮在同一個(gè)字內(nèi)。C 編譯器不會(huì)重新安排位段定義來(lái)試圖優(yōu)化存儲(chǔ)空間。

可以指定無(wú)名位段, 使得一個(gè)字中的某些位被 "跳過(guò)"。因此, 定義:
struct x_entry
{
    unsigned int type :4;
    unsigned int :3;
    unsigned int count :9;
};

將定義一個(gè)結(jié)構(gòu) x_entry, 它包含兩個(gè)位段變量 type 和 count, 而無(wú)名位段規(guī)定了 type 和 count 間隔三位。

返回頁(yè)首


3.練習(xí)題

練習(xí)題一

練習(xí)題二

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
字節(jié)對(duì)齊詳解
_attribute_((packed))
c/c++ struct union 對(duì)齊方式與#pragma pack()宏定義
[轉(zhuǎn)載]c語(yǔ)言struct結(jié)構(gòu)體的變量聲明加冒號(hào)
細(xì)說(shuō)結(jié)構(gòu)字節(jié)對(duì)齊
GNU C 擴(kuò)展之__attribute__ 機(jī)制簡(jiǎn)介|GNU,C 擴(kuò)展,__attribute__ 機(jī)制
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服