在學習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為...