自定義型別 結構體,列舉型別,聯合型別

2021-10-24 10:43:10 字數 4359 閱讀 7754

2.列舉

3.聯合體

4.練一練

struct tag

variable_list;

//結構體變數列表

struct point

p1;//宣告結構體的同時定義了結構體變數

匿名結構體

struct

x;struct

a[20],

*p;//此時:*p=&x;//非法,無法判斷結構體的型別

結構體內部包含指向自身的結構體指標

struct node

typedef

struct node

node;

struct point

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

struct point p2;

//定義結構體變數p2

struct point p3 =

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

struct stu //型別宣告

;struct stu s =

;//初始化

struct node

n1 =

,null};

//結構體巢狀初始化

struct node n2 =

,null};

//結構體巢狀初始化

//計算結構體大小

struct s3

;printf

("%d\n"

,sizeof

(struct s3));

//結果:12

struct s4

;printf

("%d\n"

,sizeof

(struct s4));

//結果:24

對齊規則

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

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

vs中預設的值為8

linux中的預設值為4

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

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

修改預設對齊數

#pragma pack(8)

//設定預設對齊數為8

struct s1

;#pragma pack()

//取消設定的對齊數,還原為預設值

結果:16

計算結構體成員對於結構體起始位置的偏移量offsetof實現:

struct s3

;int

main()

struct s

;struct s s =

,1000};

//結構體變數

void

print1

(struct s s)

//結構體傳參

void

printf2

(struct s* ps)

//結構體位址傳參

intmain()

1.位段的成員必須是 int、unsigned int 或signed int,char 。

2.位段的成員名後面有乙個冒號和乙個數字

struct a

;//此結構體大小為:8

位段的記憶體分配

位段的空間上是按照需要以4個位元組( int )或者1個位元組( char )的方式來開闢的。

位段涉及很多不確定因素,位段是不跨平台的,注重可移植的程式應該避免使用位段。

struct s

;//大小為3位元組

intmain()

; s.a =10;

//1001,成員a只佔3bit,初始化後放不下,只能擷取

s.b =12;

//1100

s.c =3;

//0011

s.d =4;

//0100

return

0;}

一一枚舉

//列舉常量的值預設從0開始,一次遞增1,也可以賦值

enum day//星期

;enum ***//性別

;

#define也可以定義常量,那麼列舉為什麼會存在?

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

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

3. 防止了命名汙染(封裝)(define是全域性的,enum是區域性的,不易衝突)

4. 便於除錯(define不可以除錯)

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

enum color//顏色

;enum color clr = green;

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

clr=5;

//非法,5是整形字面常量,clr是乙個列舉變數,型別不一樣,不能匹配

聯合成員共用同一塊記憶體空間

//聯合型別的宣告

union un

u;//聯合變數的定義

union un un;

u.i=

0x12345678

;printf

("%x\n"

, un.c)

;//結果:78(小端儲存,共同一塊記憶體空間,聯合變數c佔乙個位元組)

//計算聯合變數的大小

printf

("%d\n"

,sizeof

(un));

//4至少是最大成員的大小

聯合變數公共使用同一塊記憶體空間

union un

;union un un;

printf

("%d\n",&

(un.i));

printf

("%d\n",&

(un.c));

//結果一樣

un.i =

0x11223344

;un.c =

0x55

;printf

("%x\n"

,un.i)

;//結果:0x11223355

在任意一時刻,聯合中只存放乙個成員,並且對於聯合成員進行賦值會對其成員重寫,原來的成員的值不存在了。

1.聯合的大小至少是最大成員的大小。

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

union un1

;union un2

;//聯合體大小:8, 16

1.在vs2013下,這個結構體所佔的空間大小是( 12)位元組

typedef

struct

aa_t;

2.下面**的結果是:( 16)

#include

union un

;int

main()

解析:聯合體共用一段空間,因此看最大的成員所佔的空間,其次還要看記憶體是否對齊,用聯合體內型別最大的成員大小和系統預設對齊數取最小,得到對齊數,然後看最大成員所佔空間是否是為對齊數的整數倍

型別最大的int與預設對齊樹8取最小 4 14不是4的整數倍 則要對齊到4的整數倍因此該聯合體的大小是16

3.下面**的結果是:(1 257 )

enum enum_a

;enum enum_a enuma = y1;

enum enum_a enumb = b1;

printf

("%d %d\n"

, enuma, enumb)

;

解析:哈哈是不是忘記了列舉型別第乙個元素從1還是0開始。

列舉中元素的預設值是從0開始的往後一次遞增

如果中途賦值了 從該值往後遞增因此y1位1 b1位257

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

結構體 所謂結構體,就是將一大堆值放在一起,建立乙個新的型別,這些成員可以是不同型別的變數。struct tag variable list tag 要求 1.見名知意 2.可以省略 3.不建議省略 member list c語言中,不能為空 variable list 變數列表,可以省略,建議省略...

自定義型別 結構體,列舉,聯合

首先先說一下c語言的資料型別,其框架型別如圖所示 今天主要說一下結構體,列舉,聯合這三種自定義型別。1,結構體 1.1 結構體的宣告 結構體是一些值的集合,這些值稱為成員變數,結構體的每個成員可以是不同型別得變數。1 結構體的成員 結構體的成員可以是標量,陣列,指標,甚至是其他結構體。2 結構體的宣...

自定義型別 結構體,列舉,聯合

結構體的宣告 struct tag variable list 例如描述乙個學生 struct stu 分號不能丟特殊的宣告 在宣告結構的時候,可以不完全的宣告。比如 匿名結構體型別 struct x struct a 20 p 警告 編譯器會把上面的兩個宣告當成完全不同的兩個型別。所以是非法的。結...