C學習筆記(6)--- 共用體,位域深刻

1.共用體:html

 

共用體是一種特殊的數據類型,容許您在相同的內存位置存儲不一樣的數據類型。您能夠定義一個帶有多成員的共用體,可是任什麼時候候只能有一個成員帶有值。共用體提供了一種使用相同的內存位置的有效方式。
數據結構

爲了定義共用體,您必須使用 union 語句,方式與定義結構相似。ide

 

例子:spa

union Data { code

  int i; htm

  float f; 內存

  char str[20]; ci

} data;字符串

 

這意味着一個變量(相同的內存位置)能夠存儲多個多種類型的數據。您能夠根據須要在一個共用體內使用任何內置的或者用戶自定義的數據類型。共用體的佔用的內存大小由最大的變量決定---這個例子裏面就是字符串(char str[20]),佔用20個字節內存。get

 

爲了訪問共用體的成員,咱們使用成員訪問運算符(.)。 可是和結構體不同,因爲共用體本質上是一個內存位置,因此會致使在同一時間裏只能有一個值佔用內存位置。

 

好比:

data.i = 10;

data.f = 220.5;

strcpy( data.str, "C Programming");

printf( "data.i : %d\n", data.i);

printf( "data.f : %f\n", data.f);

printf("data.str : %s\n", data.str);

打印(printf)這個三個值,前兩個值都會損壞,由於內存位置被賦給了str.

 

可是假如是:

 

data.i = 10;

printf( "data.i : %d\n", data.i);

data.f = 220.5;

printf( "data.f : %f\n", data.f);

strcpy( data.str, "C Programming");

printf( "data.str : %s\n", data.str);

 

每次內存被佔用以後都打印了出來,而後又從新賦值,因此不會形成損壞。

 

 

共用體做用:

 

節省內存,有兩個很長的數據結構,不會同時使用,好比一個表示老師,一個表示學生,若是要統計教師和學生的狀況用結構體的話就有點浪費了!用共用體的話,只佔用最長的那個數據結構所佔用的空間,就足夠了!

 

共用體應用場景:

 

通訊中的數據包會用到共用體:由於不知道對方會發一個什麼包過來,用共用體的話就很簡單了,定義幾種格式的包,收到包以後就能夠直接根據包的格式取出數據。

 

2.位域(深刻):

 

假設咱們須要一個結構體只儲存一個固定長度的值(好比說 1,0 這種來表明true/false --- 0001只須要一個bit)的,若是正常去定義,須要兩個 int (每一個4字節 Byte,一共 8 Byte)。C 語言提供了一種更好的利用內存空間的方式。若是您在結構內使用這樣的變量,您能夠定義變量的寬度來告訴編譯器,您將只使用這些字節Byte。

 

定義例子:

struct {

  unsigned int widthValidated : 1;

  unsigned int heightValidated : 1;

} status;

 

如上,status 變量將佔用 4 個字節(byte)的內存空間,可是隻有 2 位(bit)被用來存儲值,意思就是說這兩個成員共用了一個int的內存空間(都是同類型)。

若是您用了 32 個變量,每個變量寬度爲 1 位,那麼 status 結構將使用 4 個字節,但只要您再多用一個變量,若是使用了 33 個變量,那麼它將分配內存的下一段來存儲第 33 個變量,這個時候就開始使用 8 個字節。

 

Age.age = 7;

printf( "Age.age : %d\n", Age.age );

Age.age = 8; // 二進制表示爲 1000 有四位,超出

printf( "Age.age : %d\n", Age.age );

 

output :

Age.age : 7 Age.age : 0

 

 

這個結果還會伴隨着警告。

 

 

 

sub:(來自上章)

 

1.一個位域存儲在同一個字節中,如一個字節所剩空間不夠存放另外一位域時,則會從下一單元起存放該位域。也能夠有意使某位域從下一單元開始。

 

2.因爲位域不容許跨兩個字節,所以位域的長度不能大於一個字節的長度,也就是說不能超過8位二進位。若是最大長度大於計算機的整數字長,一些編譯器可能會容許域的內存重疊,另一些編譯器可能會把大於一個域的部分存儲在下一個字中。

 

3.位域能夠是無名位域,這時它只用來做填充或調整位置。無名的位域是不能使用的.

 

4.位域在本質上就是一種結構類型,不過其成員是按二進位分配的。

 

5.結構體變量的首地址可以被其最寬基本類型成員的大小所整除。

 

6.結構體每一個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,若有須要編譯器會在成員之間加上填充字節(internal adding)。即結構體成員的末地址減去結構體首地址(第一個結構體成員的首地址)獲得的偏移量都要是對應成員大小的整數倍。

 

7.

超出範圍並非直接丟棄,而是保留對應的 3 位的值。

好比 8 是 00001000,按照位域,對應 3 位的值是 000,因此打印結果是 0;

可是 9 是 00001001,按照位域,對應 3 位的值是 001,因此打印結果是 1;

同理 10 是 00001010,按照位域,對應 3 位的值是 010,因此打印結果是 2;

 

 

引用:

https://www.runoob.com/cprogramming/c-unions.html

https://www.runoob.com/cprogramming/c-bit-fields.html

相關文章
相關標籤/搜索