1. 程式人生 > >簡析c語言中結構體的宣告使用以及位段

簡析c語言中結構體的宣告使用以及位段

1.結構體的定義

聚合資料型別能夠同時儲存超過一個的單獨資料。c語言中提供了兩種型別的聚合資料型別,陣列和結構。結構也是一些值的集合,這些值稱為它的成員。但每個成員可能具有不同的資料型別。結構體變數屬於標量型別,所以你可以像對待其他標量型別那樣執行相同型別的操作。結構體也可以作為傳遞給函式的引數。也可以作為返回值從函式中返回。相同型別的結構體之間可以相互賦值。下面我們定義一個結構體。

struct {
	int a;
	char c;
	int b;
}x;

這裡我們定義了一個變數x,他有三個成員,兩個整型,一個字元型變數。他通過(.)操作符來訪問,左運算元就是結構體的名字,右操作題就是訪問的成員,如果你擁有一個只想結構體的指標,(-.>)也可以訪問。

2.結構體的初始化

struct  {
	int a;
	char c;
	int b;
}x= { 2,'d',3 };
3.結構體的typedef
struct stu {
	int a;
	char c;
	int b;
};
這裡 stu 是結構體標籤
typedef struct  {
	int a;
	char c;
	int b;
}stu;
使用typeef定義後的結構體stu就是型別名。
4.結構體的記憶體儲存(記憶體對齊規則,為什麼存在記憶體對齊)
關於對齊規則,我們牢記以下幾點就好。
1.結構體的第一個成員永遠放在結構體的0偏移處;
2.從結構體的第二個成員開始,都要對齊到某個對齊數的整數倍處(對齊數為結構體成員自身大小和預設對齊數的較小值。vs下對齊數預設8個位元組,linux下是4個位元組)
3.結構體的總大小必須是最大對齊數的整數倍。
4.空結構體大小為1;
 struct stu {
	int a;
	double x;
	char c;
	int b;
};
這裡我們舉個例子
1.首先,int a 是4個位元組而且是第一個成員,所以從記憶體開闢的0偏移處開始向下開闢四個位元組。
2.接下來是double x自身是8個位元組,系統預設的對齊數是8個位元組,所以對齊數就是8,所以從8偏移處開闢8個位元組。
3.接下來是char c是一個位元組,所以根據第二條規則對齊數就是1.所以在16偏移處開闢一個位元組;
4.最後是int b,此時對齊數是4.所以從20偏移開始開闢四個位元組;
5.根據最後一條規則,則這個結構體的大小就是24個位元組;
程式驗證正確。
對齊的作用和原因;
各個硬體平臺對儲存空間的處理上有很大的不同。一些平臺對某些特定型別的資料只能從某些特定的地址開始存取,比如有些架構的cpu在訪問一個沒有進行對齊的變數的時候就會發生錯誤,那麼在這種結構下程式設計必須保證位元組對齊,其他平臺可能沒有這種情況,但是最常見的如果不按照合適其平臺要求對資料存放進行對齊,會在存取效率上帶來損失。比如說有些平臺每次讀都是從偶地址開始,如果一個int型(假設為32位平臺)如果存放在偶地址開始的地方,那麼一個讀週期就可以讀出32bit,而如果存放在地址開始的地方,就需要2個週期,並對兩次讀出的結構的高低位元組進行拼湊才能得到該32bit資料,顯然在讀取效率上下降很多。
5.結構實現位段,位段大小計算。位段的資料存取。
在記憶體儲存中,有些資訊的村粗並不需要佔用一個位元組,只需要幾個位元位,為了節省空間,c語言中提供了一種資料結---位段。其成員型別可以為:int char signed
unsigned int ,其次在成員名後面是一個冒號和一個整數,這個整數指定改位段所佔用的位的數目。
struct stu {
	unsigned int a : 7;
	unsigned int b : 10;
	unsigned int c : 19;
} ;
計算大小;
a)1)如果一個位段儲存單元能夠儲存得下位段結構中的所有成員,那麼位段結構中的所有成員只能放在一個位段儲存單元中,不能放在兩個位段儲存單元中;如果一個位段儲存單元不能容納下位段結構中的所有成員,那麼從剩餘的位段從下一個位段儲存單元開始存放。(在VC中位段儲存單元的大小是4位元組);    b)如果一個位段結構中只有一個佔有0位的無名位段,則只佔1或0位元組的空間(C語言中是佔0位元組,而C++中佔1位元組);否則其他任何情況下,一個位段結構所佔的空間至少是一個位段儲存單元的大小。