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

2021-10-07 12:05:07 字數 4431 閱讀 4721

①.結構體型別的宣告
struct tag

variable-list;

//例如描述乙個學生

struct stu

;//分號不能丟

//特殊宣告

//匿名結構體型別

struct

x;struct

a[20],

*p;

②.結構的自引用
//**1

struct node

;

該結構體定義是錯誤的,因為結構體的大小是根據其中的成員變數的大小以及"記憶體對齊"決定的,所以不知道struct node的大小,如果在其中再這樣定義struct node next;自引用後系統也不知道該開闢多大的記憶體空間,所以這樣的定義是錯誤的。

正確的定義:

//**2

struct node

;

//這樣的定義也是錯誤的

//**3

typedef

struct n

node;

③.結構體變數的定義和初始化
struct point

p1;//宣告型別的同時定義變數p1,不建議這樣做,建議在使用時候再定義變數

struct point p2;

//定義結構體變數p2

//初始化:定義變數的同時賦初值。

struct point p3 =

;struct stu //型別宣告

;struct stu s =

;//初始化

struct node

n1 =

,null};

//結構體巢狀初始化

④.結構體內存對齊
//什麼是記憶體對齊

計算結構體的大小時候需要考慮記憶體對齊問題

記憶體對齊是為了提高訪問效率(犧牲記憶體,提高訪問效率)

處理器每次訪問棧時從中讀取的位元組數是一定的。

如果沒有記憶體對齊原因在於,為了訪問未對齊的記憶體,處理器

需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問

//如何記憶體對齊

1. 第乙個成員在與結構體變數偏移量為0的位址處。

2. 其他成員變數(除了第乙個變數外的變數)要對齊到某個數字(對齊數)

的整數倍的位址處。

對齊數 = 編譯器預設的乙個對齊數 與 該成員大小的較小值

vs2013的預設對齊數為8

3. 結構體總大小為最大對齊數(每個成員變數都有乙個對齊數)的整數倍。

4. 如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的

整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊

數)的整數倍。

例題:

//練習1

struct s1

;printf

("%d\n"

,sizeof

(struct s1));

//12

//練習2

struct s2

;printf

("%d\n"

,sizeof

(struct s2));

//8//練習3

struct s3

;printf

("%d\n"

,sizeof

(struct s3));

//16

//練習4-結構體巢狀問題

struct s4

;printf

("%d\n"

,sizeof

(struct s4));

//32

⑤.結構體傳參
struct s

;struct s s =

,1000};

//結構體傳參方法一

void

print1

(struct s s)

//結構體位址傳參方法二

void

print2

(struct s* ps)

intmain()

結構體傳參時是乙個值拷貝的過程

如果傳遞乙個結構體物件的時候,結構體過大,系統開銷比較大,所以會導致效能的下降。更有可能導致程式崩潰

⑥.結構體實現位段(位段的填充&可移植性)
什麼是位段?

位段的宣告和結構是類似的,有兩個不同:

1.位段的成員必須是 int、unsigned

int 或signed

intchar。

(整形)中的一種

2.位段的成員名後邊有乙個冒號和乙個數字,表示所使用的的位元位

例如:

struct a

;printf

("%d\n"

,sizeof

(struct a));

//8

位段的記憶體分配

1. 位段的成員可以是 int

unsigned

intsigned

int 或者是

char (屬於整形家族)型別

2. 位段的空間上是按照需要以4個位元組( int )或者1個位元組

( char )的方式來開闢的。

3. 位段涉及很多不確定因素,位段是不跨平台的,注重可移植的

程式應該避免使用位段。

列舉顧名思義就是一一枚舉。

把可能的取值一一枚舉。

比如我們現實生活中:

一周的星期一到星期日是有限的7天,可以一一枚舉。

性別有:男、女、保密,也可以一一枚舉。

月份有12個月,也可以一一枚舉

顏色也可以一一枚舉。

這裡就可以使用列舉了。

①.列舉型別的定義
enum day//星期

;enum ***//性別

以上定義的 enum day , enum ***  都是列舉型別。 中的內容

是列舉型別的可能取值,也叫 列舉常量 。

這些可能取值都是有值的,預設從0開始,一次遞增1,當然

在定義的時候也可以賦初值。

②.列舉的優點
我們可以使用 #define 定義常量,為什麼非要使用列舉? 列舉的優點:

1. 增加**的可讀性和可維護性

2. 和#define定義的識別符號比較列舉有型別檢查,更加嚴謹。

3. 防止了命名汙染(封裝)

4. 便於除錯

5. 使用方便,一次可以定義多個常量

③.列舉的使用
enum color//顏色

;enum color clr = green;

//只能拿列舉常量給列舉變數賦值,才不會出現型別的差異。

clr =5;

//ok

聯合也是一種特殊的自定義型別 這種型別定義的變數也包含一系列的成員

,特徵是這些成員公用同一塊空間(所以聯合也叫共用體)。

①.聯合型別的定義
//聯合型別的宣告

union un

;

②.聯合的特點
聯合的成員是共用同一塊記憶體空間的,這樣乙個聯合變數的大小,至少是

最大成員的大小(因為聯合至少得有能力儲存最大的那個成員)。

union un

;union un un;

//下面輸出的結果是什麼?

un.i =

0x11223344

;un.c =

0x55

;printf

("%x\n"

, un.i)

;//11223355

可以用來判斷記憶體的大小端儲存如果結果為11223355則為小端儲存

結果為55223344則為大端儲存

③.聯合大小的計算
聯合的大小至少是最大成員的大小。

當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的

整數倍。

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...

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

二 列舉 三 聯合 1.結構體型別建立 struct stu 定義乙個學生結構體 分號不能丟 特殊的宣告 在宣告結構的時候,可以不完全的宣告 比如 匿名結構體型別 struct x struct a 20 p p x 非法,編譯器會把上面的兩個宣告當成完全不同的兩個型別 結構的不完整宣告 struc...