250 likes | 484 Views
第 8 章 结构、联合和枚举. 8.1 类型定义 概念 : 由用户自己定义数据类型 方法 : 非结构型定义 ( 类型的引用 ) 和结构类型定义 8.2 非结构型定义 例 : 将 integer 也定义成 int typedef int integer 在程序中 : int a,b,c; 和 integer a,b,c; 作用相同 例 : 将 ul 定义为 unsigned long typedef unsigned long ul ( 以少代多 ). 8.3 结构 ( 结构类型定义 )
E N D
第8章 结构、联合和枚举 8.1 类型定义 概念: 由用户自己定义数据类型 方法: 非结构型定义(类型的引用)和结构类型定义 8.2非结构型定义 例: 将integer 也定义成 int typedef int integer 在程序中: int a,b,c; 和 integer a,b,c; 作用相同 例:将 ul 定义为 unsigned long typedef unsigned long ul (以少代多)
8.3 结构 (结构类型定义) 把不同的数据类型或多个数据定义成一个结构, 该结构(类型)称为结构体. 8.3.1 定义结构 例如,定义一个”学生“属性的结构体。 struct student { int num; char name[10]; int age; char sex; float score; char addr[30]; }m,n;
说明: 其中student 是由用户定义的结构体类型名(在数据类型中有增加了一个类型)。 其中的成员称作域名。 8.3.2 说明结构变量 (结构类型变量定义方法) 例:将a,b,c 说明成student 结构体类型 方法一:用结构体类型进行说明 struct student a,b,c
方法二:先用宏定义 #define student struct student student a,b,c; 方法三:定义结构体时就说明 例:将 m, n 说明成 teacher 结构体类型 struct teacher { char name[10]; int age; char sex; char addr[30]; } m,n;
说明: 1. 结构体中的成员称为域名或分量。 2. 结构体和宏定义常常以头文件方式使用。 3. 每一个成员需要进行类型说明。 4. 结构体中的成员名可以与普通变量名相同,但使用的方式不同。 5. 结构体中的成员还可以是另一个结构体变量。 6. 可以使用sizeof() 函数测出每一个变量、类型(float等)等占用内存的字节数。
8.3.3 结构体成员 结构体中的成员还可以是另一个结构体变量 struct pat { unsigned long zip; //邮编 char *addr; //地址 unsigned long tel; }; struct address_book { char *name; long num; pat depart; //单位 pat home; //家庭 }a;
8.3.4 访问结构体变量 例: address_book a, s [10] a.num a.name a.depart.num s[3].num s[3].home.tel 8.3.5 结构体变量的初始化(赋值) 例: 给变量赋值 struct student { long int num; char name[10]; int age; char sex; }a={200705312, “zhang li”, 18, ‘w’};
例: 给结构类型的数组变量赋值 struct student { long int num; char name[10]; int age; char sex; } s[30]={{200205312,“zhangli”, },{2002}};
8.4 结构体类型的变量输出 例:使用scanf() 给结构体数组类型赋值, 输入三个学生的有关信息,然后输出 程序为: struct student { long int num; char name[10]; char sex; } s[3];
main() {int k; for(k=0; k<3;k++) { cin>>s[k].num; cin>>s[k].name; cin>>s[k].sex; } for(k=0; k<3;k++) { cout<<s[k].num<<”\n”; cout<<s[k].name”\n”; cout<<s[k].sex<<endl; } }
例:结构体嵌套的输入输出 struct date { int year; int month; int day }; struct student { long int num; char name[10]; struct date birthday; } s[3];
main() {int k; for(k=0; k<3;k++) { cin>>s[k].num; cin>>s[k].name; cin>>s[k].birthday.year; cin>>s[k].birthday.month; cin>>s[k]..birthday.day; }
for(k=0; k<3;k++) { cout<<s[k].num; cout<<s[k].name; cout<<s[k].birthday.year; cout<<s[k].birthday.month; cout<<s[k].birthday.day; } }
8.5 用结构指针变量代替结构体变量 struct student { long int num; char name[10]; char sex; } ; struct student a; 定义结构体变量 struct student *p; 定义结构体变量指针 p=&a; p->num 引用a中的成员(方法一) (*p).num引用a中的成员(方法二)
8.6 用结构指针变量代替结构体数组变量 struct student { long int num; char name[10]; char sex; } ; struct student s[30]; struct student *p; p=s; p->num 引用某一元素中的num成员 (*p).num (p++)->num 引用某一元素中的num成员后指针指向下一个(人)数组元素.
例: 用结构体类型指针变量完成上题 struct date { int year; int month; int day } struct student { int num; char name[10]; struct date birthday; }s[30];
main() {int k; struct student *p; p=s; for(k=0; k<3;k++,p++) { cin>>p->num; cin>>p->name; cin>>p->birthday.year; cin>>p->birthday.month; cin>>p->birthday.day; }
for(k=0; k<3;k++,p++) { cout<<p->num; cout<<p->name; cout<<p->birthday.year; cout<<p->birthday.month; cout<<p->birthday.day; } }
8.7 位域 位域是以二进制形式定义结构成员, 使用多少定义多少。 8.7.1 定义位域的方法 例: struct student { char *name; unsigned int sex : 1; unsigned int age : 7; };
说明: • 在成员后使用 : n 即可, n 指的是二进制位数。 • 使用位域和不使用位域差2个字节。 • 1位可表示1 或 0, 8 位可以表示 0到 128。 • 8.7.2 使用位域成员的方法 • 与普通成员一样,注意1 和 0 即可表示逻辑值。 • 8.7.3 使用位域注意事项 • 位域成员必须是unsigned int 。 • 位域成员所占位数可任意。 • 如果从新的字节开始,可以使用: • unsigned int 0;
8.8 联合(共用体) 8.8.1 联合的概念与定义 不同的数据可以共用存储单元 例: union un { int n; char name; float x; } 其特点是所有成员具有相同的首地址
8.8.2 联合体变量的定义 联合体类型名 变量名 8.8.3 联合体的使用 通过变量使用 例: un a,b; a.n=2003; a.name=”hello” b.x=3.1415962
8.8.4 联合体类型的特点 • 共享内存单元 • 每一时刻只能有一个成员起作用 • 最后一次赋值的成员有效 • 各成员的首地址相同 • 联合体变量不能参加任何运算和初始化
8.9 枚举 8.9.1枚举类型的定义 例: enum weekday{sun=5,mon=1,tue,wen,thu,fri,sat}; 说明: 可以直接改变成员的顺序。 8.9.2 枚举类型变量的说明 方法1: 直接枚举类型说明 weekday days; 方法2: 可以在定义枚举类型时说明
8.9.3 枚举变量的使用 只能做赋值和关系运算。 days=sun; 说明: 1. 在程序中起到一个限定作用。 2. 使用时, 枚举变量的取值限定在定义时的给定范围.。 3. 枚举变量输出时,只能输出枚举定义时的序号. 例如: days=sat; c<<days<<endl;