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

Thronds

一問你會(huì)什么 二問你做出過什么 三問你為了什么

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  36 隨筆 :: 0 文章 :: 56 評(píng)論 :: 0 Trackbacks
    在求職筆試中,C中的位域是一個(gè)常考點(diǎn),特別是在嵌入式軟件中更常見。位域的最大好處是可以根據(jù)自己需要定制位數(shù),從而節(jié)省空間,例如:嵌入式編程稀缺的內(nèi)存資源。還有在網(wǎng)絡(luò)通訊中,對(duì)頭信息部分的結(jié)構(gòu)定義也常用到位域,少傳一位是一位啊。
    這里來分析EMC的一道筆試題(07年招聘試題):
1 typedef struct bitstruct 2 { 3 int b1:5; 4 int :2; 5 int b2:2; 6 }bitstruct; 7 int main(int argc, char *argv[]) 8 { 9 bitstruct b; 10 printf("%d\n",sizeof(bitstruct)); 11 memcpy(&b,"EMC Examination",sizeof(b)); 12 printf("%d,%d\n",b.b1,b.b2); 13 return 0; 14 }
請(qǐng)問在little-endian systems(系統(tǒng)默認(rèn)的存放順序)中,輸出結(jié)果是什么?
答案是
4 
5-2

所需知識(shí)點(diǎn):
1.位域的概念和特點(diǎn)
    C語言允許在一個(gè)結(jié)構(gòu)體中以位為單位來指定其成員所占內(nèi)存長(zhǎng)度,這種以位為單位的成員稱為“位段”或稱“位域”(bit field)。(1)位段成員的類型必須指定為unsigned或int類型;(2)若某一位段要從另一個(gè)字開始存放,用:0長(zhǎng)度為0的空位段,作用就是使下一個(gè)位段從下一個(gè)存儲(chǔ)單位(視不同編譯系統(tǒng)而異)開始存放;(3)一個(gè)位段必須存儲(chǔ)在同一存儲(chǔ)單元中,不能跨兩個(gè)單元;(4)可以定義無名字段例如":2";(5)位段的長(zhǎng)度不能大于存儲(chǔ)單元的長(zhǎng)度,也不能定義位段數(shù)組;(6)位段可以用整形格式符輸出;(7)位段可以在數(shù)值表達(dá)式中引用,它會(huì)被系統(tǒng)自動(dòng)地轉(zhuǎn)換成整形數(shù)。[1][3]

2.Little-endian systems的內(nèi)存布局特點(diǎn)
   
    先問一個(gè)問題:Endian這個(gè)詞是什么意思?

    “endian”這個(gè)詞出自《格列佛游記》。小人國(guó)的內(nèi)戰(zhàn)就源于吃雞蛋時(shí)是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發(fā)生過六次叛亂,其中一個(gè)皇帝送了命,另一個(gè)丟了王位。

    我們一般將endian翻譯成“字節(jié)序”,將big endian和little endian稱作“大尾”和“小尾”。這也在當(dāng)今的CPU派別中一樣存在。Motorola的PowerPC系列CPU采用的Big-endian, Intel的X86系列CPU采用的是Little-endian。Little-endian的特點(diǎn)是高高低低,即高位地址存放最高有效字節(jié),低位地址存放最低有效字節(jié);而Big-endian正好相反。下面用圖的方式說明起來更直觀,例如0x12345678(特別注意,這是單個(gè)數(shù),不是字符串,如果是字符串就不一定這樣了。之前沒有特別注意這點(diǎn),害的我多花了冤枉時(shí)間)。
Big Endian

   低地址                                            高地址
   ----------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     12     |      34    |     56      |     78    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

   低地址                                            高地址
   ----------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     78     |      56    |     34      |     12    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    上面的字節(jié)序的不同,在單機(jī)的操作中沒有問題,因?yàn)橐慌_(tái)單機(jī)就是采用單一的字節(jié)序嘛!但是在兩個(gè)不同的主機(jī)進(jìn)行協(xié)作時(shí),就會(huì)出現(xiàn)問題了;另外在網(wǎng)絡(luò)通訊中也同樣會(huì)出現(xiàn)問題,詳細(xì)參考[2]

就單個(gè)字節(jié)而言,也會(huì)有這樣的問題:比特序有差別嗎?

    也分成兩種序,如果我們處理的基本單位是字節(jié)以上的話,對(duì)此就不必?fù)?dān)心了,因?yàn)镃PU存儲(chǔ)操作的最小單元是字節(jié),所以比特位的順序?qū)ξ覀儊砭褪峭该鞯模覀冊(cè)谧x取某個(gè)字節(jié)時(shí),不管它用的是Big endian 還是Little endian,我們讀到的都是一個(gè)同樣的字節(jié),只不過硬件在讀寫時(shí)的順序,一個(gè)是從高到底另一個(gè)是從低到高,對(duì)我們的使用不產(chǎn)生影響。但是如果涉及到位域的存放問題,還是要特別小心,上面這道題就是一個(gè)非常的好的例子。

Big Endian

   msb                                                         lsb
   ---------------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   1  |   0  |   1  |   1  |   0  |   1  |   0  |   0  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

   lsb                                                         msb
   ---------------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   0  |   0  |   1  |   0  |   1  |   1  |   0  |   1  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


3.memcpy()與strcpy()的區(qū)別
    這個(gè)問題很簡(jiǎn)單,可以想象成這樣:memcpy的基本單位是位,strcpy的基本單位是字符。所以,memcpy會(huì)根據(jù)提供的長(zhǎng)度完全按位拷貝,而strcpy是兩個(gè)字符串之間的拷貝。

    回來原來的問題上,在采用little endian的BUS64中,struct bitstruct在沒涉及到高低位問題時(shí),也就是我們平時(shí)常會(huì)畫出的一種形式是:
{b1 b1 b1 b1 b1 Ø Ø b2   b2 Ø Ø Ø Ø Ø Ø Ø    ØØØØØØØØ   ØØØØØØØØ};
在內(nèi)存中的實(shí)際布局是:

   低地址                                                 高地址
   -------------------------
------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+
   | b2 Ø Ø b1 b1 b1 b1 b1 |Ø Ø Ø Ø Ø Ø Ø b2 |ØØØØØØØØ |ØØØØØØØØ |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+

Ø表示空填充,這當(dāng)中包含一個(gè)原則:一個(gè)位域的存放不可以跨字存放,但可以跨字節(jié)存儲(chǔ);這里采用的比特續(xù)也是little endian,說明了比特序?qū)Σ僮饕彩怯杏绊懙穆铮?br>
    memcpy按位拷貝“EMC Examination”到b中,一個(gè)字符是8位; 又因?yàn)閟izeof(b)=4,所以只寫入"EMC "。"EMC "對(duì)應(yīng)的位序列是:{0100 0101  0100 1101  0100 0011  0010 0000},從這里寫到內(nèi)存里的形式是:(在這里不要被little endian給迷惑了,E不是放在高地址,參看上面紅色的特別注意

   低地址                                                 高地址
   -------------------------
------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+
   | b2 Ø Ø b1 b1 b1 b1 b1 |Ø Ø Ø Ø Ø Ø Ø b2 |ØØØØØØØØ |ØØØØØØØØ |
   | 0  1 0 0  0  1 0  1 |0  1  0  0 1  1 0  1 |0100 0011     |0010 0000    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

printf("%d,%d\n",b.b1,b.b2);讀出來的b1是00101,它的值是5; b2是10,轉(zhuǎn)換成十進(jìn)制是-2。


到了這一步,似乎題目已經(jīng)解答出來了,但還有兩個(gè)地方有疑惑:
1.struct bitstruct在內(nèi)存中的位存放順序是這樣的么?
   低地址                                                 高地址
   -------------------------
------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+
   | b2 Ø Ø b1 b1 b1 b1 b1 |Ø Ø Ø Ø Ø Ø Ø b2 |ØØØØØØØØ |ØØØØØØØØ |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.memcpy函數(shù)在按位拷貝時(shí)的拷貝順序是這樣的么?
   低地址                                                 高地址
   -------------------------
------------------------------------->
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-+-+-+-+-+-+-+-+-+
   | 01000101 | 01001101 |0100 0011 |0010 0000 |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
關(guān)于上面兩個(gè)問題的驗(yàn)證工作留給路過的朋友來做:-P .....  歡迎批評(píng)指正

[1]譚浩強(qiáng) C程序設(shè)計(jì) 第二版 清華大學(xué)出版社
[2]http://blog.csdn.net/sunshine1314/archive/2008/04/20/2309655.aspx
[3]http://topic.csdn.net/t/20061207/10/5212742.html#
[4]http://elanso.com/ArticleModule/LmT3M6M6HGKzTDQcPKMGKAIi.html
[5]關(guān)于字節(jié)序與編碼的關(guān)聯(lián)請(qǐng)參考http://elanso.com/ArticleModule/LmT3M6M6HGKzTDQcPKMGKAIi.html
posted on 2008-12-06 16:17 thronds 閱讀(6325) 評(píng)論(9)  編輯 收藏 引用 所屬分類: C++技術(shù)面試題

評(píng)論

# re: C中的位域 2009-12-08 22:54 haohaoking
哥們,你這文章寫得,還是刪除了吧~  回復(fù)  更多評(píng)論
  

# re: C中的位域 2010-06-20 00:20 bobluo
寫得很好,圖文并茂,但是有點(diǎn)問題。
你的結(jié)果是對(duì)的,但是內(nèi)存布局反了:
實(shí)際的內(nèi)存布局:
低地址 高地址
-------------------------------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| b1 b1 b1 b1 b1 Ø Ø b2 | b2 Ø Ø Ø Ø Ø Ø Ø |ØØØØØØØØ |ØØØØØØØØ |
| 1 0 1 0 0 0 1 0 |1 0 1 1 0 0 1 0 |11000010|00000100|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

1)b1對(duì)應(yīng)的內(nèi)存內(nèi)容為
(低地址)--------->(高地址)
101000
在little-endian里面比特序的低地址的bit是低有效位,高地址的bit是高有效位,因此對(duì)應(yīng)的數(shù)值要反過來看,為0x000101,即5
2)b2對(duì)應(yīng)的內(nèi)存內(nèi)容為
(低地址)--------->(高地址)
01
同樣,對(duì)應(yīng)的數(shù)值為0x10,即-2。

當(dāng)然,你這樣的話ascii碼都是從左向右讀(低地址在左),比較符合人的習(xí)慣,但是little-endian的話,ascii碼在內(nèi)存中的實(shí)際布局正好相反。而位域無論大小端序,都是從低地址到高地址依次存放的,不會(huì)出現(xiàn)你說的這種b2的兩位相隔如此之遠(yuǎn)的情況,這和位域本身的目的背道而馳
  回復(fù)  更多評(píng)論
  

# re: C中的位域 2010-06-20 00:29 bobluo
另外有個(gè)錯(cuò)誤,你專門用紅色標(biāo)出來的特別注意是錯(cuò)的,strcpy和memcpy的結(jié)果是一樣的,不存在你所說的差別。都是按字節(jié)拷貝,而且字節(jié)在內(nèi)存中的比特序受大小端序的影響。而非你說的不要受小端序迷惑。如果是大端序,那么是
低地址 高地址
-------------------------------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| b1 b1 b1 b1 b1 Ø Ø b2 |b2 Ø Ø Ø Ø Ø Ø Ø |ØØØØØØØØ |ØØØØØØØØ |
| 0 1 0 0 0 1 0 1 |0 1 0 0 1 1 0 1 |0100 0011|0010 0000|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  回復(fù)  更多評(píng)論
  

# re: C中的位域 2010-11-25 10:26 newmalloc
其實(shí),這個(gè)問題不用搞得那么復(fù)雜;
每個(gè)bit在內(nèi)存中的分布順序,在拷貝的時(shí)候由Memcpy來負(fù)責(zé)對(duì)齊,我們要弄清的是b1的5 bits是字節(jié)的低位開始分布的,那么只需要知道E的asic是0x45,找到最低5位,即00101b,即可知道b1=5;b2也是同樣的道理  回復(fù)  更多評(píng)論
  

# re: C中的位域 2011-09-08 12:41 digdeep126
#include <stdio.h>
struct mystr_t {
unsigned short f1:12;
unsigned short f2: 4;
};
int main()
{
struct mystr_t st;
unsigned char *pst;

st.f1 = 0xFFF;
st.f2 = 0x9;

pst = (unsigned char *)&st;
printf("%x %x\n", pst[0], pst[1]);

return 0;
}
結(jié)果顯示為:
FF 9F

按照你們的理解,請(qǐng)解釋這里的結(jié)果(gcc編譯運(yùn)行)。

原因是:
編譯器調(diào)整了 struct mystr_t。編譯將f2放到前面去了,而f1放到了后面。還有由于cpu是小端序。

所以說,位域在內(nèi)存中的存放,要看情況,并不是一定是“在little-endian里面比特序的低地址的bit是低有效位,高地址的bit是高有效位”!  回復(fù)  更多評(píng)論
  

# re: C中的位域 2012-09-21 18:26 拉拉
@bobluo
這哥們別隨便說別人不對(duì),根據(jù)我的機(jī)器驗(yàn)證,樓主說的內(nèi)存布局是很正確的。  回復(fù)  更多評(píng)論
  

# re: C中的位域 2012-09-21 18:31 拉拉
@digdeep126
真正的原因是:內(nèi)存布局為(第一字節(jié))f1 f1 f1 f1 f1 f1 f1 f1,(第二字節(jié))f2 f2 f2 f2 f1 f1 f1 f1, 按字節(jié)取當(dāng)然就是 ff 9f 啦  回復(fù)  更多評(píng)論
  

# re: C中的位域 2012-09-21 18:32 拉拉
但是這里的 -2 是怎會(huì)回事?求指教,為什么一定是負(fù)的?  回復(fù)  更多評(píng)論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美国产先锋| 欧美 日韩 国产 一区| 国产精品久久久久9999| 欧美区亚洲区| 国产精品日韩欧美| 亚洲成色精品| 亚洲精品免费观看| 夜夜嗨av色一区二区不卡| 一本久久青青| 欧美在线一二三四区| 老鸭窝91久久精品色噜噜导演| 美女福利精品视频| 日韩视频国产视频| 欧美影视一区| 欧美另类在线播放| 国产视频一区在线| 亚洲精品乱码| 久久精品免费播放| 亚洲成人自拍视频| 亚洲一区二区成人在线观看| 久久精品午夜| 欧美涩涩视频| 久久精品官网| 亚洲欧美日韩电影| 国产精品久久久久9999| 国产精品毛片大码女人| 国产一区自拍视频| 日韩视频一区二区三区在线播放免费观看 | 亚洲一级黄色| 久久久久久97三级| 欧美日韩性生活视频| 国产一区二区三区久久悠悠色av | 久久精品国产99精品国产亚洲性色 | 制服丝袜亚洲播放| 久热精品视频| 国产精品美女| 日韩亚洲精品电影| 免费在线日韩av| 亚洲专区在线| 欧美午夜女人视频在线| 亚洲另类在线一区| 女同性一区二区三区人了人一 | 最新日韩av| 久久亚洲精品一区| 国产一区二区三区在线观看免费| 亚洲图片在线观看| 亚洲欧洲一区二区在线播放 | 久久免费精品视频| 国产日韩欧美一二三区| 亚洲一区二区高清| 99在线精品视频| 欧美日韩在线精品| 在线视频欧美精品| 日韩视频二区| 欧美色视频在线| 99热免费精品在线观看| 亚洲国产精品久久久久婷婷884| 欧美在线观看一二区| 国产精品推荐精品| 欧美一级免费视频| 亚洲欧美中文另类| 国产欧美日韩在线视频| 午夜一区在线| 西瓜成人精品人成网站| 国产亚洲精品成人av久久ww| 欧美在线观看视频在线| 久久国产精品久久久久久电车| 免费不卡亚洲欧美| 久久久一本精品99久久精品66| 国产一区二区丝袜高跟鞋图片| 午夜天堂精品久久久久| 亚洲女女女同性video| 国产精品任我爽爆在线播放 | 亚洲高清资源| 亚洲欧洲日本mm| 欧美性猛交视频| 欧美亚洲日本网站| 久久精品视频在线| 国内精品伊人久久久久av影院| 99亚洲一区二区| 欧美日韩一区二区三区四区五区 | 国产精品扒开腿爽爽爽视频 | 国产欧美日韩精品a在线观看| 一级日韩一区在线观看| 一区二区三区精品在线| 欧美日韩一区二区三区视频 | 欧美成人免费小视频| 一区二区三区视频在线| 一区二区自拍| 欧美日韩不卡在线| 欧美一区日本一区韩国一区| 久热精品视频在线观看| 亚洲尤物在线视频观看| 久久久久这里只有精品| 欧美精品一卡二卡| 国产精品日韩精品欧美精品| 久久精品视频在线播放| 欧美+亚洲+精品+三区| 亚洲午夜一区二区三区| 久久精品国产清高在天天线| 日韩香蕉视频| 久久国产精品72免费观看| 亚洲美女中出| 久久av一区二区三区漫画| 一本一本a久久| 久久精品一区二区国产| 亚洲午夜一区二区| 猛男gaygay欧美视频| 欧美gay视频| 午夜精品久久一牛影视| 欧美成人高清视频| 中文日韩在线| 一本色道久久88亚洲综合88| 伊人天天综合| 欧美一区二区私人影院日本| 一区二区三区久久| 亚洲一区激情| 激情成人av在线| 夜夜嗨av一区二区三区四区| 怡红院av一区二区三区| 亚洲视频免费在线| 99在线精品观看| 美女任你摸久久| 毛片基地黄久久久久久天堂| 国产精品毛片高清在线完整版 | 久久国产精品网站| 夜夜夜久久久| 亚洲男人的天堂在线| 欧美成人资源| 欧美成人亚洲| 在线观看三级视频欧美| 久久久精品欧美丰满| 久久久久久伊人| 国产一区二区三区最好精华液| 一区二区三区www| 亚洲一区二区欧美日韩| 欧美午夜片在线免费观看| 99re8这里有精品热视频免费 | 亚洲午夜国产一区99re久久| 欧美久久精品午夜青青大伊人| 亚洲国产精品ⅴa在线观看| 亚洲风情亚aⅴ在线发布| 久久大综合网| 欧美成人午夜免费视在线看片 | 亚洲成人原创| 免费观看成人| 日韩视频一区二区| 亚洲欧美日本国产有色| 国产精品女主播一区二区三区| 亚洲午夜精品久久久久久浪潮| 午夜精品影院| 激情国产一区| 欧美在线免费视频| 99精品国产一区二区青青牛奶| 国产亚洲欧洲一区高清在线观看 | 欧美wwwwww| 亚洲第一区中文99精品| 媚黑女一区二区| 99re6这里只有精品| 欧美一区二区三区四区夜夜大片| 亚洲精品偷拍| 亚洲欧美日韩另类| 噜噜噜91成人网| 亚洲国产精品一区在线观看不卡| 老牛嫩草一区二区三区日本 | 亚洲三级性片| 国产精品久久久亚洲一区| 欧美一区1区三区3区公司| 蜜桃av一区二区三区| 日韩视频一区二区在线观看| 国产精品欧美一区二区三区奶水| 欧美一级片在线播放| 欧美激情精品久久久久久蜜臀 | 国产精品mm| 久久高清免费观看| 91久久精品久久国产性色也91| 亚洲欧美经典视频| 亚洲国产欧美日韩精品| 国产精品第三页| 免费成人小视频| 小黄鸭精品aⅴ导航网站入口| 亚洲高清免费| 久久精品99国产精品日本| 亚洲欧洲在线观看| 国产午夜精品一区二区三区欧美 | 久久久噜噜噜久噜久久| 亚洲桃花岛网站| 亚洲国产精品女人久久久| 久久精品亚洲热| 亚洲深夜福利| 亚洲欧洲一区| 伊人春色精品| 国产乱码精品一区二区三区不卡| 男女精品网站| 久久久久国产成人精品亚洲午夜| av成人老司机| 亚洲看片一区| 亚洲人成在线观看| 亚洲电影中文字幕| 免费看成人av|