null第7章 自定义数据类型第7章 自定义数据类型7.1 结构体类型
7.2 共用体
7.3 枚举类型
7.4 用typedef
声明
无利益冲突声明中华医学会杂志社职业健康检查不够规范教育部留学服务中心亲友住房声明
类型nullC++提供了许多种基本的数据类型(如int、float、double、char等)供用户使用。但是由于程序需要处理的问题往往比较复杂,而且呈多样化,已有的数据类型显得不能满足使用要求。因此C++允许用户根据需要自己声明一些类型,例如第5章介绍的数组就是用户自己声明的数据类型。此外,用户可以自己声明的类型还有结构体(structure)类型、共用体(union)类型、枚举(enumeration)类型、类(class)类型等,这些统称为用户自定义类型(user-defined type,UDT)。 本章介绍结构体类型、共用体类型和枚举类型,第8章将介绍类类型。7.1 结构体类型
7.1.1 结构体概述7.1 结构体类型
7.1.1 结构体概述有时需要将不同类型的数据组合成一个有机的整体,以供用户方便地使用。这些组合在一个整体中的数据是互相联系的。例如,一个学生的学号、姓名、性别、年龄、成绩、家庭地址等项,都是这个学生的属性。见图7.1。
图7.1null在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。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个字符
}; //最后有一个分号null这样,程序
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
者就声明了一个新的结构体类型Student(struct是声明结构体类型时所必须使用的关键字,不能省略),它向编译系统声明: 这是一种结构体类型,它包括num, name, sex, age, score, addr等不同类型的数据项。应当说明Student是一个类型名,它和系统提供的标准类型(如int、char、float、double等)一样,都可以用来定义变量,只不过结构体类型需要事先由用户自己声明而已。
声明一个结构体类型的一般形式为
struct 结构体类型名
{成员表列};null结构体类型名用来作结构体类型的标志。上面的声明中Student就是结构体类型名。大括号内是该结构体中的全部成员(member),由它们组成一个特定的结构体。上例中的num,name,sex,score等都是结构体中的成员。在声明一个结构体类型时必须对各成员都进行类型声明,即
类型名 成员名;
每一个成员也称为结构体中的一个域(field)。成员表列又称为域表。成员名的定名规则与变量名的定名规则相同。
声明结构体类型的位置一般在文件的开头,在所有函数(包括main函数)之前,以便本文件中所有的函数都能利用它来定义变量。当然也可以在函数中声明结构体类型。null在C语言中,结构体的成员只能是数据(如上面例子中所表示的那样)。C++对此加以扩充,结构体的成员既可以包括数据(即数据成员),又可以包括函数(即函数成员),以适应面向对象的程序设计。但是由于C++提供了类(class)类型,一般情况下,不必使用带函数的结构体,因此在本章中只介绍只含数据成员的结构体,有关包含函数成员的结构体将在第8章介绍类类型时一并介绍。7.1.2 结构体类型变量的定义
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
及其初始化7.1.2 结构体类型变量的定义方法及其初始化前面只是指定了一种结构体类型,它相当于一个模型,但其中并无具体数据,系统也不为之分配实际的内存单元。为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。
1. 定义结构体类型变量的方法
可以采取以下3种方法定义结构体类型的变量。
(1) 先声明结构体类型再定义变量名
如上面已定义了一个结构体类型Student,可以用它来定义结构体变量。如
Student student1, student2;null以上定义了student1和student2为结构体类型Student的变量,即它们具有Student类型的结构。如图7.2所示。
图7.2
在定义了结构体变量后,系统会为之分配内存单元。例如student1和student2在内存中各占63个字节(4+20+1+4+4+30=63)。null(2) 在声明类型的同时定义变量
例如:
struct Student //声明结构体类型Student
{ int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}student1,student2; //定义两个结构体类型Student的变量student1,student2
这种形式的定义的一般形式为
struct 结构体名
{
成员表列
}变量名表列;null(3) 直接定义结构体类型变量
其一般形式为
struct //注意没有结构体类型名
{
成员表列
} 变量名表列;
这种方法虽然合法,但很少使用。提倡先定义类型后定义变量的第(1)种方法。在程序比较简单,结构体类型只在本文件中使用的情况下,也可以用第(2)种方法。
关于结构体类型,有几点要说明: null(1) 不要误认为凡是结构体类型都有相同的结构。实际上,每一种结构体类型都有自己的结构,可以定义出许多种具体的结构体类型。
(2) 类型与变量是不同的概念,不要混淆。只能对结构体变量中的成员赋值,而不能对结构体类型赋值。在编译时,是不会为类型分配空间的,只为变量分配空间。
(3) 对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。关于对成员的引用方法见7.3节。
(4) 成员也可以是一个结构体变量。
如nullstruct Date //声明一个结构体类型Date
{ int month;
int day;
int year;
};
struct Student //声明一个结构体类型Student
{ int num;
char name[20];
char sex;
int age;
Date birthday; //Date是结构体类型,birthday是Date类型的成员
char addr[30];
}student1,student2; //定义student1和student2为结构体类型Student的变量
Student的结构见图7.3所示。null
图7.3
(5) 结构体中的成员名可以与程序中的变量名相同,但二者没有关系。例如,程序中可以另定义一个整型变量num,它与student中的num是两回事,互不影响。null2. 结构体变量的初始化
和其他类型变量一样,对结构体变量可以在定义时指定初始值。如
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″};
这样,变量student1中的数据如图7.2中所示。
也可以采取声明类型与定义变量分开的形式,在定义变量时进行初始化:
Student student2={10002,″Wang Li″,′F′,20,98,″Beijing″;
//Student是已声明的结构体类型7.1.3 结构体变量的引用7.1.3 结构体变量的引用在定义了结构体变量以后,当然可以引用这个变量。
(1) 可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量。如上面的student1和student2都是student类型的变量,可以这样赋值:
student1= student2;
(2) 可以引用一个结构体变量中的一个成员的值。例如, student1.num表示结构体变量student1中的成员的值,如果student1的值如图7.2所示,则student1.num的值为10001。
引用结构体变量中成员的一般方式为
结构体变量名.成员名null例如可以这样对变量的成员赋值:
student1.num=10010;
(3) 如果成员本身也是一个结构体类型,则要用若干个成员运算符,一级一级地找到最低一级的成员。例如,对上面定义的结构体变量student1, 可以这样访问各成员:
student1.num (引用结构体变量student1中的num成员)
如果想引用student1变量中的birthday成员中的month成员,不能写成student1.month,必须逐级引用,即
student1.birthday.month (引用结构体变量student1中的birthday成员中的month成员)null(4) 不能将一个结构体变量作为一个整体进行输入和输出。例如,已定义student1和student2为结构体变量,并且它们已有值。不能企图这样输出结构体变量中的各成员的值:
cout<
using namespace std;
struct Date //声明结构体类型Date
{int month;
int day;
int year;
};
struct Student //声明结构体类型Student
{int num;
char name[20];
char sex;
Date birthday; //声明birthday为Date类型的成员
float score;
}student1,student2={10002,″Wang Li″,′f′,5,23,1982,89.5};
//定义Student 类型的变量student1,student2,并对student2初始化
int main( )
{ student1=student2; //将student2各成员的值赋予student1的相应成员nullcout<
struct Person //声明结构体类型Person
{ char name[20];
int count;null};
int main( )
{ Person leader[3]={″Li″,0,″Zhang″,0,″Fun″,0};
//定义Person类型的数组,内容为3个候选人的姓名和当前的得票数
int i,j;
char leader_name[20]; //leader_name为投票人所选的人的姓名
for(i=0;i<10;i++)
{cin>>leader_name; //先后输入10张票上所写的姓名
for(j=0;j<3;j++) //将票上姓名与3个候选人的姓名比较
if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;
//如果与某一候选人的姓名相同,就给他加一票
}
cout<
#include
using namespace std;
struct Person
{ string name; //成员name为字符串变量
int count;
};
int main( )
{ Person leader[3]={″Li″,0,″Zhang″,0,″Fun″,0};
int i,j;
string leader_name; // leader_name为字符串变量
for(i=0;i<10;i++)
{cin>>leader_name;
for(j=0;j<3;j++)
if(leader_name==leader[j].name) leader[j].count++; //用“==”进行比较
}
cout<
#include
using namespace std;
int main( )
{struct Student //声明结构体类型student
{ int num;
string name;
char sex;
float score;
};
Student stu; //定义Student类型的变量stu
Student *p=&stu; //定义p为指向Student类型数据的指针变量并指向stu
stu.num=10301; //对stu中的成员赋值
stu.name=″Wang Fun″; //对string变量可以直接赋值
stu.sex=′f′;
stu.score=89.5;
cot<num<<″ ″<<(*p).name<<″ ″<<(*p).sex<<″ ″<<(*p).score<,例如p->num表示指针p当前指向的结构体变量中的成员num。p->num 和(*p).num等价。同样,p->name等价于(*p).name。null也就是说,以下3种形式等价:
① 结构体变量.成员名。如stu.num。
② (*p).成员名。如(*p).num。
③ p->成员名。如p->num。“->”称为指向运算符。
请
分析
定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析
以下几种运算:
p->n 得到p指向的结构体变量中的成员n的值。
p->n++ 得到p指向的结构体变量中的成员n的值,用完该值后使它加1。
++p->n 得到p指向的结构体变量中的成员n的值,并使之加1,然后再使用它。null2. 用结构体变量和指向结构体变量的指针构成链表
链表是一种常见的重要的数据结构。图7.8表示最简单的一种链表(单向链表)的结构。
图7.8
链表有一个“头指针”变量,图中以head表示,它存放一个地址。该地址指向一个元素。链表中的每一个元素称为“结点”,每个结点都应包括两个部分: 一是用户需要用的实际数据,二是下一个结点的地址。null可以看到链表中各元素在内存中的存储单元可以是不连续的。要找某一元素,可以先找到上一个元素,根据它提供的下一元素地址找到下一个元素。
可以看到,这种链表的数据结构,必须利用结构体变量和指针才能实现。可以声明一个结构体类型,包含两种成员,一种是用户需要用的实际数据,另一种是用来存放下一结点地址的指针变量。例如,可以设计这样一个结构体类型:
struct Student
{ int num;
float score;
Student *next; //next指向Student结构体变量
};null其中成员num和score是用户需要用到的数据,相当于图7.8结点中的A,B,C,D。next是指针类型的成员,它指向Student类型数据(就是next所在的结构体类型)。用这种方法就可以建立链表。见图7.9。
图7.9
图中每一个结点都属于Student类型,在它的成员next中存放下一个结点的地址,程序设计者不必知道各结点的具体地址,只要保证能将下一个结点的地址放到前一结点的成员next中即可。null下面通过一个例子来说明如何建立和输出一个简单链表。
例7.4 建立一个如图7.9所示的简单链表,它由3个学生数据的结点组成。输出各结点中的数据。
#define NULL 0
#include
struct Student
{ long num;
float score;
struct Student *next;
};
int main( )
{ Student a,b,c,*head,*p;
a. num=31001; a.score=89.5; //对结点a的num和score成员赋值
b. num=31003; b.score=90; //对结点b的num和score成员赋值
c. num=31007; c.score=85; //对结点c的num和score成员赋值
head=&a; //将结点a的起始地址赋给头指针headnulla.next=&b; //将结点b的起始地址赋给a结点的next成员
b.next=&c; //将结点c的起始地址赋给b结点的next成员
c.next=NULL; //结点的next成员不存放其他结点地址
p=head; //使p指针指向a结点
do
{cout<num<<″ ″<score<next; //使p指向下一个结点
} while(p!=NULL); //输出完c结点后p的值为NULL
return 0;
}
请读者考虑: ①各个结点是怎样构成链表的。②p起什么作用?null本例是比较简单的,所有结点(结构体变量)都是在程序中定义的,不是临时开辟的,也不能用完后释放,这种链表称为静态链表。对各结点既可以通过上一个结点的next指针去访问,也可以直接通过结构体变量名a,b,c去访问。
动态链表则是指各结点是可以随时插入和删除的,这些结点并没有变量名,只能先找到上一个结点,才能根据它提供的下一结点的地址找到下一个结点。只有提供第一个结点的地址,即头指针head,才能访问整个链表。如同一条铁链一样,一环扣一环,中间是不能断开的。建立动态链表,要用到下面7.1.7小节介绍的动态分配内存的运算符new和动态撤销内存的运算符delete。7.1.6 结构体类型数据作为函数参数7.1.6 结构体类型数据作为函数参数将一个结构体变量中的数据传递给另一个函数,有下列3种方法:
(1) 用结构体变量名作参数。一般较少用这种方法。
(2) 用指向结构体变量的指针作实参,将结构体变量的地址传给形参。
(3) 用结构体变量的引用变量作函数参数。
下面通过一个简单的例子来说明,并对它们进行比较。
例7.5 有一个结构体变量stu,内含学生学号、姓名和3门课的成绩。要求在main函数中为各成员赋值,在另一函数print中将它们的值输出。null(1) 用结构体变量作函数参数
#include
#include
using namespace std;
struct Student //声明结构体类型Student
{ int num;
char name[20];
float score[3];
};
int main( )
{ void print(Student); //函数声明,形参类型为结构体Student
Student stu; //定义结构体变量
stu.num=12345; //以下5行对结构体变量各成员赋值
stu.name=″Li Fung″;
stu.score[0]=67.5;
stu.score[1]=89;
stu.score[2]=78.5;
print(stu); //调用print函数,输出stu各成员的值
return 0;
}
nullvoid print(Student stu)
{cout<
#include
using namespace std;
struct Student
{ int num;
string name; //用string类型定义字符串变量
float score[3];
}stu={12345,″Li Fung″,67.5,89,78.5}; //定义结构体student变量stu并赋初值
int main( )
{ void print(Student *); //函数声明,形参为指向Student类型数据的指针变量nullStudent *pt=&stu; //定义基类型为Student的指针变量pt,并指向stu
print(pt); //实参为指向Student类数据的指针变量
return 0;
}
void print(Student *p) //定义函数,形参p是基类型为Student的指针变量
{ cout<num<<″ ″<name<<″ ″<score[0]<<″ ″
<score[1]<<″ ″<score[2]<
#include
using namespace std;
struct Student
{ int num;
string name;
float score[3];
}stu={12345,″Li Li″,67.5,89,78.5};
int main( )
{ void print(Student &); //函数声明,形参为Student类型变量的引用
print(stu); //实参为结构体Student变量
return 0;
}
void print(Student &stud) //函数定义,形参为结构体Student变量的引用
{cout<
#include
using namespace std;
struct Student //声明结构体类型Student
{ string name;
int num;
char sex;
};
int main( )
{ Student *p; //定义指向结构体类型Student的数据的指针变量
p=new Student; //用new运算符开辟一个存放Student型数据的空间
p->name=″Wang Fun″; //向结构体变量的成员赋值
p->num=10123;
p->sex=′m′;
cout<name<num<sex<
书
关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf
译为联合)。
声明共用体类型的一般形式为
union 共用体类型名
{成员表列
};
定义共用体变量的一般形式为
共用体类型名 共用体变量名;
当然也可在声明共用体类型的同时定义共用体变量,也可没有共用体类型名而直接定义共用体变量。null例如
可以看到,“共用体”与“结构体”的定义形式相似。但它们的含义是不同的。结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。共用体变量所占的内存长度等于最长的成员的长度。7.2.2 对共用体变量的访问方式7.2.2 对共用体变量的访问方式不能引用共用体变量,而只能引用共用体变量中的成员。例如,下面的引用方式是正确的:
a.i (引用共用体变量中的整型成员i)
a.ch(引用共用体变量中的字符型成员ch)
a.f (引用共用体变量中的双精度型成员d)
不能只引用共用体变量,例如
cout<
#include
#include //因为在输出流中使用了控制符setw
using namespace std;
struct
{ int num;
char name[10];nullchar sex;
char job;
union P //声明共用体类型
{ int grade; //年级
char position[10]; //职务
}category; //成员category 为共用体变量
}person[2]; //定义共用体数组person,含两个元素
int main( )
{ int i;
for(i=0;i<2;i++) //输入两个学生的数据
{cin>>person[i].num>>person[i].name>>person[i].sex>>person[i].job;
if(person[i].job==′s′) cin>>person[i].category.grade; //若是学生则输入年级
else if (person[i].job==′t′) cin>>person[i].category.position;//若是教师则输入职务
}
cout<
#include //在输出时要用到setw控制符
using namespace std;
int main( )
{ enum color {red,yellow,blue,white,black}; //声明枚举类型color
color pri; //定义color类型的变量pri
int i,j,k,n=0,loop; //n是累计不同颜色的组合数
for (i=red;i<=black;i++) //当i为某一颜色时
for (j=red;j<=black;j++) //当j为某一颜色时
if (i!=j) //若前两个球的颜色不同
{ for (k=red;k<=black;k++) //只有前两个球的颜色不同,才需要检查第3个球的颜色
if ((k!=i) && (k!=j)) //3个球的颜色都不同
{n=n+1; //使累计值n加1
cout<
本文档为【谭浩强清华大学C++上课ppt第7章】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。