C語言結構體位元組對齊與位域

2021-10-09 20:27:13 字數 2611 閱讀 4321

一般的結構體

位域

#include

struct stu1

;//12位元組

可以看到,結構體大小並不是簡單的位元組相加。那麼,

結構體為什麼不設定成位元組簡單相加而去為難我們呢?

解:為了提高定址速度

我們可以試想結構體在呼叫成員的情況。比如呼叫成員c。它先找到我們定義的一大塊記憶體結構體s的首位址,float的大小是四個位元組,計算機找到第乙個成員的首位址,它是int佔四個位元組。可以每次都乙個位元組乙個位元組的定址如

#include

#pragma pack(1)

//定義定址長度(本人的說法,有風險)

struct stu1

;//19位元組

此處用到#pragma pack()巨集定義。筆者將其理解為定義定址長度。[^1]

註解如下[^1]

1.括號中的數字決定其定址長度。(1的話就乙個位元組乙個位元組的尋,就成了乙個變數乙個變數的存。所以長度就是變數長度和)

2.括號內的值只能從已存在的型別中(如1,2,4,8)選取且不超過結構體中最大的成員。其餘無意義。(如:若括號內填了3,5,7,相當沒填,對結構體大小不產生影響)

3.按照定址長度和變數中較大的定址。(如定址長度為4,要尋char,還是會乙個乙個的尋。定址長度為4,要尋double的址,4個4個的尋。)

1.變數前(面)位元組總數為該變數的整數倍,結構體大小為定址長度整數倍(定址長度無意義除外);

2.能放下不補齊,內嵌首尾只能補。

#include

#pragma pack(4)

struct stu1

;//24位元組

試試stu2的計算

1.變數前(面)位元組總數為該變數的整數倍,結構體大小為定址長度整數倍(定址長度無意義除外);

2.能放下不補齊,內嵌首尾只能補。

對著如上說法:i和j之間內嵌了乙個結構體,儘管兩個char小於四,能放下,但是只能給char補到四位元組。i元素佔了四位元組。然後繼續看內嵌的結構體,char和char能在定址長度4中放下,那就放,double來了放不下了,所以就把j,k後面補齊了兩位元組,再放double。然後m,n同理。r屬於內嵌尾部,只能補足四個位元組。所以其長度為4+1+3+8+4+4+4+4+4=36;

可是要是每次都乙個位元組乙個位元組的定址多慢啊。第乙個int型別資料它就得尋四次,那可能會想到既然要尋的是四個位元組,我就四個位元組四個位元組的尋,看了首位址要是不是我要找的資料我就跨四個位元組,再尋。這樣速度就快點了。如本文開始的例子,它佔了12個位元組。

1.變數前(面)位元組總數為該變數的整數倍(也有人說偏移量),結構體大小為最大成員的倍數;

2.能放下不補齊,有內嵌的內嵌之前的位元組總數為內嵌最大成員的整數倍。

#include

struct stu2

;char s;

//4float t;

//4//s後面能放下t,不補齊。哪怕把t刪了,結構體大小不變。};

//48

我們寫一般結構體時,有沒有什麼規則,只要我們遵從,就可以提高空間利用率,減少佔位。簡單來說,一湊二,二湊四,四湊八。先給資料變數按大小分類。把最大的寫最後面。一層一層的湊,越往上越小(二能湊到四視為四。當整體,不是說上面的就用佔位小的了)。

我們知道,char有乙個位元組,有八位二進位制數,同理,int可以存32位。其所存的值為所佔位元組能表示的值。如int a:1;就只能存0或1;

乙個例子

#include

struct stu3

;int

main()

;printf

("%d\t%d\t%d\t\n"

, t.f,t.g,t.k)

;printf

("結構體stu3的位元組數為:%d\t"

,sizeof

(struct stu3));

//printf("f的位址為%d\n",(int)(&t.f))//報錯,不允許採用位域的位址

return0;

}

我們知道int型別存值的範圍為$ -2^ 到231−

12^-1

231−

1,所以對於n位,所能存的值為−2n

−1到2

n−1−

1-2^到2^-1

−2n−1到

結構體位元組對齊與位域

code advance struct c includestruct person int main 1.本身的成員變數型別 2.結構體存在位元組對齊 結構體內部最大的單成員型別的整數倍 如果下乙個成員無法在有限的空間存放則需要乙個額外的空間存放 3.如何優化位元組對齊 1.按照有限空間合理排布成...

結構體位元組對齊和位域對齊 VC gcc

分類 c c 2012 10 13 15 34 474人閱讀收藏 舉報 1 什麼是位元組對齊 乙個變數占用 n 個位元組,則該變數的起始位址必須能夠被 n 整除,即 存放起始地 址 n 0,對於結構體而言,這個 n 取其成員中的資料型別佔空間的值最大的那個。2 為什麼要位元組對齊 記憶體空間是按照位...

位域與結構體對齊

一 位域 有些資訊在儲存時,並不需要占用乙個完整的位元組,而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態,用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為 位域 或 位段 所謂 位域 是把乙個位元組中的二進位劃分為幾 個不同的區域,並說明...