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

2021-08-20 07:31:11 字數 4174 閱讀 4353

結構體:

所謂結構體,就是將一大堆值放在一起,建立乙個新的型別,這些成員可以是不同型別的變數。

struct tag

variable-list;

tag:   要求:1.見名知意; 2.可以省略; 3.不建議省略;

member-list: c語言中,不能為空;

variable-list: 變數列表,可以省略,建議省略;

結構體之間不能互相複製;例如:

struct 

x;

struct

a[20],*p;

p = &x;    (錯誤!)

結構體位址 = 首元素位址(在數值上)

結構體內元素位址遞增;

結構體成員訪問:

結構體變數的成員是通過點操作符(.)訪問的;

例如:

struct

;

struct s s

strcpy(s.name,"zhangsan");

s.age = 20;

或者用指標訪問:

(*p).a =

(*p).b =

或:p->a =

p->b =

void print(struct s* ps)

結構體的自引用:

正確方式(必須用指標):

struct node

;

也可以對結構體進行重新命名:

typedef ……

結構體的不完整宣告,結構體之間可以互相引用嗎,答案是肯定的,不過,要提前宣告才行;

struct b

struct a

;struct b

;

結構體與陣列一樣,不能被整體賦值,但可以被初始化;

結構體的記憶體對齊:

即結構體的大小計算:

首先,了解一下對齊規則:

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

2.其他成員變數要對其到某個數字(對齊數)的整數倍的位址處。對齊數=編譯器預設的乙個對齊數與該成員大小的較小值。(vs中預設的值是8,linux中預設的值是4)

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

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

那為什麼存在記憶體對齊呢?

1.平台原因(移植原因):

2.效能原因:

總之,結構體對齊是拿空間來換取時間的做法;

修改對齊數:

#pragma pack( )——修改預設對齊數;

設定為1,2,4,8……

空白表示恢復預設;

結構體傳參:

結構體傳參不發生降維,不過,結構體傳參盡量不傳結構體變數,而傳結構體指標;

struct s

;struct s s = ,1000};

void print(struct s* ps)

int main()

位段:

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

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

比如:

struct a

;

這個數字表示 占用的byte位

位段採用壓縮儲存;

位段的記憶體分配:

1.位段的型別可以是int  unsigned int  signed int 或者是 char 型別;

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

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

位段的跨平台問題:

1.int 位段被當成有符號數還是無符號數是不確定的;

2.位段中最大位的數目不能確定(16位機器最大16,32位機器最大32,寫成27,在16位機器會出問題。)

3.位段中的成員在記憶體中從左向右分配還是從右向左分配,標準尚未定義;

4.當乙個結構包含兩個位段,第二個位段成員比較大,無法容納第乙個位段剩餘的位時,是捨棄剩餘的位還是利用,這是不確定的;

列舉:

列舉——顧名思義就是一一枚舉;

列舉內的內容都是常量;

例如:

enum day //星期

;

這些列舉中的內容是列舉型別的可能取值,也叫列舉常量,這些可能取值都是有值的,預設從0開始,依次遞增1,當然也可以自行賦值;

列舉的優點:

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

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

3.防止了命名汙染;

4.便於除錯;

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

聯合:

聯合的成員是共用同一塊記憶體空間的,所以乙個聯合體的大小,至少是最大成員的大小;

例如:面試題 判斷當前計算機的大小端;

union un

;union un;

un.i = 0x11223344;

un.c = 0x55;

printf("%x\n",un.i);

執行上述**,若輸出結果為55223344,則該計算機為小端,若輸出結果為11223355;則該計算機為大端;

聯合大小計算:

聯合體的大小至少是最大成員的大小;

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

聯合體和結構體的巧妙運用:

//將long型別的ip位址,轉換為點分十進位制的表示形式;

union ip_addr

ip;};

union ip_addr my_ip;

my_ip.addr = 176238749;

printf("%d.%d.%d.%d\n",my_ip.ip.c4,my_ip.ip.c3,my_ip.ip.c2,my_ip.ip.c1);

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

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

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

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

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

結構的成員可能具有不同的型別.而且,每個結構成員都有名字,所以為了選擇特定的結構成員需要指明結構成員的名字而不是他的位置.和陣列一樣,結構變數也可以在宣告的同時進行初始化.為了對結構進行初始化,要把待儲存到結構中的值的列表準備好並用花括號括起來.初始化式中的值必須按照結構成員的順序進行顯示,結構初始...