1. 程式人生 > >位標誌與位欄位

位標誌與位欄位

位標誌:

如果你正在編寫一個課程管理系統,你會以什麼樣的形式來表示你今天哪些節有課哪些節沒課呢?比如一天有12節課,如下圖所示



可能大家會問,為什麼只是記錄哪些節有課,哪些節沒課呢?這樣的資訊有什麼作用呢?當然有用,比如你要查詢某同學今天上午1、2節是否有課,又比如在排課系統中,把某門課排到星期二下午6、7節,首先就要確定這兩節課是否已經分配給了其他課程。。。。。。

我想大部分人最初能想到的就是使用一個bool陣列來表示它(這大部分人當中當然也包括我自己),使用程式碼來表示就是下面這個樣子:

bool[] arrCourse = new bool[13];

arrCourse[5]=true;

arrCourse[6]=true;

好!恭喜你,有了一個很不錯的開始,很好地完成了任務,以上程式碼執行完的結果如下圖所示:



在陣列中,當元素值為T時,表明這一節有課,為F時,表明這一節沒課。現在感覺相當良好,現在可以開始排課了。比如我們現在需要在某天排入某門課,這一天現在的課程狀態如下圖所示:



如果我們要把這門課排到第1、2節,就需要做出如下判斷

if(arrCourse[0]==false && arrCourse[1]==false)

如果我們需要把排到1、2、3節,就需要做出如下判斷

if(arrCourse[0]==false && arrCourse[1]==false && arrCourse[2]==false)

如果需要把課排到1~5節或1~13節。。。!現在有點暈了,怎麼這麼麻煩啊!當然,你要是真的這麼寫程式那就是真的有點麻煩了,這樣的判斷應該藉助迴圈。但無論怎麼樣,判斷的次數是不能減少的,這樣的資料結構也不能讓人滿意。是否有更好的解決方案呢?

好!我們嘗試把F變為0,T變為1,看看效果怎麼樣:



這幅圖表示的不是一個二進位制數嗎?用計算器來轉換一下,它就是十進位制的902。哈哈!真是天才的想法,用一個整數就可以表示這一天的上課狀態了。現在我要把新課排在1、2節只需要把902跟二進位制的(110000000000)也就是十進位制的3072進行“與”運算(902 & 3072)就OK了,結果為0,表明可以排進去,結果不為0表明1、2節至少有一節已排入其他課了。

如果要排入的是下午6、7節,只需跟二進位制(000001100000)也就是十進位制的96進行“與”運算。現在不再需要進行多次判斷,只需一次運算,判斷結果是否為0就解決了所有問題。

現在大家應該明白位運算有多好了吧!Windows中存在著大量的位標誌,如果曾經使用Windows API進行程式設計應該對此有很深的體會。舉個例子:假設Windows字型存在以下幾種樣式:加粗,斜體,下劃線。一個字型即可以同時擁有以上三種樣式,也可以只擁有一種樣式,或擁有其中任意兩種樣式,或者乾脆一種都沒有。如何表示字型的樣式呢?當然最佳的方案就是使用位標誌。如用第一個位表示字型是否加精,第二、三個位分別表示是否是斜體和下劃線,如下圖所示:



當位標誌為:010------(十進位制的2)時,表示這個字型只有斜體這種樣式

當位標誌為:011------(十進位制的3)時,表示這個字型為粗體,同時又是斜體

。。。。。。。

所以當你要把某行字變為粗體時,只需讓它跟二進位制的(001)進行“或”運算就行了

把某行字變為斜體時,只需讓它跟二進位制的(010)進行“或”運算

把某行字變為帶下劃線時,只需讓它跟二進位制的(100)進行“或”運算

如果要把粗體去掉呢?只需把001求補變為110,然後跟位標誌進行“與”運算就行了

把某行字的斜體去掉,只需把010求補變為101,然後跟位標誌進行“與”運算就行了

把某行字的下劃線去掉,只需把100求補變為011,然後跟位標誌進行“與”運算就行了

位欄位:

結構體中欄位冒號後數字表示該欄位分配多少位

<span style="font-size:14px;">#include <stdio.h> 
#define MALE 0 ;
#define FEMALE 1 ;
#define SINGLE 0 ;
#define MARRIED 1 ;
#define DIVORCED 2 ;
#define WIDOWED 3 ;
main( )
{
	struct employee
	{ 
		unsigned  gender : 1 ;
		unsigned  mar_status : 2 ;
		unsigned  hobby : 3 ;
		unsigned  scheme : 4 ;
	} ;
	struct employee  e ;
	e.gender = MALE ; 
	e.mar_status = DIVORCED ;
	e.hobby = 5 ;
	e.scheme = 9 ;

	printf ( "\nGender = %d", e.gender ) ;
	printf ( "\nMarital status = %d", e.mar_status ) ;
	printf ( "\nBytes occupied by e = %d", sizeof ( e ) ) ;  //結果是4,這是我係統最小的位元組對齊要求
}</span>