国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C語(yǔ)言編程常見問題解答之位(bit)和字節(jié)(byte)

2019-11-17 05:41:43
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
    位指的是二進(jìn)制系統(tǒng)中的一位,它是最小的信息單位。位的用處可以從兩方面去分析:第一,計(jì)算機(jī)對(duì)位的值可以有任意多種解釋,例如表示"yes’’或"no”,或者表示磁盤是否已插入驅(qū)動(dòng)器,或者表示某個(gè)鼠標(biāo)鍵是否被按下;第二,將若干位的值連接起來(lái)后,就可以表示更復(fù)雜的數(shù)據(jù),而且每增加一位,可以表示的可能的值的數(shù)目就會(huì)增加一倍。
    換句話說(shuō),一位可以表示兩種可能的值,即“O”和“1”;兩位可以表示2×2或4種可能的值,即“00”,“01”,“10”和“11”;類似地,三位可以表示2×2×2或8種可能的值……。對(duì)計(jì)算機(jī)來(lái)說(shuō),位的這種特性既是最有力的支持——因?yàn)楹軓?fù)雜的數(shù)據(jù)(例如本書內(nèi)容)可以被分解為位的表示后存儲(chǔ)起來(lái),又是最大的限制——因?yàn)樵诂F(xiàn)實(shí)生活中許多事物的值是不精確的,這樣的值無(wú)法用數(shù)目有限的若干位來(lái)表示。
    程序員始終必須清楚每一項(xiàng)數(shù)據(jù)需要用多少位來(lái)表示。因?yàn)槲蛔鳛閱挝惶。詾榱朔奖闫鹨姡蠖鄶?shù)計(jì)算機(jī)所處理的信息單位是被稱為字節(jié)的位塊。字節(jié)是大多數(shù)計(jì)算機(jī)中最小的可尋址的信息單位,這意味著計(jì)算機(jī)給每一個(gè)字節(jié)的信息都賦予一個(gè)地址,并且一次只能存取一個(gè)字節(jié)的信息。一個(gè)字節(jié)中的位的數(shù)目可以是任意的,并且在不同的計(jì)算機(jī)中可以不同。最常見的情況是每個(gè)字節(jié)中有8位,即可以存放256個(gè)不同的值。8位這樣的長(zhǎng)度非常適合于存放表示ASCII(the American Standard Code for Information Interchange)字符的數(shù)據(jù)。
   下述程序可以顯示空格符以后的ASCII字符和PC機(jī)的圖形字符集:
# include <stdio. h>
void main (void);
void main()
{
  /" Display ASCII char set " /
  unsigned char space  =  '' ;     /* Start with SPACE
                                         char =  8 bits only * /
  int ctr =  0;
    printf (" = = = = = = = = = = = = = = = =/n" ) ;
  for  (ctr = O; ctr + space <256; ctr+ + )
    printf("%c", ctr  + space);
  printf ("/n");
}

   請(qǐng)注重,變量ctr必須是int類型,而不能是char類型,因?yàn)閏har類型只含8位,只能存放從0至255之間的值(signed char類型只能存放從-128至127之間的值)。假如ctr是char類型,它就永遠(yuǎn)不會(huì)存放256或比256更大的值,程序也就永遠(yuǎn)不會(huì)結(jié)束。此外,假如你在非PC機(jī)的計(jì)算機(jī)上運(yùn)行上述程序,那么程序所打印的非ASCII字符可能會(huì)導(dǎo)致亂屏。
    因?yàn)橛?jì)算機(jī)是以字節(jié)塊的方式工作的,所以大多數(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è)文件名。在3.5中你可以看到另外一個(gè)例子,該例通過(guò)一個(gè)標(biāo)志從兩種可能類型中選擇一種在一個(gè)聯(lián)合中使用。因?yàn)橐粋€(gè)標(biāo)志一般只有少數(shù)幾個(gè)(通常是兩個(gè))值,所以,為了節(jié)省內(nèi)存空間,通常不會(huì)將一個(gè)標(biāo)志存放在一個(gè)屬于它自己的int或char類型中。
    存儲(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ǔ)方法是沒有關(guān)系的。假如標(biāo)志的數(shù)目很多,那么最好將它們壓縮存儲(chǔ)在一個(gè)字符數(shù)組或整型數(shù)組中。這時(shí),需要通過(guò)一種被稱為位屏蔽(bit maSKINg)的過(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)志。在3.5的例子中,就使用了一個(gè)指針的低階位來(lái)存放一個(gè)標(biāo)志,該標(biāo)志的作用是從兩種可能的類型中選擇一種作為該指針?biāo)赶虻膶?duì)象類型。
    請(qǐng)參見:
    10.2什么是“位屏蔽(bit masking)”?
    10.3位域(bit fields)是可移植的嗎?
    10.4移位和乘以2這兩種方式中哪一種更好?    10.2 什么是“位屏蔽(bit masking)”?
    位屏蔽的含義是從包含多個(gè)位集的一個(gè)或一組字節(jié)中選出指定的一(些)位。為了檢查一個(gè)字節(jié)中的某些位,可以讓這個(gè)字節(jié)和屏蔽字(bit mask)進(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ì)屏蔽字按位取反所得的值進(jìn)行按位與操作。例如,你可以這樣清除flags的最低位:
    flags = flags& ~1;
或者這樣:
    flags&=~1 ;
    有時(shí),用宏來(lái)處理標(biāo)志會(huì)更方便,例10.2中的程序就是通過(guò)一些宏簡(jiǎn)化了位操作。    例10.2 能使標(biāo)志處理更方便的宏
/* Bit Masking * /
/ * Bit masking can be used to switch a character
  between lowercase and uppercase * /
#define B99v_POS(N)            ( 1U «(N) )
#define SET_FLAG(N,F)         ( (N)   = (F) )
#define CLR_FLAG(N,F)         ( (N) &= -  (F) )
#define TST_FLAGCN,F)         ( (N) & (F)  )
#define B99v_RANGE(N,M)         ( B99v_POS((M) + 1- (N))-1<<(N))
#define B99v_SHIFTL(B,N)        ( (unsigned)(B)«(N) )
#define B99v_SHIFTR(B,N)        ( (unsigned)(B)»(N) )
#define SET_MFLAG(N,F,V)       ( CLR_FLAG(N,F), SET_FLAG(N,V) )
#define CLR_MFLAG(N,F)         ( (N) &= ~(F) )
#define GET_MFLAG(N,F)         ( (N) & (F) )

# include <stdio. h>
void main()
{
  unsigned char ascii_char = 'A';    /* char  = 8 bits only */
  int test_nbr = 10;
  printf("Starting character =  %c/n" , ascii_char);
  /"   The 5th bit position determines if the character is
       uppercase or lowercase.
       5th bit =  0 - Uppercase
       5th bit =  1- Lowercase    * /
  printf ("/nTurn 5th bit on = %c/n" , SET_FLAG(ascii_char, B99v_POS(5)));
  printf ("Turn 5th bit  off = %c/n/n",CLR_FLAG(ascii_char, B99v_POS(5)));
  printf ("Look at shifting bits/n");
  printf (" = = = = = = = = = = = = = = = =/n" );
  printf ("Current value = %d/n" , test_nbr)i
  printf ("Shifting one position left = %d/n" ,
        test_nbr = B99v_SHIFTL(test_nbr, 1) );
  printf ("Shifting two positions right =  %d/n" ,
        B99v_SHIFTR(test_nbr,  2) );
}
    宏B99v_POS(N)能返回一個(gè)和N指定的位對(duì)應(yīng)的屏蔽字(例如B99v_POS(O)和B99v_POS(1)分別返回最低位和倒數(shù)第二位的屏蔽字),因此你可以用
    #define A_FLAG B99v_POS(12)
 &nb


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 南乐县| 咸宁市| 赫章县| 乾安县| 三亚市| 筠连县| 海伦市| 叙永县| 波密县| 古交市| 积石山| 嵊州市| 革吉县| 上林县| 烟台市| 张家港市| 汉沽区| 襄汾县| 柳河县| 新巴尔虎左旗| 昭苏县| 兴城市| 张家口市| 苍溪县| 汽车| 厦门市| 锡林浩特市| 赤水市| 弥渡县| 周宁县| 榆树市| 衡阳市| 云安县| 赫章县| 五指山市| 香港| 岑巩县| 上思县| 斗六市| 安乡县| 肃宁县|