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

2021-09-29 06:25:06 字數 3778 閱讀 9195

結構體的基礎知識

結構是一些值的集合,這些值稱為成員變數。結構的每個成員可以是不同型別的變數。

結構體的宣告

例如描述乙個學生:

struct stu

s;//s為變數列表

typedef

struct stu

s,*p;

//s,*p為型別

在宣告結構的時候,可以不完全的宣告。

//匿名結構體型別

struct

x;struct

a[20],

*p;

結構的自引用

不使用typedef時

錯誤的方式:

struct node

;

這種宣告是錯誤的,因為這種宣告實際上是乙個無限迴圈,成員next是乙個結構體,next的內部還會有成員是結構體,依次下去,無限迴圈。在分配記憶體的時候,由於無限巢狀,也無法確定這個結構體的長度,所以這種方式是非法的。

正確的自引用方式: (使用指標):

struct node

;

由於指標的長度是確定的(在32位機器上指標長度為4),所以編譯器能夠確定該結構體的長度。

使用typedef 時

錯誤的方式:

typedef

struct

node;

這裡的目的是使用typedef為結構體建立乙個別名node。但是這裡是錯誤的,因為型別名的作用域是從語句的結尾開始,而在結構體內部是不能使用的,因為還沒定義。

正確的方式:有三種,差別不大,使用哪種都可以。

/* 方法一 */

typedef

struct node

node;

/* 方法二 */

struct tag_2;

typedef

struct tag_2 node;

struct tag_2

;/* 方法三 */

struct tag_3

;typedef

struct tag_3 node;

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

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

intmain()

struct stu

;struct stu s =

;//初始化

struct node

n1 =

,null};

//結構體巢狀初始化

struct node n2=

,null};

//結構體巢狀初始化

結構體的使用

介紹了以上結構體的使用規則,我舉兩個例子:

strcpy

(student.name,

"ningbo");

student.age =20;

strcpy

(student.***,

"female"

);

這裡我將 student 結構體變數的所有成員的值都改了一下。

然後再介紹結構體的一種訪問成員的方法:

首先得有乙個結構體指標:

struct stu* pstudent;

//定義乙個struct stu型的指標

pstudent =

&student;

//將結構體student的位址放在結構體指標pstudent裡面

然後再進行指標直接訪問:

strcpy

(pstudent->name,

"liubei");

pstudent->age =18;

strcpy

(pstudent->***,

"male"

);

這裡通過結構體指標pstudent將結構體student的成員又進行了修改。

結構體內存對齊

結構體的對齊規則:

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

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

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

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

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

//求結構體的大小

struct s1

;struct s2

;struct s3

;struct s4

;int

main()

利用 #pragma 這個預處理命令,可以改變我們的預設對齊數。

#pragma pack(1)

//設定預設對齊數為1

struct s2

;#pragma pack()

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

總體來說:

結構體傳參

struct s

;struct s s =

,1000};

//結構體傳參

void

print1

(struct s s)

//結構體位址傳參

void

print2

(struct s* ps)

intmain()

總結: 位段

位段的宣告和結構體是很類似的,只是成員的型別有區別:

位段的成員必須是 int, unsigned int 或 signed int。

位段的成員名後邊有乙個冒號和乙個數字,數字代表該成員所佔的位元位(bit)。

struct a

;struct s

;int

main()

列舉顧名思義就是——列舉,相當於建立乙個自定義型別,用這個型別建立的變數只能取你自己設定的範圍內的值,但這只是乙個符號的定義,實際上都是 int 型的。

enum color

;enum color clr=green;

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

clr=5;

intmain()

{}中的內容是列舉型別的可能取值,也叫 列舉常量。

列舉常量都是有值的,預設從0開始依次遞增1,當然在定義的時候也可以賦初值。

列舉的優點

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

聯合型別的宣告

union un

;

聯合變數的定義

union un un;
計算聯合體變數的大小

int

main()

聯合大小的計算

union un1

;union un2

;int

main()

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

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

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

結構 結構是一些值的集合,這些值稱為成員變數。結構的每個成員可以是不同型別的變數。struct tag variable list 宣告定義後所定義的成員變數 描述乙個學生 struct student 結構體的自引用 結構正確的自引用方式 struct node 2 typedef struct ...

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

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