認識C語言中自定義型別 結構體與記憶體對齊

2021-10-12 06:51:41 字數 2559 閱讀 9167

1、結構體的宣告

使用關鍵字struct 定義:

struct  tag

variable _list;//分號不能丟

在宣告的時候,可以不完全宣告,(可以省略 tag  或者variable_list)
2、結構體自引用

struct node

3、結構體變數的定義和初始化

(1)定義結構體變數

struct  point

p1;//宣告型別的同時定義變數p1;

struct point p2;

//定義結構體變數p2;

struct point p3=;.

//宣告並初始化

4、結構體內存對齊

(1) 當我們要計算結構體的大小時,為什麼要按照結構體內存對齊規則?

舉個例子:

struct p

x;

要訪問結構體變數的成員時,需要通過(.),比如x.i ,x.b;

如果時cpu訪問記憶體中的x.i ,x.b時,由於硬體平台的限制,會增加訪問次數,畫圖理解一下:

訪問i時,從i的起始位置訪問四個位元組,取出第乙個位元組,但是訪問b時也是從i開始取4個位元組,此時b 的記憶體還沒取完,還要接著再取四個位元組,將第一次提取的後三個位元組和第二次提取的第乙個位元組合起來就是b的值,這樣訪問b時就多訪問了一次。

如果結構體內還有更多的資料,就會讓訪存次數增加很多,從而影響效率。

(2),什麼是記憶體對齊

通過犧牲空間換取效率的方案就是記憶體對齊,我們可以改變資料在記憶體中的儲存方式

如圖理解:

(3)如何記憶體對齊

struct s1

y;

你們覺得大小是 6個位元組嗎?其實他不是,是12個。

struct s2

x;

是不是覺得跟上邊的結構體大小一樣?不,他的大小是8,

下邊講解一下如何按照記憶體對齊計算結構體大小:

1)第乙個成員在與結構體變數在偏移量為0的位址處。(也就是第乙個成員不需要對齊)。(偏移量是相對第乙個元素的位置)

2)其他成員需要對齊到某個數字(對齊數)的整數倍的位址處。

對齊:我的起始偏移量是否能整除我的對齊數。

對齊數:編譯器預設的乙個對齊數與該成員大小的較小值。(對齊數一般是自身的大小,一般編譯器沒有預設對齊數,但是可以設定)。

3)結構的總大小是最大對齊數的整數被(所有成員的的對齊數比較)

4)如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍,結構體的整體大小就是所有對齊數(包含巢狀的結構體)的整數倍。

再看這個例子:

struct s2

x;

在記憶體中先放c2 (乙個位元組),再c1(偏移量:1)對齊數:1,可以整除,直接放(1個位元組),接著放 i  ,偏移量:2,對齊數 :4
不能整除,需要將i 偏移2 個位元組,佔(2+4)個位元組,三個總和,可以整除最大對齊數,所以總大小是8。

如圖:

再舉兩個例子:

如果結構體中有陣列,陣列中元素大小一樣,只要乙個元素對齊,其他的元素都可以對齊。

int

main()

x;//總大小57 ,最大對齊數 8,不能整除8,最後的大小是64

再舉乙個結構體自應用的例子:

int

main()

;//總大小20 ,最大對齊數 8,不能整除8,最後的大小是24

struct p2 ;

// 總大小是42 ,最大對齊數 8, 不能整除8,最後的大小是48

C語言中的自定義型別 struct結構體

c語言中的2種型別 原生型別 如int char等 和自定義型別 struct,enum等 結構體型別是是c語言中的使用者自定義型別,主要功能是對功能相關的資料進行封裝,它是乙個或多個變數的集合,這些變數的型別可以不同。例如一名學生可以由姓名和性別來描述,結構體中的成員也可以是乙個結構體,例如名字由...

C語言中的自定義型別 結構體 列舉 聯合

我們知道c語言基本資料型別有 本篇將重點介紹c語言中的自定義型別 結構體 列舉 聯合 struct stu int main 含義 define crt secure no warnings 1 include include struct x struct p int main 上面的 執行後發現...

C語言中的自定義型別(結構體 列舉及聯合)

結構體的記憶體對齊 位段列舉 聯合結構體是一些值的集合,這些值被稱為成員變數,結構的每個成員可以是不同型別的變數。struct piont p1 宣告結構體型別,同時定義變數p1 struct point p2 定義結構體變數p2 struct point p3 初始化 定義變數同時賦值 struc...