轉自:http://c.biancheng.net/cpp/biancheng/view/170.html
有時需要將不同類型的數據組合成一個有機的整體,以供用戶方便地使用。這些組合在一個整體中的數據是互相聯繫的。例如,一個學生的學號、姓名、性別、年齡、成績、家庭地址等項,都是這個學生的屬性,見圖7.1。
圖 7.1
可以看到學號(num)、姓名(name)、性別(sex)、年齡(age)、成績(score )、地址(addr)是與姓名爲“Li Fun”的學生有關的。如果在程序中將num,name,sex,age,score,addr分別定義爲互相獨立的變量,就難以反映出它們之間的內在聯繫。應當把它們組織成一個組合項,在一個組合項中包含若干個類型不同(當然也可以相同)的數據項。C和C++允許用戶自己指定這樣一種數據類型,它稱爲結構體。它相當於其他高級語言中的記錄(record)。
例如,可以通過下面的聲明來建立如圖7.1所示的數據類型。
- struct Student//聲明一個結構體類型Student
- {
- int num; //包括一個整型變量num
- char name[20]; //包括一個字符數組name,可以容納20個字符
- char sex; //包括一個字符變量sex
- int age; //包括一個整型變量age
- float score; //包括一個單精度型變量
- char addr[30]; //包括一個字符數組addr,可以容納30個字符
- }; //最後有一個分號
聲明一個結構體類型的一般形式爲:
struct 結構體類型名 {成員表列};
結構體類型名用來作結構體類型的標誌。上面的聲明中Student就是結構體類型名。大括號內是該結構體中的全部成員(member),由它們組成一個特定的結構體。上例中的num,name,sex,score等都是結構體中的成員。在聲明一個結構體類型時必須對各成員都進行類型聲明即類型名 成員名;每一個成員也稱爲結構體中的一個域(field)。成員表列又稱爲域表。
聲明結構體類型的位置一般在文件的開頭,在所有函數(包括main函數)之前,以便本文件中所有的函數都能利用它來定義變量。當然也可以在函數中聲明結構體類型。
在C語言中,結構體的成員只能是數據(如上面例子中所表示的那樣)。C++對此加以擴充,結構體的成員既可以包括數據(即數據成員),又可以包括函數(即函數成員),以適應面向對象的程序設計。
但是由於C++提供了類(class )類型,一般情況下,不必使用帶函數的結構體,因此在本章中只介紹只含數據成員的結構體,有關包含函數成員的結構體將在後續章節進行介紹。
結構體類型變量的定義方法及其初始化
以上只是指定了一種結構體類型,它相當於一個模型,但其中並無具體數據,系統也不爲之分配實際的內存單元爲了能在程序中使用結構體類型的數據,應當定義結構體類型的變量,並在其中存放具體的數據。定義結構體類型變量的方法可以採取以下3種方法定義結構體類型的變量。
1) 先聲明結構體類型再定義變量名
如上面已定義了一個結構體類型Student,可以用它來定義結構體變量。如:
在C語言中,在定義結構體變量時,要在結構體類型名前面加上關鍵字Sttuct,C++ 保留了C的用法,如:
struct Student studentl, student2;
提倡讀者在編寫C++程序時,使用C++新提出來的方法,即不必在定義結構體變量時加關鍵字Struct,這樣使用更方便,而且與第8章中介紹的用類(class)名定義類對象的用法一致。
以上定義了student1和student2爲結構體類型Student的變量,即它們具有Student類型的結構。如圖7.2所示。
圖7.2
在定義了結構體變量後,系統會爲之分配內存單元。例如student1和student2在內存中各佔63個字節(4+20+1+4+4+30=63)。
2) 在聲明類型的同時定義變量。例如:
- struct Student //聲明結構體類型Student
- {
- int num;
- char name[20];
- char sex;
- int age;
- float score;
- char addr[30];
- }student1, student2; //定義兩個結構體類型Student的變量student1,student2
這種形式的定義的一般形式爲:
struct 結構體名
{
成員表列
}變量名錶列;
3) 直接定義結構體類型變量。其一般形式爲:
struct //注意沒有結構體類型名
{
成員表列
}變量名錶列;
這種方法雖然合法,但很少使用。提倡先定義類型後定義變量的第(1)種方法。在程序比較簡單,結構體類型只在本文件中使用的情況下,也可以用第(2)種方法。
關於結構體類型,有幾點要說明:
1) 不要誤認爲凡是結構體類型都有相同的結構。實際上,每一種結構體類型都有自己的結構,可以定義出許多種具體的結構體類型。
2) 類型與變量是不同的概念,不要混淆。只能對結構體變量中的成員賦值,而不能對結構體類型賦值。在編譯時,是不會爲類型分配空間的,只爲變量分配空間。
3) 對結構體中的成員(即“域”),可以單獨使用,它的作用與地位相當於普通變量。
4) 成員也可以是一個結構體變量。如:
- struct Date //聲明一個結構體類型Date
- {
- int month;
- int day;
- int year;
- };
- struct Student //聲明一個結構體類型Student
- {
- int num;
- char name[20];
- char sex;
- int age;
- Date birthday;
- char addr[30];
- }student1, student2; //定義student1和student2爲結構體類型Student的變量
圖 7.3
5) 結構體中的成員名可以與程序中的變量名相同,但二者沒有關係。例如,程序中可以另定義一個整型變量num,它與student中的num是兩回事,互不影響。
結構體變量的初始化
和其他類型變量一樣,對結構體變量可以在定義時指定初始值。如:
- struct Student
- {
- int num;
- char name[20];
- char sex;
- int age;
- float score;
- char addr[30];
- }student1={10001, "Zhang Xin", 'M', 19, 90.5, "Shanghai"};
也可以採取聲明類型與定義變量分開的形式,在定義變量時進行初始化:
Student student2 = { 10002, "Wang Li", "F", 20, 98, "Beijing"}; //Student是已聲明的結構體類型