自定義型別

2021-08-20 06:57:53 字數 3697 閱讀 5159

struct tag

//結構體型別

variable

-list; //結構體變數

//tag 結構體標籤

例如

struct stu

;

特殊的宣告
//匿名結構體型別

struct

//省略結構體標籤

x; //若不建立x,則無法使用該結構體

結構體的不完全宣告
struct b; //不完全宣告

struct a

;struct b

;

結構體的成員可以是標量,陣列,指標,甚至是其他結構體
結構體成員的訪問
在這裡,我們宣告乙個結構體
struct s

;

結構體變數通過點操作符(.)訪問
struct s s;  //定義結構體變數

s.a = 20; //訪問結構體成員

s.b = 30;

s.c = 40;

結構體指標通過操作符(->)訪問
struct s *p;  //定義結構體指標

p->a =

20; //訪問結構體成員

p->b =

30;p->c =

40;

結構體的自引用
結構體在引用自身時,需要使用同型別的結構體指標
struct s

;

在這裡,對結構體重命名時需要注意,建立同型別的結構體指標時不可以使用重新命名之後的名字

typedef

struct

node;

typedef

struct node

node;

結構體變數的定義
struct s

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

struct s p2; //定義結構體變數p2

結構體變數的初始化
struct s p3 = ; //定義變數的同時初始化
第乙個成員在與結構體變數偏移量為0的位址處

其他成員要對齊到對齊數的整數倍的位址處(對齊數 = 編譯器預設對齊數(vs為8,linux為4)與該成員大小的較小值)

結構體的總大小為所有成員中的最大對齊數的整數倍

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

平台原因(移值原因)

不是所有的硬體平台都能訪問任意位址上的任意資料;某些硬體平台只能在某些位址處取某些特定型別的資料,否則會出現硬體異常

效能原因

資料結構(尤其是棧)應該盡可能地在自然邊界上對齊

原因在於為了訪問未對齊的記憶體,處理器需要做兩次記憶體訪問,而對齊的記憶體訪問僅需一次訪問

總體來說,結構體的記憶體對齊是拿空間換時間的做法在設計結構體時,我們需要讓占用空間小的成員盡量集中在一起
struct s1

;struct s2

;printf("%d\n", sizeof(struct s1)); //12

printf("%d\n", sizeof(struct s2)); //8

//s1和s2的成員一樣,但所占用的空間大小卻不同

struct s

;struct s s = ;

//結構體傳參

print1(s);

void print1(struct s s)

print2(&s);

void print2(struct s *ps)

從函式棧幀中我們可以了解到,函式傳參時引數需要壓棧,如果在傳遞乙個過大的結構體時,引數壓棧時系統的開銷比較大,所以會導致效能的下降
位段的宣告

位段的宣告與結構體相似,但有兩個不同:

位段的成員必須是int,unsignef int,signed int 或char(整型家族)型別

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

struct s1

;struct s2

;

位段的記憶體分配
位段的空間上是按照4個位元組(int)或者1個位元組(char)的方式開闢的
printf("%d\n", sizeof(struct s1));  //8

printf("%d\n", sizeof(struct s2)); //3

位段的跨平台問題
位段是不跨平台的

int位段被當成unsigned還是signed是不確定的

位段中的最大位的數目不能確定

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

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

enum

day;

enum

color

;

enum day,enum color是列舉型別

{}中的內容是列舉型別可能的取值,也叫列舉常量,這些可能取值都是有值的,預設從0開始,一次增加1,當然,在定義時也可以賦初值

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

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

防止命名汙染(封裝)//命名衝突

便於除錯

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

enum color

;enum color clr = green; //只能拿列舉常量給列舉變數賦初值,才不會出現型別差異

聯合是一種特殊的自定義型別,這種型別定義的變數包含一系列成員,這些成員共用同一塊空間
union un

;union un un; //聯合變數的定義

聯合的成員是共用同一塊空間的,這樣乙個聯合變數的大小至少也是最大成員的大小(聯合至少有能力儲存最大的那個成員)
union un1

;union un2

;printf("%d\n", sizeof(union un1)); //8

printf("%d\n", sizeof(union un2)); //12

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

union ip_addr

ip;};

union ip_addr my_ip;

my_ip.addr = 123456789;

//printf("%d\n", sizeof(my_ip)); //4

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

自定義型別

typedef型別 typedef 已有型別 新建型別 示例 typedef double area,volume typedef int number number i1 area a enum enum 列舉型別名 enum week 預設sun 0,可以比較 如果修改必須形如enum week...

自定義型別

下面列舉幾種c語言中常用的自定義資料型別 1.結構體型別 當描述乙個整型變數時,可以用int,描述字元型變數時,可以用char,但要描述乙個學生時,因為這個學生包含的資訊很多,比如姓名,性別,年齡等,不能通過單一的型別來描述,所以,這裡引入結構體型別,將某個事物的共有屬性集合在一起,宣告乙個結構體型...

自定義型別

列舉從字面意思理解就是將可能取的值一一枚舉出來,列舉型別沒有成員 可言,裡邊存放的是可能取值。列舉型別的定義 enum day enum color printf d n red printf d n green printf d n blue 執行結果 day和color都是定義的列舉型別,中的內...