第5章构造数据类型 C++程序中除基本数据类型int,float,long,double,char,bool,string等外,还允许自己声明数据类型。用户声明的数据类型中最为常用的数据类型是“数组”。除数组外,还有结构体类型(structure)、共用体类型(union)、枚举类型(enumeration)、类类型(class)等。这些统称为用户自定义数据类型。 5.1结构体数据类型 5.1.1结构体概念 数组是单一数据类型的数据集合。结构体是一个可以包含不同数据类型的一个数据结构,它是一种可以自己定义的数据类型,它和数组主要不同点在于结构体可以在一个结构中声明不同的数据类型,相同结构的结构体变量是可以相互赋值的,而一个数组中的所有数组元素则是相同的数据类型,而且数组名是常量,不能用于整体赋值。结构体相当于其他高级语言或数据库中的记录(record)。 例如,银行储户的基本信息涉及储户账号、姓名、性别、地址、存款日期、存款金额等诸多信息。储户账号、地址是字符串型(string),存款金额是双精度型(double),性别是布尔型(bool),存款日期是日期型(date)。但是,在C++程序中没有日期型这个基本数据类型,一般通过年、月、日三个整型(int)来替代日期型,通过声明一个名为date日期型的结构体数据类型就可以解决这个问题。储户记录由若干不同的数据类型的数据组成,使用数组来处理储户记录需要多个不同的数组,操作过于烦琐,使用结构体数据类型能够方便地处理储户信息的记录数据。 5.1.2结构体声明 在C++程序中设计一个计算储户定期存款程序需要涉及储户的存款日期、取款日期等有关日期型数据的处理,我们已经知道C++程序中没有像其他语言一样提供“日期/时间”这个基本数据类型,要处理完整的日期型数据,则要声明一个日期型的结构体数据类型。 例如,结构体数据类型日期(date)由年(year)、月(month)、日(day)组成,C++语言允许用户将三个整型组合成一个日期型类型构成结构体,如表5.1所示。 表5.1结构体date date monthdayyear 声明一个名为date的结构体类型。 struct date {int month; int day; int year; }; 声明一个结构体类型date,struct是声明结构体类型的关键字,经过声明后,date就成为一个在本程序中合法使用的数据类型的名称,date结构体类型声明后它和系统提供的int,char,float,double,bool,string等基本数据类型一样可以用来定义变量类型。 声明一个结构体类型的一般形式如下。 struct结构体类型名 {成员表}; 结构体类型名用来作为结构体类型的标志。上面例子的声明中date是结构体类型名。花括号内是该结构体中的全部成员(member),由它们组成一个特定的结构体。上例中的month,day,year等都是结构体中的成员。在声明一个结构体类型时必须对其成员都进行相应类型声明,结构体成员的数据类型声明格式为“类型名成员名;”,每一个结构体成员定名规则与变量定名相同。结构体成员可以是常用的数据类型,也可以是已经声明过的结构体类型。它的成员不仅是数据变量(称为数据成员),而且还可以是一个函数(称为成员函数)。C++语言中提供了类(class)类型,一般而言,结构体中不必带有函数成员。 例如,声明两个结构体类型date和depositors。结构体类型date和depositors成员名数据类型如表5.2和表5.3所示。 表5.2结构体类型date成员名数据类型 成员名说明成员名数 据 类 型数据类型说明 月monthint整型 日dayint整型 年yearint整型 表5.3结构体类型depositors成员名数据类型 成员名说明成员名数 据 类 型数据类型说明 储户账号depositorsidlong长整型 储户姓名depositorsnamechar [ ]或string字符数组型或者字符串型 存款日期depositdatedate结构体类型 定期存款额fixeddepositdouble双精度型 存款年数deposityearint整型 存款利率depositratedouble双精度型 存款利息depositinterestdouble双精度型 结构体类型date及depositors声明语句如下。 struct date {int month; int day; int year; }; struct depositors {long depositorsid; char depositorsname[40]; date depositdate; double fixeddeposit; int deposityear; double depositrate; double depositinterest; }; 在声明depositors结构体类型时,其中一个成员depositdate是date结构体类型,date类型必须在depositors结构体声明前先进行声明。 声明结构体类型的位置一般在文件的开头,在所有函数(包括main函数)之前,便于本文件中所有的函数都能利用它来定义变量。当然,也可以在函数中声明结构体类型。 5.1.3结构体类型变量的定义方法 可以采用下列三种方法定义结构体类型的变量。 1. 方法一 先声明结构体类型,再定义变量的一般形式如下。 struct结构体名 {成员表}; 结构体类型名变量名; 例如: datedate1,date2; depositorsd1[10]; 说明: date和depositors是一个结构体类型名,在用结构体类型名定义变量时,date1,date2是date结构体类型的变量,d1[10]是depositors结构体类型数组变量。 2. 方法二 在声明类型的同时定义变量的一般形式如下。 struct结构体名 {成员表}变量名; 例如: struct date {int month; int day; int year; }date1,date2; 3. 方法三 直接定义结构体类型及变量的一般形式如下。 struct {成员表}变量名; 例如: struct {int month; int day; int year; }date1,date2; 说明: 方法三虽然合法,但是很少使用。一般提倡使用方法一“先声明结构体类型,再定义变量”,因为将声明结构体类型和定义结构体变量分开,有利于不同的函数甚至不同的文件能够使用所声明的结构体类型。若程序较长,在C++中允许将若干个结构体类型的声明集中放在一个头文件中,可以使用#include指令将头文件包含到本文件中,这个文件就能使用这个结构体类型。 关于结构体类型的几点说明。 (1) 结构体类型的结构根据需要进行设计,可以设计出多种不同的结构体类型。 (2) 类型与变量是两个不同的概念。只能对结构体变量中的成员赋值,而不能对结构体类型赋值。C++在编译时对类型是不分配空间的,只对变量分配空间。 (3) 结构体中的成员可以单独使用,它的作用与地位和普通变量相同。 (4) 结构体成员可以是一个结构体变量。 (5) 结构体中的成员名可以与程序中的变量名相同,二者之间没有关系。 5.1.4结构体变量的初始化 与其他类型的变量一样,结构体变量可以在定义时进行初始化来指定初值。 例如: struct date {int month; int day; int year; }; struct depositors {long depositorsid; char depositorsname[40]; date depositdate; double fixeddeposit; int deposityear; double depositrate; double depositinterest; }; depositors e1={932111222,"李强",11,30,2013,20000,1,0.0325,650}; 说明: 在Visual C++6.0中不支持对数据类型为string字符串型的结构体成员初始化,所以本例中depositorsname采用了字符数组型来实现结构体变量成员depositorsname的初始化。 5.1.5结构体变量的使用 定义了结构体变量就可以使用这个变量及成员,使用结构体变量中成员的一般形式如下。 结构体变量名.成员名 例如: e1.depositorsid//使用结构体变量e1的成员depositorsid “.”是成员运算符,它在所有运算符中优先级最高,把e1.depositorsid作为一个整体来处理。 【例51】声明两个结构体类型date和depositors,定义一个名为e1的结构体变量且数据初始化,输出e1变量的各成员数据。 编写程序 1#include 2using namespace std; 3#include 4struct date 5{int month; 6int day; 7int year; 8}; 9struct depositors 10{long depositorsid; 11char depositorsname[40]; 12date depositdate; 13double fixeddeposit; 14int deposityear; 15double depositrate; 16double depositinterest; 17}; 18int main() 19{depositors e1={932111222,"李强",11,30,2013,20000,1,0.0325,650}; 20cout<<"depositorsid:"<>e2;,也不能写成: cout< 2using namespace std; 3#include 4struct date 5{int month; 6int day; 7int year; 8}; 9struct depositors 10{long depositorsid; 11char depositorsname[40]; 12date depositdate; 13double fixeddeposit; 14int deposityear; 15double depositrate; 16double depositinterest; 17}; 18int main() 19{depositors e[5]={ 20{932111222,"李强",11,30,2013,20000,1,0.0325,650}, 21{932111223,"张丽丽",12,21,2013,35000,2,0.0375,2625}, 22{932111654,"伍刚",12,12,2013,17000,5,0.0475,4037.5}, 23{932111987,"徐丽霞",10,4,2013,18500,3,0.0425,2358.75}, 24{932111223,"张丽丽",10,11,2013,9000,2,0.0375,675}}; 25void print(depositors array[]); 26void search(depositors array[]); 27print(e); 28search(e); 29return 0; 30} 31void print(depositors array[]) 32{int i; 33cout<<"id,name,date(month/day/year),deposit,year,rate,interest" 34<>search_id; 49for(i=0;i<=4;i++) 50{if (array[i].depositorsid==search_id) 51{ cout< 2#include 3using namespace std; 4struct person 5{int id; 6char name[30]; 7char job; 8union c 9{ int score; 10char jobtitle[10]; 11}category; 12}; 13person p[2]; 14int main() 15{int i; 16p[0].id=1; 17strcpy(p[0].name,"王刚"); 18p[0].job='s'; 19p[0].category.score=75; 20p[1].id=2; 21strcpy(p[1].name,"张小强"); 22p[1].job='t'; 23strcpy(p[1].category.jobtitle,"副教授"); 24for(i=0;i<=1;i++) 25{ cout< 2#include 3using namespace std; 4int main() 5{enum grade {A_level,B_level,C_level,D_level}; 6grade g1[10]; 7int i;float score; 8for (i=1;i<=10;i++) 9{cin>>score; 10switch (int(score/5)) 11{case 20: 12case 19: 13case 18: 14case 17:g1[i]=grade(0);break; 15case 16: 16case 15:g1[i]=grade(1);break; 17case 14: 18case 13: 19case 12:g1[i]=grade(2);break; 20default:g1[i]=grade(3);break; 21} 22} 23for(i=1;i<=10;i++) 24 switch (g1[i]) 25{case A_level:cout<<"A_level"< 2#include 3using namespace std; 4struct person 5{string name; 6int count; 7}; 8person leader[100]; 9int num=4; 10int main() 11{void sort(person x[]); 12int i,j,n; 13bool flag=true; 14leader[0].name="DAI";leader[0].count=0; 15leader[1].name="LI";leader[1].count=0; 16leader[2].name="WANG"; leader[2].count=0; 17leader[3].name="ZHAO"; leader[3].count=0; 18string leadername[100]; 19cout<<"请输入选民人数:"; 20cin>>n; 21 22for(i=0;i>leadername[i]; 25} 26 27for(i=0;i 2#include 3using namespace std; 4struct line 5{string sentence; 6int count; 7string word[100]; 8}; 9 10line str[100]; 11int n; 12 13int main() 14{void input(); 15void print(); 16void filterword(); 17input(); 18filterword(); 19print(); 20return 0; 21} 22 23void input() 24{cout<<"输入n:"; 25cin>>n; 26char x; 27getchar(); 28int i; 29for(i=0;i<=n-1;i++) 30{cout<<"输入第"<