①.結構體型別的宣告
struct tag
variable-list;
//例如描述乙個學生
struct stu
;//分號不能丟
//特殊宣告
//匿名結構體型別
struct
x;struct
a[20],
*p;
②.結構的自引用
//**1
struct node
;
該結構體定義是錯誤的,因為結構體的大小是根據其中的成員變數的大小以及"記憶體對齊"決定的,所以不知道struct node的大小,如果在其中再這樣定義struct node next;自引用後系統也不知道該開闢多大的記憶體空間,所以這樣的定義是錯誤的。
正確的定義:
//**2
struct node
;
//這樣的定義也是錯誤的
//**3
typedef
struct n
node;
③.結構體變數的定義和初始化
struct point
p1;//宣告型別的同時定義變數p1,不建議這樣做,建議在使用時候再定義變數
struct point p2;
//定義結構體變數p2
//初始化:定義變數的同時賦初值。
struct point p3 =
;struct stu //型別宣告
;struct stu s =
;//初始化
struct node
n1 =
,null};
//結構體巢狀初始化
④.結構體內存對齊
//什麼是記憶體對齊
計算結構體的大小時候需要考慮記憶體對齊問題
記憶體對齊是為了提高訪問效率(犧牲記憶體,提高訪問效率)
處理器每次訪問棧時從中讀取的位元組數是一定的。
如果沒有記憶體對齊原因在於,為了訪問未對齊的記憶體,處理器
需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問
//如何記憶體對齊
1. 第乙個成員在與結構體變數偏移量為0的位址處。
2. 其他成員變數(除了第乙個變數外的變數)要對齊到某個數字(對齊數)
的整數倍的位址處。
對齊數 = 編譯器預設的乙個對齊數 與 該成員大小的較小值
vs2013的預設對齊數為8
3. 結構體總大小為最大對齊數(每個成員變數都有乙個對齊數)的整數倍。
4. 如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的
整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊
數)的整數倍。
例題:
//練習1
struct s1
;printf
("%d\n"
,sizeof
(struct s1));
//12
//練習2
struct s2
;printf
("%d\n"
,sizeof
(struct s2));
//8//練習3
struct s3
;printf
("%d\n"
,sizeof
(struct s3));
//16
//練習4-結構體巢狀問題
struct s4
;printf
("%d\n"
,sizeof
(struct s4));
//32
⑤.結構體傳參
struct s
;struct s s =
,1000};
//結構體傳參方法一
void
print1
(struct s s)
//結構體位址傳參方法二
void
print2
(struct s* ps)
intmain()
結構體傳參時是乙個值拷貝的過程
如果傳遞乙個結構體物件的時候,結構體過大,系統開銷比較大,所以會導致效能的下降。更有可能導致程式崩潰
⑥.結構體實現位段(位段的填充&可移植性)
什麼是位段?
位段的宣告和結構是類似的,有兩個不同:
1.位段的成員必須是 int、unsigned
int 或signed
intchar。
(整形)中的一種
2.位段的成員名後邊有乙個冒號和乙個數字,表示所使用的的位元位
例如:
struct a
;printf
("%d\n"
,sizeof
(struct a));
//8
位段的記憶體分配
1. 位段的成員可以是 int
unsigned
intsigned
int 或者是
char (屬於整形家族)型別
2. 位段的空間上是按照需要以4個位元組( int )或者1個位元組
( char )的方式來開闢的。
3. 位段涉及很多不確定因素,位段是不跨平台的,注重可移植的
程式應該避免使用位段。
列舉顧名思義就是一一枚舉。
把可能的取值一一枚舉。
比如我們現實生活中:
一周的星期一到星期日是有限的7天,可以一一枚舉。
性別有:男、女、保密,也可以一一枚舉。
月份有12個月,也可以一一枚舉
顏色也可以一一枚舉。
這裡就可以使用列舉了。
①.列舉型別的定義
enum day//星期
;enum ***//性別
;
以上定義的 enum day , enum *** 都是列舉型別。 中的內容
是列舉型別的可能取值,也叫 列舉常量 。
這些可能取值都是有值的,預設從0開始,一次遞增1,當然
在定義的時候也可以賦初值。
②.列舉的優點
我們可以使用 #define 定義常量,為什麼非要使用列舉? 列舉的優點:
1. 增加**的可讀性和可維護性
2. 和#define定義的識別符號比較列舉有型別檢查,更加嚴謹。
3. 防止了命名汙染(封裝)
4. 便於除錯
5. 使用方便,一次可以定義多個常量
③.列舉的使用
enum color//顏色
;enum color clr = green;
//只能拿列舉常量給列舉變數賦值,才不會出現型別的差異。
clr =5;
//ok
聯合也是一種特殊的自定義型別 這種型別定義的變數也包含一系列的成員
,特徵是這些成員公用同一塊空間(所以聯合也叫共用體)。
①.聯合型別的定義
//聯合型別的宣告
union un
;
②.聯合的特點
聯合的成員是共用同一塊記憶體空間的,這樣乙個聯合變數的大小,至少是
最大成員的大小(因為聯合至少得有能力儲存最大的那個成員)。
union un
;union un un;
//下面輸出的結果是什麼?
un.i =
0x11223344
;un.c =
0x55
;printf
("%x\n"
, un.i)
;//11223355
可以用來判斷記憶體的大小端儲存如果結果為11223355則為小端儲存
結果為55223344則為大端儲存
③.聯合大小的計算
聯合的大小至少是最大成員的大小。
當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的
整數倍。
C語言中的自定義型別 結構體 列舉 聯合
我們知道c語言基本資料型別有 本篇將重點介紹c語言中的自定義型別 結構體 列舉 聯合 struct stu int main 含義 define crt secure no warnings 1 include include struct x struct p int main 上面的 執行後發現...
C語言中的自定義型別(結構體 列舉及聯合)
結構體的記憶體對齊 位段列舉 聯合結構體是一些值的集合,這些值被稱為成員變數,結構的每個成員可以是不同型別的變數。struct piont p1 宣告結構體型別,同時定義變數p1 struct point p2 定義結構體變數p2 struct point p3 初始化 定義變數同時賦值 struc...
C語言 自定義型別 結構體 列舉 聯合
二 列舉 三 聯合 1.結構體型別建立 struct stu 定義乙個學生結構體 分號不能丟 特殊的宣告 在宣告結構的時候,可以不完全的宣告 比如 匿名結構體型別 struct x struct a 20 p p x 非法,編譯器會把上面的兩個宣告當成完全不同的兩個型別 結構的不完整宣告 struc...