




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C語(yǔ)言編程要點(diǎn)第10章位(bit)和字節(jié)(byte)第10章位(bit)和字節(jié)(byte)位指的是二進(jìn)制系統(tǒng)中的一位,它是最小的信息單位。位的用處可以從兩方面去分析:第一,計(jì)算機(jī)對(duì)位的值可以有任意多種解釋?zhuān)绫硎?quot;yes'或"no",或者表示磁盤(pán)是否已插入驅(qū)動(dòng)器,或者表示某個(gè)鼠標(biāo)鍵是否被按下;第二,將若干位的值連接起來(lái)后,就可以表示更復(fù)雜的數(shù)據(jù),而且每增加一位,可以表示的可能的值的數(shù)目就會(huì)增加一倍。換句話說(shuō),一位可以表示兩種可能的值,即“O和“1;”兩位可以表示2M或4種可能的值,即“00:“01,”“1麗“11;”類(lèi)似地,三位可以表示2X2應(yīng)或8種可能
2、的值。對(duì)計(jì)算機(jī)來(lái)說(shuō),位的這種特性既是最有力的支持因?yàn)楹軓?fù)雜的數(shù)據(jù)(例如本書(shū)內(nèi)容)可以被分解為位的表示后存儲(chǔ)起來(lái),又是最大的限制因?yàn)樵诂F(xiàn)實(shí)生活中許多事物的值是不精確的,這樣的值無(wú)法用數(shù)目有限的若干位來(lái)表示。程序員始終必須清楚每一項(xiàng)數(shù)據(jù)需要用多少位來(lái)表示。因?yàn)槲蛔鳛閱挝惶?,所以為了方便起?jiàn),大多數(shù)計(jì)算機(jī)所處理的信息單位是被稱為字節(jié)的位塊。字節(jié)是大多數(shù)計(jì)算機(jī)中最小的可尋址的信息單位,這意味著計(jì)算機(jī)給每一個(gè)字節(jié)的信息都賦予一個(gè)地址,并且一次只能存取一個(gè)字節(jié)的信息。一個(gè)字節(jié)中的位的數(shù)目可以是任意的,并且在不同的計(jì)算機(jī)中可以不同。最常見(jiàn)的情況是每個(gè)字節(jié)中有8位,即可以存放256個(gè)不同的值。8位這樣的長(zhǎng)度
3、非常適合于存放表示ASCII(theAmericanStandardCodeforInformationInterchange)字符的數(shù)據(jù)。下述程序可以顯示空格符以后的ASCII字符和PC機(jī)的圖形字符集:#include<stdio.h>voidmain(void);voidmain()/"DisplayASCIIcharset"/unsignedcharspace=''/*StartwithSPACEchar=8bitsonly*/intctr=0;printf("ASCIICharactersn")?printf(&quo
4、t;=n");for(ctr=O;ctr+space<256;ctr+)printf("%c",ctr+space);printf("n");請(qǐng)注意,變量ctr必須是int類(lèi)型,而不能是char類(lèi)型,因?yàn)閏har類(lèi)型只含8位,只能存放從0至255之間的值(signedchar類(lèi)型只能存放從-128至127之間的值)。如果ctr是char類(lèi)型,它就永遠(yuǎn)不會(huì)存放256或比256更大的值,程序也就永遠(yuǎn)不會(huì)結(jié)束。此外,如果你在非PC機(jī)的計(jì)算機(jī)上運(yùn)行上述程序,那么程序所打印的非ASCII字符可能會(huì)導(dǎo)致亂屏。因?yàn)橛?jì)算機(jī)是以字節(jié)塊的方式工作的,所以大多
5、數(shù)程序也以這種方式工作,有時(shí),考慮到要存放的數(shù)據(jù)項(xiàng)的數(shù)目,或者移動(dòng)每一位的信息所需的時(shí)間,節(jié)省內(nèi)存空間就顯得很有必要。這時(shí),我們通常會(huì)用少于一個(gè)字節(jié)的空間來(lái)存放那些只有少數(shù)可能值的數(shù)據(jù),這也就是本章要討論的主要內(nèi)容10.1. 用什么方法存儲(chǔ)標(biāo)志(flag)效率最高?標(biāo)志的作用是對(duì)程序執(zhí)行過(guò)程中的兩種或更多種選擇作出決定。例如,在執(zhí)行MS-DOS的dir命令時(shí),可以用“w”標(biāo)志使該命令在屏幕上顯示若干列文件名而不是每行只顯示一個(gè)文件名。在35中你可以看到另外一個(gè)例子,該例通過(guò)一個(gè)標(biāo)志從兩種可能類(lèi)型中選擇一種在一個(gè)聯(lián)合中使用。因?yàn)橐粋€(gè)標(biāo)志一般只有少數(shù)幾個(gè)(通常是兩個(gè))值,所以,為了節(jié)省內(nèi)存空間,通
6、常不會(huì)將一個(gè)標(biāo)志存放在一個(gè)屬于它自己的int或char類(lèi)型中。存儲(chǔ)標(biāo)志值的效率是存儲(chǔ)空間和存取速度之間的一種折衷。存儲(chǔ)空間利用效率最高的存儲(chǔ)方法是用數(shù)目足夠的位來(lái)存儲(chǔ)標(biāo)志值的所有可能值,但大多數(shù)計(jì)算機(jī)不能直接尋址內(nèi)存中單獨(dú)的一位,因此標(biāo)志值要從存放它的字節(jié)中提取。存取速度最快的存儲(chǔ)方法是將每個(gè)標(biāo)志值都存放到一個(gè)屬于它自己的整型變量中,但是,當(dāng)一個(gè)標(biāo)志只需要一位存儲(chǔ)空間而變量的長(zhǎng)度為32位時(shí),那么其余的31位就全部浪費(fèi)掉了,因此這種方法的存儲(chǔ)空間利用效率非常低。如果標(biāo)志的數(shù)目不多,那么使用哪種存儲(chǔ)方法是沒(méi)有關(guān)系的。如果標(biāo)志的數(shù)目很多,那么最好將它們壓縮存儲(chǔ)在一個(gè)字符數(shù)組或整型數(shù)組中。這時(shí),需要通
7、過(guò)一種被稱為位屏蔽(bitmasking)的過(guò)程來(lái)提取這些標(biāo)志值,即屏蔽掉不需要的位,只處理所需的位。有時(shí),為了節(jié)省存儲(chǔ)空間,可能會(huì)將一個(gè)標(biāo)志和另外一個(gè)值存放在一起。例如,如果一個(gè)整型的值小于整型所能表示的最大值,那么就可用它的高階位來(lái)存放標(biāo)志;如果某些數(shù)據(jù)總是2或4的倍數(shù),那么就可用它的低階位來(lái)存放標(biāo)志。在35的例子中,就使用了一個(gè)指針的低階位來(lái)存放一個(gè)標(biāo)志,該標(biāo)志的作用是從兩種可能的類(lèi)型中選擇一種作為該指針?biāo)赶虻膶?duì)象類(lèi)型。請(qǐng)參見(jiàn):102什么是“位屏蔽(bitmasking)”?103位域(bitfields)是可移植的嗎?104移位和乘以2這兩種方式中哪一種更好?10.2. 什么是“位屏
8、蔽(bitmasking)”?位屏蔽的含義是從包含多個(gè)位集的一個(gè)或一組字節(jié)中選出指定的一(些)位。為了檢查一個(gè)字節(jié)中的某些位,可以讓這個(gè)字節(jié)和屏蔽字(bitmask)進(jìn)行按位與操作(C的按位與運(yùn)算符為&)屏蔽字中與要檢查的位對(duì)應(yīng)的位全部為1,而其余的位(被屏蔽的位)全部為0。例如,為了檢查變量flags的最低位,你可以讓flags和最低位的屏蔽字進(jìn)行按位與操作:flags&1;為了置位所需的位,可以讓數(shù)據(jù)和屏蔽字進(jìn)行按位或操作(C的按位或運(yùn)算符為|)。例如,你可以這樣置位flags的最低位:flags=flags|1;或者這樣:flags|=1;為了清除所需的位,可以讓數(shù)據(jù)和對(duì)
9、屏蔽字按位取反所得的值進(jìn)行按位與操作。例如,你可以這樣清除flags的最低位:flags=flags&1;或者這樣:flags&=1;有時(shí),用宏來(lái)處理標(biāo)志會(huì)更方便,例102中的程序就是通過(guò)一些宏簡(jiǎn)化了位操作。例102能使標(biāo)志處理更方便的宏/*BitMasking*/*Bitmaskingcanbeusedtoswitchacharacterbetweenlowercaseanduppercase*/( 1U ?(N) )( (N) | = (F) )( (N) &= - (F) )#defineBIT_POS(N)#defineSET_FLAG(N,F)#defineC
10、LR_FLAG(N,F)#define BIT_RANGE(N,M)#define BIT_SHIFTL(B,N)#define BIT_SHIFTR(B,N)#define SET_MFLAG(N,F,V)#define CLR_MFLAG(N,F)#define GET_MFLAG(N,F)(BIT_POS(M)+1-(N)-1<<(N)(unsigned)(B)?(N)(unsigned)(B)?(N)(CLR_FLAG(N,F),SET_FLAG(N,V)(N)&=(F)(N)&(F)#include<stdio.h>voidmain()unsi
11、gnedcharascii_char='A'/*char=8bitsonly*/inttest_nbr=10;printf("Startingcharacter=%cn",ascii_char);/"The5thbitpositiondeterminesifthecharacterisuppercaseorlowercase.5thbit=0-Uppercase5thbit=1-Lowercase*/printf("nTurn5thbiton=%cn",SET_FLAG(ascii_char,BIT_POS(5);printf(
12、"Turn5thbitoff=%cnn",CLR_FLAG(ascii_char,BIT_POS(5);printf("Lookatshiftingbitsn");printf("=n");printf("Currentvalue=%dn",test_nbr)iprintf("Shiftingonepositionleft=%dn",test_nbr=BIT_SHIFTL(test_nbr,1);printf("Shiftingtwopositionsright=%dn",B
13、IT_SHIFTR(test_nbr,2);宏BIT_POS(N)能返回一個(gè)和N指定的位對(duì)應(yīng)的屏蔽字(例如BIT_POS(O)和BIT_POS(1)分別返回最低位和倒數(shù)第二位的屏蔽字),因此你可以用#defineA_FLAGBIT_POS(12)#defineA_FLAGBIT_P0S(13)代替#defineA_FLAG4096#defineA_FLAG8192這樣可以降低出錯(cuò)的可能性。宏SET_FLAG(N,F)能置位變量N中由值F指定的位,而宏CLR_FLAG(N,F)則剛好相反,它能清除變量N中由值F指定的位。宏TST_FLAG(N,F)可用來(lái)測(cè)試變量N中由值F指定的位,例如:if(T
14、ST_FLAG(flags,A_FLAG)/*dosomething*/;宏BIT_RANGE(N,M)能產(chǎn)生一個(gè)與由N和M指定的位之間的位對(duì)應(yīng)的屏蔽字,因此,你可以用# defineFIRST_OCTAL_DIGITBIT_RANGE(0,2)/*111"/* 111000*/# defineSECOND-OCTAL-DIGITBIT-RANGE(3,5)代替#define FIRST_OCTAL_DIGIT 7/*111*/#defineSECOND_OCTAL_DIGIT56/*111000*/這樣可以更清楚地表示所需的位。宏BIT_SHIFT(B,N)能將值B移位到適當(dāng)?shù)膮^(qū)域
15、(從由N指定的位開(kāi)始)。例如,如果你用標(biāo)志C表示5種可能的顏色,你可以這樣來(lái)定義這些顏色:#defineC_FLAGBIT-RANGE(8,10)/*11100000000*/*hereareallthevaluestheCflagcantakeon*/# defineC_BLACKBIT-SHIFTL(0,8)/*ooooooooooo*/# defineC-REDBIT_SHIFTL(1,8)/*00100000000*/# defineC-GREENBIT_SHIFTL(2,8)/*01000000000*/# defineC-BLUEBIT-SHIFTL(3,8)/*011000000
16、00*/# defineC_WHITEBIT-SHIFTL(4,8)/*10000000000*/# defineC-ZEROC-BLACK# defineC-LARGESTC-WHITE/*Atrulyparanoidprogrammermightdothis*/#ifC_LARGEST>C_FLAGCauseanerrormessage.TheflagC_FLAGisnotbigenoughtoholdallitspossiblevalues.#endif/*C_LARGEST>C_FLAG*/宏SET_MFLAG(N,F,V)先清除變量N中由值F指定的位,然后置位變量N中由值
17、V指定的位。宏CLR_MFLAG(N,F)的作用和CLR_FLAG(N,F)是相同的,只不過(guò)換了名稱,從而使處理多位標(biāo)志的宏名字風(fēng)格保持一致。宏GET_MFLAG(N,F(xiàn))能提取變量N中標(biāo)志F的值,因此可用來(lái)測(cè)試該值,例如:if(GET_MFLAG(flags,C_FLAG)=C_BLUE)/*dosomething*/;注意:宏BIT_RANGE()和SET_MFLAG()對(duì)參數(shù)N都引用了兩次,因此語(yǔ)句SET_MFLAG(*x+,C_FLAG,C_RED);的行為是沒(méi)有定義的,并且很可能會(huì)導(dǎo)致災(zāi)難性的后果。請(qǐng)參見(jiàn):10.1用什么方法存儲(chǔ)標(biāo)志(flag)效率最高?103位域(bitfields
18、)是可移植的嗎?10.3. 位域(bitfields)是可移植的嗎?位域是不可移植的。因?yàn)槲挥虿荒芸缭綑C(jī)器字,而且不同計(jì)算機(jī)中的機(jī)器字長(zhǎng)也不同,所以一個(gè)使用了位域的程序在另一種計(jì)算機(jī)上很可能無(wú)法編譯。假設(shè)你的程序能在另一種計(jì)算機(jī)上編譯,將位分配給位域時(shí)所遵循的順序仍然是沒(méi)有定義的。因此,不同的編譯程序,甚至同一編譯程序的不同版本所產(chǎn)生的代碼,很可能無(wú)法在由原來(lái)的編譯程序所生成的數(shù)據(jù)上工作。通常應(yīng)該避免使用位域,除非計(jì)算機(jī)能直接尋址內(nèi)存中的位并且編譯程序產(chǎn)生的代碼能利用這種功能,并且由此而提高的速度對(duì)程序的性能是至關(guān)重要的。請(qǐng)參見(jiàn):10 .1用什么方法存儲(chǔ)標(biāo)志(flag)效率最高?11 2什么是
19、“位屏蔽(bitmasking)”?10.4. 移位和乘以2這兩種方式中哪一種更好?不管你采用哪種方式,任何合格的優(yōu)化編譯程序都會(huì)產(chǎn)生相同的代碼,因此你可以采用使程序的上下文更易讀的那種方式。你可以用DOSWindows上的CODEVIEW或UNIX機(jī)上的反匯編程序(通常被稱為"dis”)這樣的工具來(lái)查看下述程序的匯編代碼:例104乘以2和左移一位經(jīng)常是相同的voidmain()unsignedinttest_nbr=300;test_nbr*=2;test_nbr=300;test_nbr<<=1;請(qǐng)參見(jiàn):10. 1用什么方法存儲(chǔ)標(biāo)志(flag)效率最高?10.5. 什
20、么是高位字節(jié)和低位字節(jié)?通常我們從最高有效位(mostsignificantdigit)開(kāi)始自左向右書(shū)寫(xiě)一個(gè)數(shù)字。在理解有效位這個(gè)概念時(shí),可以想象一下你的支票數(shù)額的第一位增加1和最后一位增加1之間的巨大區(qū)別,前者肯定會(huì)讓你喜出望外。計(jì)算機(jī)內(nèi)存中一個(gè)字節(jié)的位相當(dāng)于二進(jìn)制數(shù)的位,這意味著最低有效位表示1,倒數(shù)第二個(gè)有效位表示2X1或2,倒數(shù)第三個(gè)有效位表示2X2X1或4,依此類(lèi)推。如果用內(nèi)存中的兩個(gè)字節(jié)表示一個(gè)16位的數(shù),那么其中的一個(gè)字節(jié)將存放最低的8位有效位,而另一個(gè)字節(jié)將存放最高的8位有效位,見(jiàn)圖105。存放最低的8位有效位的字節(jié)被稱為最低有效位字節(jié)或低位字節(jié),而存放最高的8位有效位的字節(jié)被稱為最高有效位字節(jié)或高位字節(jié)。高位字節(jié)低位字節(jié)1514131211109.8.7.6.5.4.3.2.1.0.圖10.5雙字節(jié)整數(shù)中的位請(qǐng)參見(jiàn):10. 616位和32位的數(shù)是怎樣存儲(chǔ)的10.6. 16位和32位的數(shù)是怎樣存儲(chǔ)的?一個(gè)16位的數(shù)占兩個(gè)字節(jié)的存儲(chǔ)空間,即高位字節(jié)和低位字節(jié)(見(jiàn)105中的介紹
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 錄音協(xié)議合同書(shū)二零二五年
- 有限合伙股權(quán)代持協(xié)議內(nèi)容
- 農(nóng)村生態(tài)環(huán)境監(jiān)測(cè)技術(shù)服務(wù)協(xié)議
- 安全生產(chǎn)綜合知識(shí)預(yù)習(xí)試卷庫(kù)加答案
- 草場(chǎng)承包租賃合同
- 碘化四甲銨企業(yè)ESG實(shí)踐與創(chuàng)新戰(zhàn)略研究報(bào)告
- 蝦苗采購(gòu)合同采購(gòu)合同
- 外用液體制劑企業(yè)縣域市場(chǎng)拓展與下沉戰(zhàn)略研究報(bào)告
- 智能安防照明一體化設(shè)備企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報(bào)告
- 智能安防文物展柜設(shè)備行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報(bào)告
- 2025年九江市第一批面向社會(huì)公開(kāi)招聘留置看護(hù)隊(duì)員【68人】筆試備考試題及答案解析
- 2025屆廣東省高三下學(xué)期二模英語(yǔ)試題(原卷版+解析版)
- 2025-2030中國(guó)OWS耳機(jī)市場(chǎng)發(fā)展?fàn)顩r及前景趨勢(shì)研究研究報(bào)告
- 杭州師范大學(xué)附屬醫(yī)院與拱墅區(qū)雙向轉(zhuǎn)診信息平臺(tái)建設(shè)項(xiàng)目招標(biāo)文件
- 線上養(yǎng)羊合同協(xié)議
- 2025至2030中國(guó)白電市場(chǎng)競(jìng)爭(zhēng)戰(zhàn)略規(guī)劃與運(yùn)行態(tài)勢(shì)研究報(bào)告
- 煙草證借用合同范本
- 燒燙傷培訓(xùn)課件
- 【語(yǔ)文】第23課《“蛟龍”探?!氛n件 2024-2025學(xué)年統(tǒng)編版語(yǔ)文七年級(jí)下冊(cè)
- 大部分分校:地域文化形考任務(wù)一-國(guó)開(kāi)(CQ)-國(guó)開(kāi)期末復(fù)習(xí)資料
- 走進(jìn)泰國(guó)-課件
評(píng)論
0/150
提交評(píng)論