● 構造數據類型概念
Structured data types 構造數據類型
結構體(structure), 聯合體/共用體 (union), 枚舉類型(enumeration type), 要有意識這三者是數據類型
Union is also like structure, i.e. collection of different data types which are grouped together. Each element in a structure or a union is called member. • Structure allocates storage space for all its members separately. • Whereas, Union allocates one common storage space for all its members |
● 結構體使用場景
無論是基本數據類型還是數組都僅僅描述了事物某一方面的特性, 但是, 一種事物往往具有多方面的屬性, 如一個同學有學號, 姓名, 性別, 年齡等屬性. |
||
定義形式: struct union_type_name { member_type member_name_1; member_type member_name_2; ... member_type member_name_n; };
結構體變量的定義 & 結構體成員的初始化, 例如:
|
||
● 結構體成員初始化的兩種方法
//結構體變量名.成員名 #include <iostream> using namespace std;
void main() { struct person_info { int index; char name[30]; short age; }; person_info p_info; //也可以寫成struct person_info p_info; p_info.index=1; strcpy(p_info.name,"Jim"); //位字符數組賦值需要使用字符串復制函數strcpy(), 否則會提示: cannot convert from 'char [4]' to 'char [30]' p_info.age=20;
cout << p_info.index<< endl; cout << p_info.name << endl; cout << p_info.age << endl;
cout<<sizeof(person_info)<<endl; cout<<sizeof(p_info)<<endl; //結構體類型和結構體變量的大小都是36字節, 即4+30+2=36 }
/* 可以在聲明一個結構體變量后賦值: struct person_info { int index; char name[30]; short age; }; person_info p_info={1,"Jim", 20}; */ /* 也可以在定義結構體變量時直接對成員賦值: struct person_info { int index; char name[30]; short age; } p_info={1,"Jim", 20};*/ |
//結構體指針變量->成員名 //在定義結構體的同時, 聲明結構體指針變量 #include <iostream> using namespace std;
void main() { struct person_struct { int index; char name[30]; short age; }*p, p_info={1,"Jim",20}; p=&p_info; cout <<p->index << endl; cout <<p->name << endl; cout << p->age << endl; cout <<(*p).index << endl; cout <<(*p).name << endl; cout <<(*p).age << endl;
cout << sizeof(p) << endl; cout << sizeof(p_info) << endl; }
//也可以寫成: struct person_info { int index; char name[30]; short age; }; person_info p_info={1,"Jim",20}; struct person_info *p=&p_info; //一定要寫定義的結構體類型名, 不能寫成struct *p=&p_info; |
|
|
總之, 在上述案例中, 訪問結構體成員有下面三種方法: ① p_info.index; ② p->index; ③ (*p).index; ② 當一個結構體類型定義完成后, 如果要使用這個類型, 保留字struct在C語言中必須使用,而在C++中則可被省略不寫。 |
● 結構體的嵌套, 子結構體(sub-structure)
#include <iostream> using namespace std;
void main() { struct person_info { int index; char name[30]; short age; struct work_place { char address[150]; char postCode[30]; char gateCode[50]; char street[100]; char area[50]; }WP; //子結構體(sub-structure) };
person_info p_info; //p_info是person_info結構體類型變量 strcpy(p_info.WP.address,"House"); //可以把WP看作是p_info變量的子變量(sub-variable) strcpy(p_info.WP.postCode,"10000"); strcpy(p_info.WP.gateCode,"302"); strcpy(p_info.WP.street,"Lan Tian"); strcpy(p_info.WP.area,"China");
cout << p_info.WP.address << endl; cout << p_info.WP.postCode << endl; cout << p_info.WP.gateCode<< endl; cout << p_info.WP.street << endl; cout << p_info.WP.area << endl; } |
|
● 結構體變量作函數參數
#include <iostream> using namespace std;
struct person_info //定義結構體 { int index; char name[30]; short age; }; void show_stuct_message(struct person_info my_info) //自定義函數,形參是結構體變量my_info, 輸出結構體變量成員, 不返回值 { cout << my_info.index << endl; cout << my_info.name << endl; cout << my_info.age<< endl;
} void main() {
person_info p_info; //聲明結構體變量p_info, 作為形參 p_info.index=1; strcpy(p_info.name,"Jim"); p_info.age=20; show_stuct_message(p_info); //調用自定義函數 } |
|
● 結構體指針做函數參數
#include <iostream> using namespace std; struct person_info { int index; char name[30]; short age; }; void show_struct_message(struct person_info *my_info) { cout << my_info->index << endl; cout << my_info->name << endl; cout << my_info->age<< endl;
} void main() {
person_info p_info; p_info.index=1; strcpy(p_info.name,"Jim"); p_info.age=20; show_struct_message(&p_info); } |
|
● 結構體數組的聲明與引用 & 指針訪問結構體數組
結構體數組: 每個元素都是結構體變量的數組 //定義結構體數組的一般形式: struct 結構體名 { 成員列表; }數組名;
struct Student //可以把Student這個結構體名省略 { char name[20]; int number; char sex; int grade; }student[5];
//結構體數組中各數據在內存中的存儲是連續的,例如: |
#include <iostream> using namespace std;
void main() { struct person_info { int index; char name[30]; short age; }p_info[5]={{1,"Jim",20}, //p_ifno是一個結構體數組 {2,"Eric",21}, {3,"Peter",22}, {4,"Amy",22}, {5,"Lucy",22}};
struct person_info *p; p=p_info; //p_info是一個結構體數組名, 因此就代表一個地址值 for(int i=0;i<5;i++,p++) { cout << p->index << endl; cout << p->name << endl; cout << p->age << endl; } } |
|
● 共用體變量的大小
所有共用體在同一時刻只能有一個值, 它屬於某一數據成員, 不過其它成員會共享這個值, 只是會轉換成這些成員的數據類型 共用體變量的大小是其最大成員的大小. 聯合體使用場景: 例如通信中的數據包會用到共用體, 因為不知道對方會發一個什么數據類型的包過來,用共用體的話就很簡單了,定義幾種格式的包,收到包之后就可以直接根據包的數據類型取出數據。 |
||
定義形式: union union_type_name { member_type member_name_1; member_type member_name_2; ... member_type member_name_n; };
聯合體變量的定義, 例如:
|
||
#include<stdio.h>
union data_union /*聲明共用體類型*/ { int a; /*成員變量*/ char b; };
int main() { union data_union my_union; /*定義共用體變量*/ my_union.a=97; /*為共用體變量中成員賦值*/ printf("a: %d\n",my_union.a); /*輸出成員變量數據*/ printf("b: %c\n",my_union.b); my_union.b='A'; /*改變成員的數據*/ printf("a: %d\n",my_union.a); /*輸出成員變量數據*/ printf("b: %c\n",my_union.b); printf("sizeof(data_union): %d\n",sizeof(data_union)); printf("sizeof(my_union): %d\n",sizeof(my_union)); return 0; } |
||
|
● 枚舉類型(enumeration type)
使用場景: 很多集合描述的狀態為有限幾個, 例如比賽結果只有輸, 贏和平手三種狀態; 一周只有七天等等. |
● 枚舉類型是一些標識符的集合, 這些標識符代表整型常量. 聲明形式: ① 標識符沒有被賦值 enum 枚舉類型名 {枚舉常量1, 枚舉常量2,…, 枚舉常量n}; enum enumeration_type_name { enumeration_constant_1, enumeration_constant_2, ..., enumeration_constant_n} 例如: enum weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; 如果標識符沒有被賦值, 標識符會被自動賦值為從0開始的整型常量 ② 標識符被賦值 enum enumeration_type_name //方括號(中括號)內的內容可以寫或不寫 { identifier[=integral constant], identifier[=integral constant], ... identifier[=integral constant], }; 上面的枚舉類型聲明相當於: enum Weekday {Sunday=0, Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6}; 也可以自己賦值, 如: enum Weekday {Sunday=2, Monday=3, Tuesday=4, Wednesday=5, Thursday=0, Friday=1, Saturday=6}; 如果只給前幾個標識符賦值, 編譯器會給后面的標識符自動累加賦值, 例如: enum Weekday {Sunday=7, Monday=1, Tuesday, Wednesday, Thursday, Friday, Saturday}; 相當於: enum Weekday {Sunday=7, Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6};
● 枚舉類型變量(enumeration variable/enum variable) enum Weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; Weekday myworkday; 也可以去掉上面花括號后面的分號, 然后直接寫變量的標識符: enum Weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday} myworkday;
注意:① 在C語言中, 還需要寫關鍵字, 即: enum weekday myworkday; ② 枚舉變量的值只能在Sunday和Saturday之間, 即一個整型數據不能直接賦給一個枚舉變量, 不過可以先將一個整型常量強轉為Weekday枚舉類, 然后再賦值. |
● 枚舉類型的聲明, 枚舉類型變量的聲明及其運算
#include <iostream> using namespace std;
void main() { enum Weekday {Sunday,Monday,Tuesday,Wednesday,Thresday,Friday,Saturday}; int a=2,b=1; Weekday day;
day=Tuesday; cout<<day<<endl;
day=(Weekday)a; //將整型的a強轉為Weekday類型 cout << day << endl;
day=(Weekday)(Sunday+Wednesday); //Sunday+Wednesday后得到一個整型常量, 因此也需要強轉 cout << day << endl;
day=(Weekday)5; //等價於day=(enum Weekday)5; 輸出Weekday的第5個標識符代表的整型常量(從0開始計數) cout << day << endl;
Weekday another_day; another_day=Tuesday; cout<<day-another_day<<endl;
cout<<sizeof(Weekday)<<endl; cout<<sizeof(another_day)<<endl; //enum類型的長度以及每個enum類型變量的長度都是一個枚舉常量的長度, 即sizeof(int)=4; } |
|