C++提供了一些基本的数据类型(如int,float,double,char等)供用户使用,但是由于程序需要处理的问题往往比较复杂,而且呈多样化,已有的数据类型不能满足使用要求。因此C和C++允许用户根据需要自己声明一些类型。此外用户可以自己声明的类型还有结构体类型,共用体类型,枚举类型,类类型等,这些统称为用户自定义类型。
结构体类型
为什么需要有结构体类型
数组是用户自己建立的数据类型,数组中的各元素是属于同一个类型的,但是在处理任务时只有数组还是不够,有时需要将不同类型的数组合成一个有机的整体,以供用户方便地使用。这些组合在一个整体中的数据是互相联系的。
一些互相独立的变量可以组织成一个组合项,在一个组合项中包含若干类型不同的数据项,称为结构体。
一个简单的结构体如下:
struct Student //声明一个结构体类型Student
{
int num; //包括一个整型变量num
char name[20]; //包括一个字符数组name,可以容纳20个字符
char sex; //包括一个字符变量sex
int age; //包括一个整型变量age
float score; //包括一个单精度型变量score
}; //最后有一个分号
struct是声明结构体类型时必须使用的关键字,它向编译系统声明,这是一种结构体类型,它包括一些不同类型的数据项。
声明一个结构体类型的一般形式为
struct 结构体类型名
{成员表};
结构体类型名用来作结构体类型的标志。在声明一个结构体类型时必须对各成员进行类型声明,每一个成员也称为结构体中的一个域,成员表又称为域表,成员名定名规则与变量名相同。
结构体类型变量的定义方法及其初始化
前面只是指定了一种结构体类型,它相当于一个模型,但其中并无具体数据,系统对其也不分配实际内存单元。为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。
定义结构体类型变量的方法
1、先声明结构体类型再定义变量
Student stu1,stu2;
2、在声明类型的同时定义变量
struct Student
{···}stu1,stu2;
建议使用第一种,结构体成员也可以是一个结构体变量。
结构体变量的初始化
对结构体变量可以在定义时指定初始值,也可以采取声明类型与定义变量分开的形式,在定义变量时进行初始化。
引用结构体变量
在定义了结构体变量后,可以引用这个变量。
1、可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量,如
stu1=stu2;
赋值时,结构体变量stu2中的各个成员的值分别赋给结构体变量stu1中相应的成员。
2、可以引用一个结构体变量中的一个成员的值,如
stu1.num //表示结构体变量stu1中的成员num的值。
引用结构体变量中成员的一般形式为:
结构体变量名.成员名
“.”是成员运算符,它在所有的运算符中优先级最高,因此可以把stu1.num作为一个整体看待。
例1:定义两个结构体变量stu1和stu2,成员包括学号、姓名、性别、出生日期和成绩。对stu2初始化,再把stu2的值赋给stu1,输出stu1的各成员。
#include <iostream>
using namespace std;
struct Date
{
int month;
int day;
int year;
};
struct Student
{
int num;
char name[20];
char sex;
Date birthday;
float score;
};
Student stu1;
Student stu2 = { 1002,"zhangsan",'B',2,15,2002,88.8 };
int main()
{
stu1 = stu2;
cout << "学号:" << stu1.num << endl;
cout << "姓名:" << stu1.name << endl;
cout << "成绩:" << stu1.sex << endl;
cout << "出生日期:" << stu1.birthday.year << "/" << stu1.birthday.month << "/" << stu1.birthday.day << endl;
cout << "分数:" << stu1.score << endl;
return 0;
}
结构体数组
一个结构体变量中可以存放一组数据,如一个学生的学号、姓名、成绩等,如果有10个学生的数据需要参加运算,显然应该用数组,这就是结构体数组。
结构体数组与以前介绍过的数值型数组不同之处在于,每个数组元素都是一个结构体类型的数据,它们都分别包括各个成员项。
例2:对候选人得票的统计程序。设有三个候选人,最终只能有一个人当选为领导,今有10个人参加投票,从键盘先后输入这10个人所投候选人的名字,要求最后输出各候选人的票结果。
#include <iostream>
#include <string>
using namespace std;
struct person
{
string name;
int count;
};
person leader[3] = { "zhao",0,"qian",0,"sun",0 };
int main()
{
int i, j;
string leader_name;
cout << "请输入10位候选人姓名:";
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 << endl;
for (i = 0; i < 3; i++)
cout << leader[i].name << ":" << leader[i].count << endl;
return 0;
}
指向结构体变量的指针
一个结构体变量的指针就是该变量所占据的内存段的起始地址,可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址,指针变量也可以用来指向结构体数组中的元素。
1、通过指向结构体变量的指针引用结构体变量中的成员
例3:定义一个结构体变量stu,成员包括学号、姓名、性别、成绩,定义一个指针变量p指向该结构体变量stu,通过该指针变量输出各成员的值。
#include <iostream>
#include <string>
using namespace std;
int main()
{
struct Student
{
int num;
string name;
char sex;
float score;
};
Student stu; //定义Student类型的变量stu
Student* p = &stu; //定义p为指向Student类型数据的指针变量并指向stu
stu.num = 10001;
stu.name = "zhangsan";
stu.sex = 'B';
stu.score = 88.88;
cout << stu.num << " " << stu.name << " " << stu.sex << " " << stu.score << endl;
cout << (*p).num << "-" << (*p).name << "-" << (*p).sex << "-" << (*p).score << endl;
return 0;
}
为了使用方便和使之直观,C和C++提供了指向结构体变量的运算符“->”,形象地表示指向关系。如p->num表示指针p当前指向的结构体变量中的成员num,和(*p).unm等价。
2、用结构体变量和指向结构体变量的指针构成链表
链表是一种常见的重要的数据结构。
链表有一个头指针变量,它存放一个地址,该地址指向一个元素。链表中的每一个元素称为结点,每个结点都应包括两个部分:第一部分为用户需要用的实际数据,第二部分为下一个结点的地址,直到最后一个元素,最后一个元素不再指向其它元素,它称为表尾,它的地址部分放一个NULL表示空地址,链表到此结束。
链表中各元素在内存中的存储单元可以是不连续的,要找某一元素,可以先找到上一个元素,根据它提供的下一个元素地址找到下一个元素。这种链表的数据结构必须利用结构体变量和指针才能实现。
可以声明一个结构体类型,包含两种成员,一种是用户需要的实际数据,另一种是用来存放下一结点地址的指针变量。
例4:建立一个链表,由3各学生数据的结点组成,输出各结点中的数据
#include <iostream>
using namespace std;
struct student
{
int num;
float score;
struct student* next;
};
int main()
{
student a, b, c, * head, * p;
a.num = 31001; a.score = 88.8;
b.num = 31008; b.score = 70;
c.num = 31111; c.score = 60;
head = &a;
a.next = &b;
b.next = &c;
c.next = NULL;
p = head;
do
{
cout << p->num << " " << p->score << endl;
p = p->next;
} while (p != NULL);
return 0;
}
结构体类型数据作为函数参数
将一个结构体变量中的数据传递给另一个函数,有三种方法
1、用结构体变量名作参数
2、用指向结构体变量的指针作实参,将结构体变量的地址传给形参
3、用结构体变量的引用作函数形参,它就成为实参的别名。
例5:有一个结构体变量stu,内含学生学号、姓名和三门课的成绩,要求在main函数中为各成员赋值,在另一函数print中将它们的值输出
1、用结构体变量作函数参数。
#include <iostream>
#include <string>
using namespace std;
struct Student
{
int num;
string name;
float score[3];
};
int main()
{
void print(Student);
Student stu;
stu.num = 123456;
stu.name = "zhangsan";
stu.score[0] = 60;
stu.score[1] = 70;
stu.score[2] = 80;
print(stu);
return 0;
}
void print(Student stu)
{
cout << stu.num << " " << stu.name << " " << stu.score[0] << " " << stu.score[1] << " " << stu.score[2] << endl;
}
2、用指向结构体变量的指针作实参
#include <iostream>
#include <string>
using namespace std;
struct Student
{
int num;
string name;
float score[3];
}stu = { 123456,"zhangsan",66,77,88 };
int main()
{
void print(Student*);
Student* pt = &stu;
print(pt);
return 0;
}
void print(Student* p)
{
cout << p->num << " " << p->name << " " << p->score[0] << " " << p->score[1] << " " << p->score[2] << endl;
}
3、用结构体变量的引用作函数实参
#include <iostream>
#include <string>
using namespace std;
struct Student
{
int num;
string name;
float score[3];
}stu = { 12346,"zhangsan",66,77,88 };
int main()
{
void print(Student&);
print(stu);
return 0;
}
void print(Student& stud)
{
cout << stud.num << " " << stud.name << " " << stud.score[0] << " " << stud.score[1] << " " << stud.score[2] << endl;
}
527

被折叠的 条评论
为什么被折叠?



