計(jì)算機(jī)中的信息表示

閱讀經(jīng)典——《深入理解計(jì)算機(jī)系統(tǒng)》02

  1. 基本數(shù)據(jù)類型
  2. 大小端模式
  3. 整型數(shù)范圍與C標(biāo)準(zhǔn)
  4. 復(fù)合型類型轉(zhuǎn)換——從short到unsigned

基本數(shù)據(jù)類型

讓我們復(fù)習(xí)一下C語言中基本數(shù)據(jù)類型的字節(jié)數(shù)

名稱 32位 64位
char 1 1
short int 2 2
int 4 4
long int 4 8
long long int 8 8
char * 4 8
float 4 4
double 8 8

這其實(shí)是很基礎(chǔ)的知識,但是值得一提的是伺糠,表中只有兩個(gè)數(shù)據(jù)類型在32位和64位計(jì)算機(jī)中使用了不同的字節(jié)數(shù)蒙谓,一個(gè)是long int,另一個(gè)是char *训桶。其實(shí)不只是char *累驮,任何數(shù)據(jù)類型的指針使用的字節(jié)數(shù)都和char *是一樣的酣倾,所以這里更好的寫法應(yīng)該是type *

為了盡量使程序可移植谤专,要小心從32位到64位的變化躁锡。例如,在32位機(jī)器中使用int保存變量的地址可行置侍,但同樣的程序移植到64位機(jī)器中就成了bug映之。所以不如嘗試用long int保存變量的地址。這個(gè)時(shí)候墅垮,上面的表格就體現(xiàn)出了它的價(jià)值惕医。

大小端模式

對于多于一個(gè)字節(jié)的數(shù)據(jù)類型,在內(nèi)存中有兩種存儲(chǔ)方式算色,以整型數(shù)0x01234567為例

大小端模式

大端模式將高位存放在低地址抬伺,而小端模式將高位存放在高地址。這對我們編程有什么影響呢灾梦?說實(shí)話峡钓,在我寫過的程序中并沒考慮過大小端模式,但在如下幾個(gè)方面若河,可以體現(xiàn)出大小端模式的影響:

  • 大端機(jī)器與小端機(jī)器間的網(wǎng)絡(luò)通信能岩。很明顯,如果雙方都遵循先發(fā)低位再發(fā)高位的規(guī)則萧福,發(fā)送前后數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式是完全一致的拉鹃,但大端機(jī)器和小端機(jī)器對同樣的數(shù)據(jù)存儲(chǔ)方式卻會(huì)解析出完全不同的結(jié)果,因此數(shù)據(jù)出現(xiàn)差錯(cuò)鲫忍。因此膏燕,解決辦法是發(fā)送前全部轉(zhuǎn)換成大端模式,對方接收后悟民,再根據(jù)自己的機(jī)器類型轉(zhuǎn)換成大端或小端模式坝辫。實(shí)際中網(wǎng)絡(luò)通信也的確是這樣做的。

  • 反匯編可以看到真實(shí)數(shù)據(jù)順序射亏。

    add %eax, 0x8049464

    反匯編結(jié)果為

    80483bd: 01 05 64 94 04 08

    操作數(shù)0x8049464被轉(zhuǎn)換成了小端模式下的結(jié)果64 94 04 08近忙。

  • 繞開類型系統(tǒng)的強(qiáng)制轉(zhuǎn)換。例如如下代碼可以測試出機(jī)器是大端模式還是小端模式:

int value = 0x01234567;
char *ch = (char *)(&value);
if (*ch == 0x01) {
    //大端模式
}
else if (*ch == 0x67) {
    //小端模式
}
else {
    //其它
}

由于ch一定指向value最低地址的字節(jié)智润,因此可以通過ch來判斷系統(tǒng)的大小端類型及舍。

整型數(shù)范圍與C標(biāo)準(zhǔn)

本文最開始就給出了各個(gè)基本數(shù)據(jù)類型的字節(jié)數(shù),根據(jù)字節(jié)數(shù)我們可以推斷出在采用二進(jìn)制補(bǔ)碼編碼的情況下各個(gè)類型的表示范圍窟绷。比如說int的范圍為-2,147,483,648 ~ 2,147,483,647锯玛。但是C標(biāo)準(zhǔn)的存在卻提醒我們事實(shí)并非總是如此。

C標(biāo)準(zhǔn)規(guī)定的各類型整型數(shù)的范圍與其典型值有所不同钾麸,通常小于其典型值范圍更振,并且所有有符號類型只要求對稱范圍。例如饭尝,int只要求-32767 ~ 32767肯腕。雖然我們使用的編譯器會(huì)按照系統(tǒng)位數(shù)來決定int類型的實(shí)際范圍,但是钥平,如果想要使代碼能夠跨平臺(tái)实撒,最好按照C標(biāo)準(zhǔn)規(guī)定的范圍來設(shè)計(jì)自己的程序,這樣只要編譯器遵循C標(biāo)準(zhǔn)涉瘾,代碼就一定不會(huì)出錯(cuò)知态。否則,像int i = 99999;這樣的語句立叛,放到16位計(jì)算機(jī)上就直接溢出了负敏。

接下來提一個(gè)有趣的事情,在32位計(jì)算機(jī)的頭文件<limits.h>中秘蛇,定義了各個(gè)基本數(shù)據(jù)類型的范圍其做,以整型為例

#define INT_MAX 2147483647
#define INT_MIN (-INT_MAX-1)

為什么最小值不直接寫#define INT_MIN -2147483648呢?

因?yàn)閷幾g器來說赁还,-2147483648是一個(gè)表達(dá)式妖泄,它的意思是對2147483648取負(fù)。但是2147483648這個(gè)數(shù)已經(jīng)超出了整型數(shù)所能表示的范圍艘策,因此這樣寫是沒有意義的蹈胡。更詳細(xì)的解釋可以查看后面的參考資料。

復(fù)合型類型轉(zhuǎn)換——從short到unsigned

數(shù)據(jù)類型既有不同的范圍朋蔫,又有不同的符號性質(zhì)罚渐,當(dāng)兩者同時(shí)轉(zhuǎn)換時(shí),就需要多加注意斑举。

例如搅轿,從short轉(zhuǎn)換到unsigned需要分兩步,實(shí)際過程相當(dāng)于(unsigned)(int)富玷,而不是(unsigned)(unsigned short)璧坟。也就是說,先擴(kuò)大范圍赎懦,再改變符號性質(zhì)雀鹃。對于下面的代碼

short s = -12345;
unsigned u = s;
printf("%u\n", u);
unsigned u1 = (unsigned)(int) s;
printf("%u\n", u1);
unsigned u2 = (unsigned)(unsigned short) s;
printf("%u\n", u2);

打印結(jié)果uu1都是4294954951,而u253191励两。

參考資料

文中若有錯(cuò)誤或不當(dāng)之處黎茎,懇請各位讀者指出。
關(guān)注作者文集《深入理解計(jì)算機(jī)系統(tǒng)》当悔,第一時(shí)間獲取最新發(fā)布文章傅瞻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末踢代,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子嗅骄,更是在濱河造成了極大的恐慌胳挎,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溺森,死亡現(xiàn)場離奇詭異慕爬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)屏积,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門医窿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人炊林,你說我怎么就攤上這事姥卢。” “怎么了渣聚?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵隔显,是天一觀的道長。 經(jīng)常有香客問我饵逐,道長括眠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任倍权,我火速辦了婚禮掷豺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘薄声。我一直安慰自己当船,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布默辨。 她就那樣靜靜地躺著德频,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缩幸。 梳的紋絲不亂的頭發(fā)上壹置,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機(jī)與錄音表谊,去河邊找鬼钞护。 笑死,一個(gè)胖子當(dāng)著我的面吹牛爆办,可吹牛的內(nèi)容都是我干的难咕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼余佃!你這毒婦竟也來了暮刃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤爆土,失蹤者是張志新(化名)和其女友劉穎沾歪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雾消,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年挫望,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了立润。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡媳板,死狀恐怖桑腮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛉幸,我是刑警寧澤破讨,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站奕纫,受9級特大地震影響提陶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜匹层,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一隙笆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧升筏,春花似錦撑柔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至灵汪,卻和暖如春檀训,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背享言。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工肢扯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人担锤。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓蔚晨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子铭腕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 10,923評論 6 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法银择,類相關(guān)的語法,內(nèi)部類的語法累舷,繼承相關(guān)的語法浩考,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • 1.寫一個(gè)NSString類的實(shí)現(xiàn) +(id)initWithCString:(c*****t char *)nu...
    韓七夏閱讀 3,752評論 2 37
  • 本章我們來研究三種重要的數(shù)字表示 無符號是基于傳統(tǒng)二進(jìn)制表示法被盈,表示大于或等于0的數(shù)字 補(bǔ)碼是表示有符號整數(shù)的最常...
    程序員必修課閱讀 1,003評論 2 2
  • 注:這是第三遍讀《C語言深度解剖》析孽,想想好像自從大學(xué)開始就沒讀完過幾本書,其中譚浩強(qiáng)的那本《C語言程序設(shè)計(jì)(第四版...
    HavenXie閱讀 1,717評論 1 6