C語言自定義型別

2021-09-27 04:28:27 字數 3530 閱讀 2997

在學習c語言的時候,它有很多的自定義型別,例如:結構體,列舉,聯合。。。

這些型別在我們的日常使用的時候,或多或少的都會遇見到,下面就系統的介紹一下這幾種型別。

一.結構體

1.結構體型別的宣告:通俗點來說,結構就是一些值的集合,這些值稱為成員變數,結構體的每個成員可以是不同型別的成員變數。

如下所示:

struct goods

;

結構體使用的時候也可以省略掉結構體的標籤

struct

name;

2.結構體自引用的書寫形式

struct node

;

也可以寫成下面這樣的**

typedef

struct node

node;

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

struct point

p1;struct point p1 =

;struct node

n1 =

,nullptr}

;//結構體巢狀初始化

strcut node n2 =

,nullptr}

;

4.結構體內存對齊

當我們計算結構體的大小的時候,就必須要運用記憶體對齊規則

struct s3

;struct s4

;int

main()

5.結構體傳參

struct s

;struct s s =

,10000};

void

print

(struct s* ps)

intmain()

//在這裡為什麼要傳位址呢?

//因為在函式傳參的時候,引數是需要進行壓棧的,如果傳遞給乙個結構體物件的時候,

//結構體過大,引數壓棧的系統開銷比較大,所有會導致效能的下降。

//所以結構體傳參的時候要傳位址。

6.位段

struct a

;//a就是乙個位段,那麼位段a的大小是多少呢?

printf

("%d\n"

,sizeof

(struct a)

);

c語言標準規定,位域的寬度不能超過它所依附的資料型別的長度。通俗地講,成員變數都是有型別的,這個型別限制了成員變數的最大長度,:後面的數字不能超過這個長度。

c語言標準還規定,只有有限的幾種資料型別可以用於位域。在 ansi c 中,這幾種資料型別是 int、signed int 和 unsigned int(int 預設就是 signed int);到了 c99,_bool 也被支援了。

但編譯器在具體實現時都進行了擴充套件,額外支援了 char、signed char、unsigned char 以及 enum 型別,所以上面的**雖然不符合c語言標準,但它依然能夠被編譯器支援。

二.列舉

1.列舉型別的定義

enum day//星期

;//上述定義的就是乙個列舉型別,{}中的內容是列舉型別的可能用值,也叫做列舉常量

//這些在取值都是有值的,預設是從1開始,一次遞增1,當然在定義的時候可以副賦初值。

enum color

;

2.列舉的優點

3.列舉的使用

enum color

;enum color clr = green;

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

三.聯合(共用體)

1.聯合的定義

聯合是一種特殊的自定義型別,這種型別定義的變數也包含一系列的成員,特徵是這些成員共用一塊空間(所以聯合也叫共用體)

例如:

union un

;union un u;

printf

("%d\n"

,sizeof

(u))

;//4

2.聯合的特點

聯合的成員是公用同一塊記憶體空間的,這樣乙個聯合變數的大小,至少是最大成員的大小。

union un

;union un u;

printf

("%d\n",&

(u.i));

printf

("%d\n",&

(u.c));

u.i =

0x11223344

;u.c =

0x55

;printf

("%x\n"

, u.i)

;

3.聯合大小的計算

union un1 

;union un2

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

intmain()

面試題:

1.結構體的記憶體對齊規則:

2.為什麼存在記憶體對齊?

2.效能原因:資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要做兩次記憶體訪問,而對齊的記憶體訪問僅需要一次訪問。

總體來說:結構體的記憶體對齊是拿空間換時間的做法。

我們在設計結構體的時候,既要滿足記憶體對齊,又要節省空間,所以應該讓占用空間小的成員集中在一起。

3.設計結構體的時候,既要滿足記憶體對齊,又要節省空間,又該如何?

struct s1		//12

;struct s2 //8

s1和s2型別的成員一模一樣,但是s1和s2所佔空間的大小有了一些區別

#pragma pack(5)

struct s1

;#pragma pack()

#pragma pack(1)

struct s2

;#pragma pack()

intmain()

4.寫乙個巨集,計算結構體中某變數相對於首位址的偏移,並給出證明

#define find(student, e) (size_t)&(((student*)0) - >e)

struct student

;int

main()

c語言 自定義型別

struct stu 分號不能丟 匿名結構體型別 struct x struct a 20 p p x 非法的操作,上面倆種完全是不同的宣告 struct node 結構體的自引用 struct node n1 null 直接初始化 struct node n2 null 結構體巢狀初始化 先來看下...

C語言之自定義型別

結構體型別的建立struct tag stu struct class struct class1 int main 這裡編譯器會把上邊兩個宣告當作不同的型別,而且如果我們在想建立乙個相同成員的結構體class2,就必須的在main 函式前邊建立,這樣及其不方便。struct tag class i...

C語言 自定義型別詳解

目錄 直接上 struct point p1 建立結構體時順便建立變數,分號一定不能掉 struct point p2 單獨建立變數 struct point p3 建立變數時順便賦值 struct node n1 int main struct是建立結構體的關鍵字,point是結構體的名字,p1為...