1.結構體
(1)為什么需要結構體?
沒有結構體之前,在C語言中,數據的組織依靠:變量+數組
最初簡單的時候,只需要使用基本數據類型(char、short、int、float、double)來定義單個變量,需要幾個變量就定義幾個。后來情況復雜了,有時需要很多意義相關的變量(如需要存儲及運算一個班級的學生分數),這時候數組出現了。數組解決了需要很多類型相同、意義相關的變量的問題。但是數組是有限制的。數組最大的不足在于,一個數組只能存儲很多數據類型相同的變量。
題目:使用一個數據結構來保存一個學生的所有信息(姓名、學號、性別)
所以碰到需要封裝幾個類型不同的變量的時候,數組就無能為力。
(2)什么是結構體?
#include <stdio.h>
struct Student
{
char name[20]; //學生姓名
unsigned int num; //學號
int isMale; //性別
}
注意:
①結構體類型的定義是在函數外面,而不是里面
②結構體定義的是一個新的組合類型。而不是變量,也不消耗內存(因為還未分配空間)。稍后再定義變量的地方,再使用該結構體類型來定義變量。
int main(void)
{
struct Student s1; //s1是一個變量,類型是struct Student
//給結構體變量賦值
s1.name[0] = 'J';
s1.name[1] = 'i';
s1.name[2] = 'm';
s1.name[3] = '\0';
s1.num = 123;
s1.isMale = 1;
printf("s1.name = %s.\n s1.num = %d.\n s1.isMale = %d.\n", s1.name,s1.num,s1.isMale);
return 0;
}
結構體是一個集合,集合中包含很多元素,這些元素的數據類型可與相同,也可以不相同,所以結構體是一種數據封裝的方法。(大箱子裝零散的東西)結構體存在的意義就在于,把很多數據類型不相同的變量封裝在一起,組成一個大的新的數據類型。這種封裝就好比戶口封裝家庭,公司封裝部門。
數據結構:把龐大復雜的數據用一定的方式組織管理起來,便于操作(查找、增加、刪除等)這就叫數據結構。
(3)結構體和數組的關聯(lián)
數組是一種特殊的結構體,特殊之處在于各封裝內的各個元素類型是相同的。結構體和數組都是對一些子元素的封裝,因此定義的時候都輸封裝作為整體定義,但是使用的時候,都是使用封裝中的子元素,一般結構體變量和數組變量都不會作為一個整體操作。
打印規(guī)則
| 數據類型 | 格式化符號 |
|---|---|
| float/double | %f |
| char | %c或%d |
| int | %d |
| 指針 | %p |
(4)使用結構體的步驟
第一步:定義結構體類型,結構體類型的定義是在函數外面(函數外面==全局的)
第二步:使用第一步定義的類型來定義結構體變量。
第三步:使用變量。實際上使用結構體變量的時候,使用的是結構體變量中封裝的各個子元素,而不是結構體變量本身。
(5)結構體的初始化
結構體變量和普通變量一樣,作為局部變量時,如果定義的時候無初始化也無顯式賦值,則結構體變量中的子元素的值是隨機的。
初始化的三種方式
①struct Mystruct s = {100, 'd', 12.445, 111.111}; //完全OK
②struct Mystruct s =
{
//部分OK,中間缺少某一個后面賦值全不對
s.a = 1444,
s.b = 'k',
s.c = 3.13,
s.d = 123,
};
③struct Mystruct s =
{
//完全OK,中間缺少某一個也OK
.a = 1444,
.b = 'k',
.c = 3.13,
.d = 123,
};
選擇①③兩種方式,不選②
2.共用體(union)
union Student
{
struct Male m;
struct Female f;
}
一般和結構體結合,選擇結構體其中一種使用。
3.宏定義
#define N 321 //宏定義的格式
宏定義要注意的問題:
(1)宏定義一般是在函數的外面
(2)宏定義必須要先定義,再使用宏。如果先使用就會編譯報錯。
(3)宏定義中宏名一般用大寫。不是語法規(guī)定的,是一般約定俗稱的。
(4)為什么使用宏定義?
在C語言中,一般使用常數的時候,都不是直接使用的,而是先把該常數定義為一個宏,然后在程序中使用該宏名。這樣做的好處是,等我們需要修改該常數時,只需要在宏定義處修改依次即可。而不用到代碼中到處尋找,看哪里用過該常數。