3. 位域
4. 聯合體
5. 聯合體位域
今天來點概念性的東西,如果在**中用到位運算和聯合體位域,是不是會顯得高階一些呢?哈哈。
在c語言中共提供了6中位運算子,具體如下:
& 按位與
| 按位或
^ 按位異或
~ 取反
<< 左移
>> 右移
按位與運算子"&"是雙目運算子。其功能是參與運算的兩數各對應的二進位相與。
只有對應的兩個二進位均為 1 時,結果位才為 1,否則為 0。參與運算的數以補碼方式
出現。例如:9&5 可寫算式如下:
00001001
(9 的二進位制補碼)
&00000101
(5 的二進位制補碼)
00000001
(1 的二進位制補碼)
可見 9&5=1。
按位與運算通常用來對某些位清 0 或保留某些位。例如把 a 的高八位清 0 ,保留低八
位,可作 a&255 運算( 255 的二進位制數為 0000000011111111)。
按位或運算子「|」是雙目運算子。其功能是參與運算的兩數各對應的二進位相或。只
要對應的二個二進位有乙個為 1 時,結果位就為 1。參與運算的兩個數均以補碼出現。
例如:9|5 可寫算式如下:
00001001
|00000101
00001101
(十進位制為 13
)可見 9|5
=13
按位異或運算子「^」是雙目運算子。其功能是參與運算的兩數各對應的二進位相異
或,當兩對應的二進位相異時,結果為 1。參與運算數仍以補碼出現。
例如 9^5 可寫成算式如下:
00001001
^00000101
00001100
(十進位制為 12
)
求反運算子~為單目運算子,具有右結合性。其功能是對參與運算的數的各二進位按位
求反。例如~9 的運算為:
~
(0000000000001001
)結果為:1111111111110110
左移運算子「<<」是雙目運算子。其功能把「<< 」左邊的運算數的各二進位全部左移若
乾位,由「<<」右邊的數指定移動的位數,高位丟棄,低位補 0。
例如:
a<<
4
指把 a 的各二進位向左移動 4 位。如 a=00000011(十進位制 3),左移 4 位後為 00110000(十進位制 48)。
右移運算子「>>」是雙目運算子。其功能是把「>> 」左邊的運算數的各二進位全部右移若
乾位,「>>」右邊的數指定移動的位數。
例如:
設 a=
15,a>>
2
表示把 000001111 右移為 00000011(十進位制 3)。
應該說明的是,對於有符號數,在右移時,符號位將隨同移動。當為正數時,最高位補
0,而為負數時,符號位為 1,最高位是補 0 或是補 1 取決於編譯系統的規定。turbo c 和
很多系統規定為補 1。
有些資訊在儲存時,並不需要占用乙個完整的位元組,而只需佔幾個或乙個二進位制位。例
如在存放乙個開關量時,只有 0 和 1 兩種狀態,用一位二進位即可。為了節省儲存空間,並
使處理簡便,c語言又提供了一種資料結構,稱為「位域」或「位段」。
所謂「位域」是把乙個位元組中的二進位劃分為幾個不同的區域,並說明每個區域的位數。
每個域有乙個網域名稱,允許在程式中按網域名稱進行操作。這樣就可以把幾個不同的物件用乙個字
節的二進位制位域來表示。
位域定義與結構定義相仿,其形式為:
struct 位域結構名
;
其中位域列表的形式為:
型別說明符 位網域名稱:位域長度
例如:
struct bits
;
位域變數的說明與結構體變數說明的方式相同。 可採用先定義後說明,同時定義說明或
者直接說明這三種方式。
例如:
struct bits
data;
說明 data 為 bits 變數,共佔兩個位元組。其中位域 a 佔 8 位,位域 b 佔 2 位,位域 c 佔 6
位。對於位域的定義尚有以下幾點說明:
乙個位域必須儲存在同乙個位元組中,不能跨兩個位元組。如乙個位元組所剩空間不夠存放另一位域時,應從下一單元起存放該位域。也可以有意使某位域從下一單元開始。
例如:
struct bits
在這個位域定義中,a 佔第一位元組的 4 位,後 4 位填 0 表示不使用,b 從第二位元組開始,占用 4 位,c 占用 4 位。
由於位域不允許跨兩個位元組,因此位域的長度不能大於乙個位元組的長度,也就是說 不能超過 8 位二進位。
位域可以無位網域名稱,這時它只用來作填充或調整位置。無名的位域是不能使用的。
例如:
struct bits
;
從以上分析可以看出,位域在本質上就是一種結構型別,不過其成員是按二進位分配的。
位域的使用和結構成員的使用相同,其一般形式為:
位域變數名·位網域名稱
位域允許用各種格式輸出。
main()
bit,
*pbit;
bit.a=1;
bit.b=7;
bit.c=15;
printf
("%d,%d,%d\n"
,bit.a,bit.b,bit.c)
; pbit=
&bit;
pbit->a=0;
pbit->b&=3
; pbit->c|=1
;printf
("%d,%d,%d\n"
,pbit->a,pbit->b,pbit->c)
;}
位運算是c語言的一種特殊運算功能, 它是以二進位制位為單位進行運算的。位運
算符只有邏輯運算和移位運算兩類。位運算子可以與賦值符一起組成復合賦值符。
如&=,|=,^=,>>=,<<=等。
利用位運算可以完成組合語言的某些功能,如置位,位清零,移位等。還可進行數
據的壓縮儲存和並行運算。
位域在本質上也是結構型別,不過它的成員按二進位制位分配記憶體。其定義、說明及
使用的方式都與結構相同。
位域提供了一種手段,使得可在高階語言中實現資料的壓縮,節省了儲存空間,同
時也提高了程式的效率。
聯合體也叫共用體,是一種特殊的類,也是一種構造型別的資料結構。在乙個聯合體內能夠定義多種不同的資料型別。乙個被說明為該聯合體型別的變數中。同意裝入該聯合體所定義的不論什麼一種資料。這些資料共享同一段記憶體,以達到節省空間的目的。
聯合體有兩個特性:
1. 在union中,分配記憶體空間的大小,等於佔記憶體最大的資料型別位元組大小。
2. 共享同一段記憶體
下面就驗證一下這兩個特性:
union bits ;-
(void
)uniontest
uniontest方法中,按照聯合體特性bit的大小應該是8位元組(由double決定的),a和b的位址應該是相同的,並且先給a賦值,再給b賦值,那麼b的值會將a的值覆蓋,下面看結果。
gymdemo[
8709
:405491
] bits size =
8位元組gymdemo[
8709
:405491
] a address =
0x7ffee72d70b8
, b address =
0x7ffee72d70b8
gymdemo[
8709
:405491
] a =
0, b =
8.000000
union isa bits;
};
上面的這種結構即是聯合體位域的乙個示例,聯合體isa中的cls和bits只能有乙個是有值,從而節省了空間,而bits又是位域,能儲存很多資料,節省空間,所以聯合體位域能夠大大的節省空間。 聯合體 位域結構體 聯合體的妙用
在c語言中,變數的定義是分配儲存空間的過程。一般的,每個變數都具有其獨有的儲存空間,那麼可不可以在同乙個記憶體空間中儲存不同的資料型別 不是同事儲存 呢?答案是可以的,使用聯合體就可以達到這樣的目的。聯合體也叫共用體,在c語言中定義聯合體的關鍵字是union。定義乙個聯合型別的一般形式為 union...
聯合體,位域, 結構體對齊
聯合體union 當多個資料需要共享記憶體或者多個資料每次只取其一時,可以利用聯合體 union 在c programming language 一書中對於聯合體是這麼描述的 1 聯合體是乙個結構 2 它的所有成員相對於基位址的偏移量都為0 3 此結構空間要大到足夠容納最 寬 的成員 1下面解釋這四...
聯合體 位域結構體 C C 中的位域
各種基本資料型別中,長度最小的 char 和 bool 在記憶體中占用乙個位元組的空間,但對於某些資料型別只需要幾個二進位制位即可儲存,例如 enum gameresult 由於它只有四種取值,只需要兩個二進位制位就可儲存,而乙個 gameresult 型別變數至少要佔1個位元組 8個二進位制位 在...