390 likes | 636 Views
c++ 程序设计. 补充章节: 结构体、共用体、枚举. 结构体 [*] 共同体 [* 关键掌握与结构体的区别 ] 枚举类型 自定义数据类型. 简单回顾. 以往讨论的数据类型都是 C++ 语言提供的,相对简单的数据类型。 这一章将讨论让用户定义自己的数据类型 结构体、共用体和枚举类型 —— 由基本类型组成 结构体是这一章的重点: 结构体变量、结构体数组和指针 返回结构体类型数据的函数 共用体和枚举类型、变量的定义和引用; 掌握用户自定义类型的定义和使用。. 1 结构体. 数组将若干具有共同类型特征的数据组合在了一起。
E N D
补充章节: 结构体、共用体、枚举 结构体 [*] 共同体 [*关键掌握与结构体的区别] 枚举类型 自定义数据类型
简单回顾 以往讨论的数据类型都是C++语言提供的,相对简单的数据类型。 这一章将讨论让用户定义自己的数据类型 结构体、共用体和枚举类型 —— 由基本类型组成 结构体是这一章的重点: 结构体变量、结构体数组和指针 返回结构体类型数据的函数 共用体和枚举类型、变量的定义和引用; 掌握用户自定义类型的定义和使用。
1 结构体 数组将若干具有共同类型特征的数据组合在了一起。 然而实际中的数据类型要复杂的多,例如: 描述一个学生,需要学号、姓名、性别、年龄、籍贯、民族等等信息。 单独的一个学号,姓名都很好描述: char *examno=“NO001”; char *name=“zhang3”; char sex=‘F’;int age=20; ….. 要描述这样一个学生类,怎么办?
1.1结构体类型的定义 声明一个结构体类型的一般形式为: struct 结构体类型名 { 成员项表列}; 成员项表列的格式 数据类型 成员名; struct 结构类型名 { 数据类型 数据项1;数据类型 数据项2; …… ……数据类型 数据项n; }; struct student { long sno; char sname[20]; int age; char sex; char nation[10]; } ; student 就是用户自定义的类型 各成员项的定义
定义一个结构体变量 1:用已经定义的结构体类型名定义变量: struct student stu1,stu2; 2: 定义类型的同时定义变量 struct student { long sno; char sname[20]; int age; char sex; char nation[10]; } stu1, stu2; sizeof(struct student) 或 sizeof(stu1) = 37 sno sname age sex nation 4B 20B 2B 1B 10B
struct student{ char *sno;//2 char *sname;//2 int age;//4 char sex;//1 char *nation;//2 }; sizeof(struct student)=? struct student{ long sno;//8 char sname[20]; int age;//4 char sex;//1 char nation[10]; }stu2; main(){ struct student stu1; cout<<"size of student type:“<<sizeof(struct student)<<endl; cout<<"size of student type:“<<sizeof(stu1)<<endl; }
描述一个日期:年/月/日 描述一个商品:条形码、 品名、 价格、生产日期 struct date{ int year; int month; int day; }; struct date{int year,month,day;} [同样] struct items{ char code[10]; char *name; float price; struct date made_date; }; struct items{ char code[10]; char *name; float price; struct date{ int year; int month; int day; } made_date; };
1.2结构体类型的初始化和引用 在以上结构体变量的三种定义的同时都可以进行初始化赋值,例如: struct student stu1={“10001“,”Zhang3”,20,’F’,”HanZu”}; 注意初始化数据应与类型中的各个成员在位置上一一对应。对于嵌套的结构体类型变量,初始化是对各个基本类型的成员赋初值,例如: struct items cloth={"BM00001", "T-shirt", 340.00,{2013,4,23} }; struct items cloth={"BM00001", "T-shirt", 340.00,2011,5,4 };
引用结构体成员 结构体变量名·成员名 结构体变量名·结构体变量名.成员名[嵌套结构] struct student { long sno; char sname[20]; int age; char sex; char nation[10]; } stu1, stu2; struct items{ char code[10]; char *name; float price; struct date made_date; } cloth,food; food.made_date.year==2013 &&food.made_date.month==4 &&food.made_date.day==23 stu1.sno=100002; stu1.age+=1; if (stu1.sex==‘F’)
编写程序:输入学生信息,打印学生信息 #include <iostream> #include <cstring> void main(){ struct student stu1; cout<<"Please input student no:"<<endl; cin>>stu1.sno; cout<<"Please input student name:"<<endl; cin>>stu1.sname; cout<<"Please input student age:"<<endl; cin>>stu1.age; cout<<"Please input student sex:"<<endl; cin>>stu1.sex; cout<<"Please input student nation:"<<endl; cin>>stu1.nation; cout<<stu1.sno<<stu1.sname<<stu1.age<< stu1.sex<<stu1.nation<<endl; } struct student { long sno; char sname[20]; int age; char sex; char nation[10]; } stu1;
结构体变量的赋值、输入和输出 结构体变量的输入和输出也都只能对其成员进行 对结构体变量的成员进行赋值 同一类型的结构体变量可相互赋值 同类型的两个结构体变量之间可以整体赋值(请比较数组之间不能整体赋值) stud1=stud2;
【例题】分析下面程序的结果 #include <iostream.h> struct table {char name[20]; double price; }; void main() {struct table t2={"Desk002",140.5}; struct table t1; t1.name[0]='D'; t1.name[1]='1'; t1.name[2]='\0'; t1.price=150.0; cout<<t1.name<<','<<t1.price<<endl; cout<<t2.name<<','<<t2.price<<endl; }
1.3 结构体数组 1:struct student { long sno; char sname[20]; int age; char sex; char nation[10]; } stu[3]; 2:struct student stu[3]; 3:初始化 struct student stu [3]={ {101,"Wang li",18,'M',"HanZu"}, {102,"ZhangF",19,'M',"ManZu"}, {103,"Li Ling",20,'F',"HanZu"} };
sno sname age sex nation sno sname age sex nation sno sname age sex nation stu stu+1 stu+2 引用: stu[i].sno stu[i].sname stu[i].age stu[i].sex stu[i].nation 结构型数组元素可以相互赋值 stu[i]=stu[j]
在一个学生表里按照一定的条件查找学生 按性别查询 struct student stu [10]={ {101,"Wang li",18,'M',{1987,1,2},"HanZu"}, {102,"ZhangF",19,'M',{1987,1,3},"ManZu"}, {103,"Li Ling",20,'F',{1986,2,2},"HanZu"}, {104,"Ling2",20,'F',{1986,2,2},"HanZu"}, {105,"Wing",19,'M',{1986,2,2},"HuiZu"}, {106,"Ting",20,'M',{1988,2,2},"HuiZu"}, {107,"Hling",20,'F',{1983,2,2},"HanZu"}, {108,"Cao Wing",20,'M',{1986,2,2},"HuiZu"}, {109,"GaoTing",16,'M',{1988,2,2},"HuiZu"}, {110,"Hanling",20,'F',{1983,2,2},"HanZu"}, };
void output(struct student stu){ cout<<stu.sno<<stu.sname<<stu.age<<stu.sex\<<stu.birthday.year<<stu.birthday.month<<stu.birthday.day<<stu.nation; } void querybySex(struct student stu[],char sex ){ int i; for(i=0;i<N;i++) if (stu[i].sex==sex) output(stu[i]); } #define N 10 Void main(){char sex; cout<<“Please input Query Sex Condition:"; cin>>sex; cout<<"SNO\tSname\tAge\tSex\tBirthday\tNation\n"); querybySex(stu,sex);}
输入3个学生的信息然后输出。每个学生的信息包括学号、姓名和4门课程的成绩输入3个学生的信息然后输出。每个学生的信息包括学号、姓名和4门课程的成绩 #include <iostream>void main(){struct stu_type {long num; char name[20]; float score[4]; }st[3]; int i, j;float t; cout<<"Enter students' datas:“<<endl;
for(i=0; i<3; i++){ cin>>st[i].num; getchar(); gets(st[i].name); for(j=0; j<4; j++) { cin>>t; st[i].score[j]=t; }}cout<<"No.Name\Score1\Score2\Score3\Score4\n");for(i=0; i<3; i++){cout<<st[i].num<<st[i].name<<endl; for(j=0; j<4; j++) cout<<st[i].score[j]<<end;}}
sno:4B sname:20B age:2B sex:1B nation:10B . . . . . . . pstu p2 p1 1.4 结构体指针 指向结构体的指针 struct student { long sno; char sname[20]; int age; char sex; char nation[10]; } stu,*pstu; pstu=&stu; 定义指针指向结构体里的成员 int *p1; p1=&stu.age; char *p2; p2=stu.nation;
通过结构类型的指针变量,访问成员有以下两种形式:通过结构类型的指针变量,访问成员有以下两种形式: 如果象上面那样定义了指向结构体变量的指针变量p以后,*p即表示p所指向的结构体变量student,其成员student.num可表示为: (*p).num 或者p->num 第二种表示与第一种表示等价,运算符“->”与“.”优先级相同,具有最高的优先级。
Void main(){struct student { long sno; char sname[20]; int age; char sex; char nation[10]; } stu={101,"Zhang3",18,'F',"HanZu"},*pstu; int *p1; char *p2; pstu=&stu; p1=&stu.age; p2=stu.nation; cout<<"SNO:”<< (*pstu).sno, <<endl; cout<<“SName:”<< pstu->sname<<endl; cout<<“Age:”<< pstu->age <<endl; cout<<“sex:”<< pstu->sex <<endl; cout<<“Nation:“<< pstu->nation<<endl; cout<<"point1=“<<*p1<<endl; cout<<"point2=“<<p2; } SNO:101,SName:Zhang3,Age:18,sex:F,Nation:HanZu point1=18 point2=HanZu
sno sname age sex nation sno sname age sex nation sno sname age sex nation stu stu+1 stu+2 pstu 指向结构体数组的指针 struct student { long sno; char sname[20]; int age; char sex; char nation[10]; } stu[3], *pstu; pstu=stu; pstu+1 pstu+2
【例】分析下列程序的结果 #include <iostream.h> struct address { char name[20]; int age; char *addr; }; void main() { struct address info={"Chen Ming",18,"Street BeiJing 123"},*p; cout<<info.name<<','<<info.age<<','<<info.addr<<endl; p=&info; p->addr="Street BeiJing 251"; p->age=20; cout<<p->name<<','<<(*p).age<<','<<info.addr<<endl; }
1.5 结构体与函数 1:将结构体作为参数传递给函数: 值传递 地址传递 【结构体指针或结构体数组】 2:返回结构体类型的函数 以一个例子来说明
编写一个程序,描述公司的员工信息包括: 姓名、部门、薪水、工龄 实现以下功能 1:打印某个员工的信息 2:实现在年后为企业员工加薪和加工龄的函数 不同部门加薪程度不同,销售部 + 200, 技术部 + 150 3:按姓名查询到某位员工,并将其返回 首先:定义员工类型,初始化员工数组 打印员工信息函数,只需要值传递就可以,员工数据无需修改 年后加薪函数, 需要地址传递,因为需要修改员工的薪水 查询员工函数,需要返回员工类型的值
struct staff{//定义员工类型 char name[20]; char department[20]; float salary; int serv_time; }; struct staff //初始化员工数组 work[5]={ {“Zhang3”,”Sale Department”,5000.00,3}, {“Li4”,”Support Department”,6000.00,4}, {“Wang5”,”Support Department”,2000.00,1}, {“Cao6”,”Sale Department”,2500.00,3}, {“Cheng7”,”Support Department”,1300.00,1} }; void output(struct staff work){//打印员工信息函数,只需要值传递就可以,员工数据无需修改 cout<<“Name:”<<work.name<<“Dep:”<<work.department<<“Salary:”<<work.salary<<“ServTime:”<<work.serv_time<<endl; }
void annual(struct staff *work){ /*当s1=s2时,返回值=0*/ if (strcmp(work->department,”Sale Department”)==0) { work->salary+=200; work->serv_time+=1;} if (strcmp(work->department,”Support Department”)==0) { work->salary+=150; work->serv_time+=1;} }//年后加薪函数, 需要地址传递,因为需要修改员工的薪水 struct staff find(struct staff work[],char *name){ int i; for(i=0;i<N;i++) if (strcmp(work[i].name,name)==0) return work[i]; return ; }//查询员工函数,需要返回员工类型的值
Output: Name:Zhang3 ,Dep:Sale Department ,Salary:5000.000000 ,ServTime: 3 Name:Li4 ,Dep:Support Department ,Salary:6000.000000 ,ServTime: 4 Name:Wang5 ,Dep:Support Department ,Salary:2000.000000 ,ServTime: 1 Name:Cao6 ,Dep:Sale Department ,Salary:2500.000000 ,ServTime: 3 Name:Cheng7 ,Dep:Support Department ,Salary:1300.000000 ,ServTime: 1 Deal After: Name:Zhang3 ,Dep:Sale Department ,Salary:5200.000000 ,ServTime: 4 Name:Li4 ,Dep:Support Department ,Salary:6150.000000 ,ServTime: 5 Name:Wang5 ,Dep:Support Department ,Salary:2150.000000 ,ServTime: 2 Name:Cao6 ,Dep:Sale Department ,Salary:2700.000000 ,ServTime: 4 Name:Cheng7 ,Dep:Support Department ,Salary:1450.000000 ,ServTime: 2 Find a work: Name:Cao6 ,Dep:Sale Department ,Salary:2700.000000 ,ServTime: 4 #define N 5 Void main(){ void annual(struct staff *work); void output(struct staff work); struct staff find(struct staff work[],char *name); int i; char *name="Cao6"; for(i=0;i<N;i++) output(work[i]); for(i=0;i<N;i++) annual (&work[i]); // annual (work+i); for(i=0;i<N;i++) output(work[i]); cout<<"Find a work:“<<endl; output(find(work,name)); }
【例】编程求两个复数的和 复数的形式:a+bi 其中,a是实部,b是虚部。 建立描述复数的结构体类型: struct complex { double r; double i; }; struct complex add(struct complex x,struct complex y) { struct complex z; z.r=x.r+y.r; z.i=x.i+y.i; return z; } void main() { struct complex z; struct add(struct complex,struct complex); struct complex x={1.2,2.5},y={2.4,5.6}; z=add(x,y); cout<<"x+y="<<z.r<<"+i"<<z.i<<endl; } #include<iostream.h> struct complex { double r; double i; };
2 共用体 问题:什么是共用体类型?什么是共用体变量?共用体类型与结构体类型有什么区别和联系? 7.2.1 共用体类型的定义 共用体类型的定义与结构体类型的定义类似,但所用关键字不同,共用体类型用关键字union定义,具体形式为: union 类型名 {成员项表列}; union exam{ int a; float b; char c;};
定义了共用体变量后,系统为共用体变量开辟一定的存储单元。由于共用体变量先后存放不同类型的成员,系统开辟的共用体变量的存储单元的字节数为最长的成员需要的字节数。定义了共用体变量后,系统为共用体变量开辟一定的存储单元。由于共用体变量先后存放不同类型的成员,系统开辟的共用体变量的存储单元的字节数为最长的成员需要的字节数。 另外,先后存放各成员的首地址都相同,即共用体变量、共用体变量的所有成员它们的首地址都相同。 共用体变量的引用与引用结构体变量相似: 共同体可以直接赋值 uni1=uni2 x.ax.bx.c
【例】分析下列程序的输出结果 #include <iostream.h> union data {int i; char c; double d; }d1; void main() {d1.d=10.5; cout<<d1.d<<endl; d1.i=102; cout<<d1.i<<endl; d1.c='f'; cout<<d1.c<<endl; cout<<sizeof(double)<<','<<sizeof(d1)<<','<<sizeof(union data)<<endl; cout<<&d1<<','<<&d1.i<<','<<&d1.c<<','<<&d1.d<<endl; }
3 枚举类型 3.1 枚举类型的定义 枚举类型定义的形式为: enum 类型名{标识符序列}; 例如,定义枚举类型color_name,它由5个枚举值组成: enum color_name{red,yellow,blue,white,black}; enum weekday{ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday,Sunday} (1) enum是定义枚举类型的关键字。(2) 枚举值标识符是常量不是变量,系统自动给予它们0,1,2,3…值。
1.枚举变量的说明 可以用定义过的枚举类型来定义枚举变量,形式为: enum类型名变量名表; 例如定义枚举类型color_name的变量color: enum color_name color; 也可以在定义类型的同时定义变量,形式为: enum类型名{标识符序列}变量名表; 例如定义枚举类型color_name的变量color: enum color_name{red,yellow,blue,white,black} color; 或者省略类型名直接定义变量,形式为: enum{标识符序列} 变量名表;
编写程序:使用色彩的枚举型,当字体为黑色,背景为白色时编写程序:使用色彩的枚举型,当字体为黑色,背景为白色时 打印出GOOD!,并打印出颜色对应的系统值 enum color_name{red,yellow,blue,white,black}; main(){ enum color_name fontcolor, backgroudcolor; fontcolor = black; backgroudcolor = white; if (fontcolor == black && backgroudcolor==white){ cout<<"Good! black =“<<fontcolor <<“white =“<<backgroudcolor; } }
分析下列程序的结果 #include <iostream.h> enum color{red,orange,yellow,green,blue,violet,indigo}; void main() { enum color c1,c2; c1=yellow; c2=(enum color)1; int c3=3+blue; cout<<c1<<','<<c2<<','<<c3<<endl; }
已知今天的日期,编程求出明天的日期。 #include<iostream.h> struct date { int year; int month; int day; };//结构体 int judge(struct date *pd) { int l_year=0; if ((pd->year%4==0&&pd->year%100!=0)||pd->year%400==0) l_year=1; return l_year; }//判断是否是闰年 int day_no(struct date *pd) { int day; int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//可用枚举类型 if (judge(pd)&&(pd->month==2))day=29; else day=month[pd->month]; return day; } //根据月份计算当月天数
已知今天的日期,编程求出明天的日期。 void main() { struct date td,tm; int judge(struct date*),day_no(struct date *); cout<<"Enter today's day: "; cin>>td.year>>td.month>>td.day; if (td.day!=day_no(&td))//如果不是月末一日 { tm.day=td.day+1; tm.month=td.month; tm.year=td.year;} else if (td.month==12)//如果是12月末日 {tm.day=tm.month=1;tm.year=td.year+1;} else//如果是1-11月末日 {tm.day=1;tm.month=td.month+1;tm.year=td.year;} cout<<"Tomorrow is "<<tm.year<<'/'<<tm.month<<'/'<<tm.day<<endl; }