C語言 結構體struct 結構體對齊

2021-09-29 03:31:40 字數 4020 閱讀 7671

1、定義乙個結構體(順便例項結構體變數):

struct

tag(結構體型別名)

//struct + tag 這兩者共同構成了結構體型別 單獨的tag(結構體型別名) 不能稱之為結構體型別

(結構體變數名)

;

2、定義的同時使用typedef(相當於定義結構體 + 為結構體起新名字)

typedef

struct

tag(結構體型別名)

//struct + tag(結構體型別名) == 結構體型別

mystruct

(結構體型別)

;此時mystruct ==

struct tag

例項化時:

1、c中:

struct tag a; //struct + tag 這兩者共同構成了結構體型別 單獨的tag(結構體型別名) 不能稱之為結構體型別

mystruct a; //mystruct(結構體型別) = struct +結構體型別名

2、c++中

tag a; 合理 tag和mtstruct均是結構體型別

mystruct a; 合理

結構體型別的定義格式為:strcut結構體名;

結構體變數的定義有3種形式:

1、定義結構體型的同時定義結構體變數

如:strcut結構體名變數;

2、先定義乙個結構體型別,然後使用該型別來定義結構體變數,

如:strcutstudent:student變數;

3、定義乙個無名稱的結構體型別的同時定義結構體變數

如:strcutstudent變數;

如果在函式內宣告→作用域僅限函式內部

可以只初始化乙個成員,也可以任意順序初始化

struct boot gift =

意義:記憶體對齊可以大大提公升記憶體訪問速度,是一種用空間換時間的方法。

(記憶體不對齊會導致每次讀取資料都會讀取兩次,使得記憶體讀取速度減慢。)

1、資料成員自身的對齊值:

2、結構體/類的自身對齊值:其成員中自身對齊值最大的那個值。

3、對齊係數:#pragma pack (value)時的指定對齊值value。(vs中預設的值為8;linux中的預設值為4。)

4、資料成員、結構體/類的有效對齊值n:自身對齊值和指定對齊值中小的那個值。

僅long和point的長度受到系統環境的影響

1、第乙個成員的首位址為0.

2、其餘成員的首位址是對齊數的整數倍,對齊數=min(對齊係數,成員自身長度)

3、結構體的總大小,為所有最大對齊數(含巢狀結構體的對齊數)的整數倍。

修改預設對齊數:

預處理指令: #pragma pack(?)

例如:#pragma pack(4)

struct

故整體結構體的記憶體對齊為24位元組

1.下面的結構體大小分別是多大(假設32位機器)?

struct a

;//進行整體對齊,最大型別為1《對齊係數4,按1整體對齊,所以1+1+1=3

struct b

;//進行整體對齊,最大型別為4=對齊係數4,所以按4整體對齊4 1+2=3<4 對齊4 所以4+4=8

struct c

;//進行整體對齊,最大型別為4=對齊係數4,所以按4整體對齊 1<4(對齊4) 4=4 2<4(對齊4) 所以4+4+4=12

#pragma pack(2)

struct d

;//進行整體對齊,最大型別為4>對齊係數n(2),所以按2整體對齊 1<2(對齊2)4>2(2的倍數) 2=2 所以2+4+2=8

//4行(每行2位元組)

// 1位元組char 空白1位元組

// int前半2位元組

// int後半2位元組

// short2位元組

2. 有乙個如下的結構體:

struct a

; 答案及解析:24

64位編譯器下:指標8位元組(一定不能忘記),題目不說預設4位元組對齊

long a1;

//8short a2;

//2 8+2=10(不是4的倍數)對齊到4的倍數12

int a3;

//4 4+12=16(4的倍數)

int*a4;

//8 8+16=24(4的倍數)

//6行

// long前4位元組

// long後4位元組

// short2位元組 空白2位元組

// int4位元組

// point前4位元組

// point後4位元組

3.在32位cpu上選擇預設對齊的情況下,有如下結構體定義:

struct a

;則sizeof(struct a)的值為16位元組

題目不說,預設linux對齊係數=

4位元組對齊19+

11=30<

32bit 44+

29=33>

32bit 4+4

1byte=

8bit 1 對齊到 44+

4+4+

4=16//4行(對齊4位元組)

// a19位 b11位 空白2位

// c4位 空白28位

// d29位 空白3位

// char1位元組 空白3位元組

typedef

struct bb //sizeof(bb) == 16位元組

bb;//4行,每行4=double對齊值4= min(linux預設對齊係數4,double長度8)

// int4位元組

// double前4位元組

// double4位元組

// float4位元組

typedef

struct aa

aa;//9行,每行4位元組 此結構體的對齊值 = 該結構體中最大的對齊值,即4

// char2位元組 空白2位元組

// int4位元組

// double前4位元組

// double後4位元組

// short2位元組 空2位元組

// 4行bb(每行4位元組) bb成員的對齊值 = min(linux對齊引數4,bb長度16) = 4

柔性陣列,它只能放在結構體末尾,是申明乙個長度為0的陣列,就可以使得這個結構體是可變長的。

例如:char data[0];

char data;

//中沒有或者0

對於編譯器來說,此時長度為0的陣列並不占用空間,因為陣列名本身不佔空間,它只是乙個偏移量, 陣列名這個符號本身代 表了乙個不可修改的位址常量 (注意:陣列名永遠都不會是指標! ),但對於這個陣列的大小,我們可以進行動態分配 請仔細理解後半部分,對於編譯器而言,陣列名僅僅是乙個符號,它不會占用任何空間,它在結構體中,只是代表了乙個偏移量,代表乙個不可修改的位址常量!

對於0長陣列的這個特點,很容易構造出變成結構體,如緩衝區,資料報等等:

注意:構造緩衝區就是方便管理記憶體緩衝區,減少記憶體碎片化,它的作用不是標誌結構體結束,而是擴充套件

柔性陣列是c99的擴充套件,簡而言之就是乙個在struct結構裡的標識佔位符(不佔結構struct的空間)。

意義:1、方便管理記憶體緩衝區

2、減少記憶體碎片化

3、把單一元素的陣列放在乙個struct的尾端,使得每個struct物件可以擁有可變大小的陣列。

typedef

struct list_tlist_t;

C語言結構體struct

定義 定義結構體,要定義兩次,1定義型別,2定義變數 1定義時 不分配記憶體,和 define一樣 定義結構體的樣式,叫什麼名字,成員,句式 2再定義 分配記憶體 用著個樣式定義變數 與typedef有點像 3如果定義的是 p指標,只表示出此結構體 變數的起始位址 struct a struct a...

C語言結構體(Struct)

在c 語言中,可以使用結構體 struct 來存放一組不同型別的資料。結構體的定義形式為 struct 結構體名 結構體是一種集合,它裡面包含了多個變數或陣列,它們的型別可以相同,也可以不同,每個這樣的變數或陣列都稱為結構體的成員 member 請看下面的乙個例子 struct stu stu 為結...

Struct 結構體疑惑(c語言)

struct 結構體疑惑 c語言 如有錯,請務必指正 本文主要介紹在 struct 結構體中對陣列和指標的操作細節。我們需要明確兩個概念 a 初始化 分配記憶體並寫入值。b 賦值 查詢記憶體並寫入值。在結構體中,陣列和指標最大的的區別為 陣列將資訊存在結構體所占有的記憶體中,而指標是將資訊的首位址儲...