青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

franksunny的個人技術空間
獲得人生中的成功需要的專注與堅持不懈多過天才與機會。 ——C.W. Wendte

C/C++ 結構體的一個高級特性 ―― 指定成員的位數

?

在大多數情況下,我們一般這樣定義結構體:

struct student

{

????????????? ? unsigned int sex;

????????????? unsigned int age;

};

對于一般的應用,這已經能很充分地實現數據了的 封裝

但是,在實際工程中,往往碰到這樣的情況:那就是要用一個基本類型變量中的不同的位表示不同的含義。譬如一個 cpu 內部的標志寄存器,假設為 16 bit ,而每個 bit 都可以表達不同的含義,有的表示結果是否為 0 ,有的表示是否越界等等。這個時候我們用什么數據結構來表達這個寄存器呢?

答案還是結構體!

為達到此目的,我們要用到結構體的高級特性,那就是在基本成員變量的后面添加“ : 數據位數”組成新的結構體:

struct xxx

{

????????????? 成員 1 類型成員 1 : 成員 1 位數 ;

?????? ????? ? 成員 2 類型成員 2 : 成員 2 位數 ;

?????? ????? ? 成員 3 類型成員 3 : 成員 3 位數 ;

};

基本的成員變量就會被拆分!這個語法在初級編程中很少用到,但是在高級程序設計中不斷地被用到!例如:

struct student

{

????????????? ? unsigned int sex : 1;

????????????? unsigned int age : 15;

};

上述結構體中的兩個成員 sex age 加起來只占用了一個 unsigned int 的空間(假設 unsigned int 16 位)。

基本成員變量被拆分后,訪問的方法仍然和訪問沒有拆分的情況是一樣的,例如:

struct student sweek;

sweek.sex = MALE;// 這里的 MALE 只能是 0 1 ,值不能大于 1

sweek.age = 20;

雖然拆分基本成員變量在語法上是得到支持的,但是并不等于我們想怎么分就怎么分,例如下面的拆分顯然是不合理的:

struct student

{

????????????? ??? unsigned int sex : 1;

????????????? ? unsigned int age : 12;

};

這是因為 1+12 = 13 ,不能再組合成一個基本成員,不能組合成 char int 或任何類型,這顯然是不能 自圓其說 的。

在拆分基本成員變量的情況下,我們要特別注意數據的存放順序,這還與 CPU Big endian 還是 Little endian 來決定。 Little endian Big endian CPU 存放數據的兩種不同順序。對于整型、長整型等數據類型, Big endian 認為第一個字節是最高位字節(按照從低地址到高地址的順序存放數據的高位字節到低位字節);而 Little endian 則相反,它認為第一個字節是最低位字節(按照從低地址到高地址的順序存放數據的低位字節到高位字節)。

我們定義 IP 包頭結構體為:

struct iphdr {

#if defined(__LITTLE_ENDIAN_BITFIELD)

?????? __u8?????? ihl:4,

?????? ?????? version:4;

#elif defined (__BIG_ENDIAN_BITFIELD)

?????? __u8?????? version:4,

???? ?????? ihl:4;

#else

#error?????? "Please fix <asm/byteorder.h>"

#endif

?????? __u8?????? tos;

?????? __u16?????? tot_len;

?????? __u16?????? id;

?????? __u16?????? frag_off;

?????? __u8?????? ttl;

?????? __u8?????? protocol;

?????? __u16?????? check;

?????? __u32?????? saddr;

?????? __u32?????? daddr;

?????? /*The options start here. */

};

Little endian 模式下, iphdr 中定義:

?????? __u8?????? ihl:4,

?????? ?????? version:4;

其存放方式為:

1 字節低 4 ?ihl

1 字節高 4 ?version IP 的版本號)

若在 Big endian 模式下還這樣定義,則存放方式為:

1 字節低 4 ?version IP 的版本號)

1 字節高 4 ?ihl

這與實際的 IP 協議是不匹配的,所以在 Linux 內核源代碼中, IP 包頭結構體的定義利用了宏:

#if defined(__LITTLE_ENDIAN_BITFIELD)

#elif defined (__BIG_ENDIAN_BITFIELD)

#endif

來區分兩種不同的情況。

由此我們總結全文的主要觀點:

1 ?????? C/C++ 語言的結構體支持對其中的基本成員變量按位拆分;

2 ?????? 拆分的位數應該是合乎邏輯的,應仍然可以組合為基本成員變量;

要特別注意拆分后的數據的存放順序,這一點要結合具體的 CPU 的結構。

?

?

?

?

該文是由宋寶華處轉載而來的,筆者以前從未知道結構體還可以這樣用法,筆者做過嘗試,再 VC 下用過的感受有兩點

1、????????????? 結構體按位拆分時,雖然宋兄提醒不能拆分如文中紅色背景顯示的情況,但是本人試過,并非是不可以的,而且如果 CPU 支持 32 的話,顯然文中的以 16 位來分配的話也是沒有達到要求的。

2、????????????? 按位拆分時字節數目問題,我們先看兩例

?????? struct student1

?????? {

????????????? unsigned char sex : 1;

????????????? unsigned int? no : 5;

????????????? char??????? ??age : 7;

????????????? int????????? grade : 10;

?????? };

?

????????????? struct student2

?????? {

????????????? unsigned char sex : 1;

????????????? char??????? ? ?age : 7;

????????????? unsigned int ?no : 5;???????????

????????????? int????????? grade : 10;

?????? };

以上兩例中雖然意思并不大,但是如果按 int 2 字節 16 char 1 字節 8 位來劃分內存的話,那么 student1 占用了 6 字節共 48 位,但是實際使用了 23 位,另外 25 位沒定義,而 student2 占用了 3 字節共 24 位,但是實際使用也是 23 位。這個過程,我把它總結為前后變量的類型不一致時,字節就重新分配。

3、????????????? 賦值過程中數據編碼問題。還看兩例

?????? student1 ss;

?????? ss.age = 255;

?????? student2 st;

?????? st.age= 191;

ss.age 的值為 -1 ,而 st.age 的值為 63 ,其實 255 11111111 ,因為是 7 位,所以采用截斷方式,變成 1111111 ,又因為 age 是有符號的變量,所以根據負數的編碼規則賦值 255 時得到的結果就是 -1 。在這里采用了截斷的方式,為止正確賦值時一定不能大于位數編碼值。

以上是個人學習宋兄文章的小小實踐小結,歡迎大家給出更理論的總結。原文請查看 http://blog.donews.com/21cnbao/archive/2006/10/07/1054807.aspx

posted on 2006-10-20 00:05 frank.sunny 閱讀(6686) 評論(7)  編輯 收藏 引用 所屬分類: C/C++學習和實踐

FeedBack:
# re: C/C++結構體的一個高級特性――指定成員的位數
2006-10-20 13:31 | guest
位域,已經是一個很古老的特性了  回復  更多評論
  
# re: C/C++結構體的一個高級特性――指定成員的位數
2006-10-20 20:34 | 木葉流水
student2 占用了 3 字節?
unsigned char sex : 1;
char age : 7; 分別占一個字節 unsigned int no : 5;
int grade : 10;兩個加起來占一個字節是吧
一共三個字節  回復  更多評論
  
# re: C/C++結構體的一個高級特性――指定成員的位數
2006-10-20 21:04 | frank.sunny
非常感謝樓上不留名的大俠指點,我還算是個新手,謝謝你一語道破了,這只是一個“位域”概念,本人搜索了一下這一概念,發現有一個人總結的還比較可以的
總結如下:
使用位域的主要目的是壓縮存儲,其大致規則為:
1) 如果相鄰位域字段的類型相同,且其位寬之和小于類型的sizeof大小,則后面的字段將緊鄰前一個字段存儲,直到不能容納為止;
2) 如果相鄰位域字段的類型相同,但其位寬之和大于類型的sizeof大小,則后面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數倍;
3) 如果相鄰的位域字段的類型不同,則各編譯器的具體實現有差異,VC6采取不壓縮方式,Dev-C++采取壓縮方式;
4) 如果位域字段之間穿插著非位域字段,則不進行壓縮;
5) 整個結構體的總大小為最寬基本類型成員大小的整數倍。


樓上木葉流水兄,看過這個總結不知道是否有更清晰的了解啊,可以看他網頁
http://blog.csdn.net/jiyucn/archive/2006/07/01/862085.aspx

  回復  更多評論
  
# re: C/C++結構體的一個高級特性――指定成員的位數
2006-10-25 20:17 | 清風雨
這個特性,在現在內存相對充足來說,基本是無所謂的;除非你做嵌入式開發或許有點用(不是做這個的,不了解)。
另外,他會成員的訪問低效;而且加上內存對齊,這里節省的空間又被編譯器為了性能填充的無用字節給浪費了(當然,你可以設置不對齊)。
在現在,這個特性,真的是很古老哦(而且基本無用),也算不上高級啦!
當然,你作為了解了解一下也是好的。
  回復  更多評論
  
# re: C/C++結構體的一個高級特性――指定成員的位數
2006-10-26 09:39 | frank.sunny
@清風雨
其實題目是沿用原作者的,我也是學習用的,他本人就是搞嵌入式的,我覺得這個可以搞懂些變量底層的東西

謝謝大俠關心啊,呵呵  回復  更多評論
  
# re: C/C++結構體的一個高級特性――指定成員的位數
2008-07-01 11:41 | Eagles
學習了!!!!  回復  更多評論
  
# re: C/C++結構體的一個高級特性――指定成員的位數
2009-05-27 15:57 | Alec C.
位域在嵌入式開發中還是很有用的,特別是涉及到底層協議的時候  回復  更多評論
  

常用鏈接

留言簿(13)

隨筆分類

個人其它博客

基礎知識鏈接

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            中国成人亚色综合网站| 亚洲人成久久| 久久综合伊人77777| 欧美在线视频免费观看| 亚洲欧美激情在线视频| 午夜视黄欧洲亚洲| 欧美一级播放| 久久精品一二三区| 久久免费的精品国产v∧| 欧美一区二区视频在线观看2020| 国产精品99久久久久久久vr| 午夜精品久久久99热福利| 欧美一区2区三区4区公司二百 | 欧美超级免费视 在线| 久久久国产精品亚洲一区| 欧美一区二区福利在线| 久久久精品网| 亚洲国产二区| 日韩天堂av| 午夜精品在线看| 久久精品一区二区国产| 久久免费国产精品| 亚洲人成7777| 亚洲欧美国产精品桃花| 卡通动漫国产精品| 欧美日韩一区二区三区高清| 国产真实乱子伦精品视频| 亚洲精美视频| 亚洲字幕一区二区| 欧美超级免费视 在线| 在线视频一区观看| 久久久亚洲国产美女国产盗摄| 欧美国产精品中文字幕| 国产精品一区三区| 亚洲精品在线免费| 狂野欧美一区| 亚洲午夜精品视频| 美女亚洲精品| 国产日韩欧美视频| 亚洲一区二区三区免费观看| 久久五月天婷婷| 这里只有精品电影| 欧美精品免费在线| 亚洲激情网站| 久久国内精品视频| 亚洲视频电影图片偷拍一区| 免费在线观看成人av| 国产日韩一区二区三区在线播放| 日韩视频免费在线观看| 久久夜色撩人精品| 亚洲一区二区在线| 欧美理论在线播放| 亚洲国产美女久久久久| 久久久在线视频| 一本久久a久久精品亚洲| 久久综合99re88久久爱| 欧美亚一区二区| 亚洲国产日韩欧美综合久久| 欧美一区观看| 中文在线资源观看网站视频免费不卡 | 国内外成人在线视频| 一区二区三区 在线观看视频| 久久资源av| 亚洲欧美在线x视频| 国产精品激情| 亚洲综合精品四区| 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲国产99精品国自产| 欧美一级专区| 国产欧美一区二区精品仙草咪| 99精品国产热久久91蜜凸| 欧美成年人视频| 久久久久久一区二区三区| 国产日产精品一区二区三区四区的观看方式 | 欧美一区二视频| 国产精品丝袜91| 午夜国产欧美理论在线播放| 99热在线精品观看| 欧美日韩一区二区视频在线观看| 亚洲精品免费网站| 亚洲精品一区二区三区婷婷月| 欧美高清在线一区二区| 91久久综合亚洲鲁鲁五月天| 欧美黄色免费| 欧美日韩精品欧美日韩精品| 亚洲一区二区精品| 亚洲女人天堂av| 国产视频久久久久| 农夫在线精品视频免费观看| 欧美韩日高清| 亚洲欧美激情四射在线日 | 亚洲精品国产精品乱码不99 | 亚洲区国产区| 国产精品国产三级欧美二区| 亚洲欧美日韩在线观看a三区| 亚洲视频一二| 国产亚洲在线| 亚洲国产精品va在线观看黑人| 欧美激情偷拍| 欧美一区二区三区电影在线观看| 亚洲欧美在线免费| 亚洲高清电影| 亚洲图色在线| 亚洲第一精品久久忘忧草社区| 欧美激情精品久久久久久大尺度| 日韩视频在线观看国产| 久久久久综合一区二区三区| 亚洲福利专区| 亚洲午夜精品一区二区三区他趣| 一区在线播放视频| 亚洲私人影院| 亚洲破处大片| 欧美亚洲一区二区在线| 亚洲乱码国产乱码精品精可以看| 亚洲一区www| 亚洲国产视频一区| 性欧美暴力猛交另类hd| 夜夜嗨av一区二区三区| 久久久久久91香蕉国产| 亚洲一区尤物| 欧美电影免费观看大全| 久久精品国产亚洲高清剧情介绍 | 久久精品视频在线看| 亚洲网友自拍| 久久久久综合网| 欧美在线影院| 欧美日韩国产欧美日美国产精品| 欧美一区二区福利在线| 欧美日本乱大交xxxxx| 另类激情亚洲| 国产视频在线观看一区| 亚洲免费高清视频| 亚洲三级毛片| 美女图片一区二区| 久久综合国产精品台湾中文娱乐网| 欧美日韩国产综合视频在线| 欧美国产日韩一二三区| 黄色一区二区三区四区| 亚洲欧美区自拍先锋| 亚洲摸下面视频| 欧美午夜在线视频| 日韩亚洲视频在线| 中文一区字幕| 欧美午夜精品久久久久久超碰| 亚洲精品免费网站| aa级大片欧美| 欧美另类人妖| 亚洲精品视频中文字幕| 一区二区精品| 欧美午夜免费电影| 亚洲香蕉成视频在线观看 | 久久综合精品一区| 国产日韩在线亚洲字幕中文| 亚洲欧美另类在线观看| 久久精品国产视频| 在线精品国产欧美| 久久频这里精品99香蕉| 欧美成人自拍| 欧美无乱码久久久免费午夜一区| 亚洲高清免费视频| 一本高清dvd不卡在线观看| 欧美日韩xxxxx| 在线一区二区三区四区| 欧美一区二区日韩| 一区二区视频免费完整版观看| 久久久久久夜| 亚洲伦理在线免费看| 亚洲尤物在线视频观看| 国产乱理伦片在线观看夜一区| 欧美一区深夜视频| 亚洲国产成人av好男人在线观看| 快she精品国产999| 亚洲精品美女免费| 欧美亚洲一区| 精品999在线观看| 免费欧美视频| 一本色道久久加勒比88综合| 欧美综合第一页| 最新国产成人在线观看| 国产精品高潮在线| 久久久久久穴| 亚洲性线免费观看视频成熟| 久久综合狠狠综合久久激情| 国产精品视频第一区| 久久av一区二区三区亚洲| 亚洲国产欧美日韩精品| 亚洲欧美激情四射在线日| 激情成人综合| 国产精品久久久久久av下载红粉| 久久精品伊人| 夜夜爽99久久国产综合精品女不卡| 欧美一区二区精品久久911| 亚洲日本欧美天堂| 国产三级欧美三级| 欧美—级a级欧美特级ar全黄| 亚洲一级黄色| 亚洲国产精品一区二区第四页av| 香蕉久久夜色精品国产| 夜夜嗨av一区二区三区网页| 狠狠入ady亚洲精品|