• 沒有找到結果。

数组是由相同类型的数据元素组成,而结构是由一组不同的数据类型构成。结构类型为 处理复杂的数据提供了便利的手段。如一个学生的信息就是由姓名、性别、出生日期、籍贯、

成绩等不同类型的数据共同组成,它如同数据库表的结构。结构与数组都是构造类型,也十分 相似,都是由若干分量组成,结构中的分量称为结构成员。

4.6.1 结构

在程序中使用结构之前,首先要对结构的组成进行描述,称为结构类型的定义。

1.结构类型定义 形式:

struct 结构类型标识符 {

结构成员 1;

结构成员 2;

结构成员 n;

};

说明:

(1)说明结构类型的关键字是 struct,其后的结构类型标识符是所定义的结构类型名。

(2)结构类型是一种混合的数据类型,其成员可为任意类型,只有自身的实例除外。

例如,描述一个人的出生日期可以说明下面的结构类型:

struct date {

int month;

int day;

int year;

};

该结构类型的变量又可以作为其他结构类型的成员。例如:

struct man {

char name[15];

char sex;

int age;

struct date birthday;

};

以上说明了一个结构类型 struct man,其中有一个成员 birthday 又是 struct date 类型的变量,

其结构如图 4.22 所示。

birthday

name sex age

month day year

图 4.22 结构类型 struct man 2.结构类型变量的定义

从语法上来说,用户自定义的结构类型的地位等同于 char、int、float、double 等标准类型。

结构类型本身并不占用存储空间,只有结构变量才需要分配存储空间。结构变量的成员在内存 中占用一片连续存储区域,其大小为结构中每个成员的长度之和。C++语言中提供了 3 种利用 已说明的结构类型定义结构变量的方法。

(1)说明结构类型的同时定义结构变量,如:

struct man {

char name[15];

char sex;

int age;

struct date birthday;

}m1;

以上在说明结构类型 man 的同时定义了一个该类型的变量 m1。

(2)省略类型名,直接定义结构变量,如:

struct {

char name[15];

char sex;

int age;

struct date birthday;

}m[3];

此处定义了一个包含 3 个元素的结构数组,其中每个元素都是一个包含若干个成员的结 构类型数据。C++语言中允许定义这种无类型名的变量。

(3)说明结构类型之后,再定义该类型的变量,如:

struct man m2,*p;

该语句定义了一个 struct man 类型的变量 m2 和指向结构类型的指针变量 p。

3.结构类型变量的引用

(1)普通结构变量成员的访问。

形式:结构变量名.成员名

其中,“.”是成员访问运算符,是优先级最高的运算符之一。如果结构变量的成员本身也 是结构类型,则需要使用多个“.”运算符来实现。

例如,对前面定义过的 m1 变量进行赋值:

strcpy (m1.name, "Wang Min");

m1.sex = 'F';

m1.age = 24;

m1.birthday.month = 8;

m1.birthday.day = 10;

m1.birthday.year = 1985;

(2)通过指针访问结构变量的成员。

形式:(*指向结构的指针).成员名 或

指向结构的指针->成员名

注意:不能省略圆括号。运算符“->”与“.”运算符相同,具有所有运算符中最高的优 先级。假设有定义:

struct man1 m,*p=&m;

则可以这样对结构变量 m 的成员赋值:strcpy(p->name, "Wang Min");。

【例 4.16】用结构数组保存学生数据并显示。

程序如下:

//Ex4_16.cpp

#include "iostream"

#include "cstring"

using namespace std;

struct person {

char name[10]; //姓名 bool sex; //性别 int age; //年龄 float score; //成绩 }a[10];

void main() {

int n,i,k;

person x;

cout<<"请输入一个正整数(1~n):";

cin>>n;

cout<<"从键盘输入具有 person 结构的"<<n<<"个记录:"<<endl;

for(i=0;i<n;i++) {

cin>>x.name;

cin>>k;

if (k==1) x.sex=true; else x.sex=false; //1 为男,非 1 为女 cin>>x.age>>x.score ;

a[i]=x; //结构赋值 }

cout<<"显示具有 person 结构的"<<n<<"个记录:"<<endl;

for(i=0;i<n;i++) {

cout<<a[i].name<<' ';

if (a[i].sex==true) cout<<"man"<<' ';

else cout<<"woman"<<' ';

cout<<a[i].age<<' '<<a[i].score<<endl;

} }

运行结果如图 4.23 所示。

图 4.23 运行结果

4.6.2 链表基础

结构类型的重要应用之一就是链表。现实生活中存在大量需要动态存储和表示的数据,

如排队、数据排序等。链表是一种动态数据结构,所谓“动态数据结构”是指在程序运行过 程中,数据结构的规模可以根据实际的需要动态变化,从而可以克服数组在使用前必须确定 大小的问题。

1.链表的概念

在结构类型中有一种特殊类型,它除了包含有一般的数据域以外,还包含一个指向自身 结构的指针。这种类型的对象又称节点,每个节点的指针域用来指向下一个节点,由此形成一 个链表,如图 4.24 所示。

例如:

struct item {

(3)循环链表(以单向循环链表为例),如图 4.27 所示。

图 4.27 单向循环链表 对链表的主要操作有以下几种:

(1)建立或生成一个链表。

(2)查找链表元素。

(3)插入一个新元素。

 插表头:将每一新节点固定插入至当前已生成链表的表头位置。

 插表尾:将每一新节点固定插入至当前已生成链表的表尾位置。

 有序表:将每一新节点插入至链表中的适当位置(表头、表中或表尾),以保持链表 的有序性。

(4)删除一个链表节点。

(5)遍历链表,输出链表长度及节点的有关信息。

【例 4.17】输入简化的学生数据,把它们组成线性链表,并输出各学生信息。要求每一 新节点都插入至已生成链表的表头位置。

分析:(1)生成链表:依次键入学号(假设互不相同),创建新的节点,并插入至表头位 置。遇结束标志即止,此时已生成所需链表。

(2)遍历链表:从表头开始,“顺藤摸瓜”遍历所有节点并输出各节点中的有关信息——

学号,直至表尾。

程序如下:

//Ex4_17.cpp

#include "iostream"

#include "cstring"

#include "iomanip"

using namespace std;

void main( ) {

struct item {

int num;

item *next;

};

item *head=NULL,*temp; //初始表头为 NULL int stno;

cout<<"Enter students' numbers,-1 to stop:"<<endl;

head

. 2

. 4

.

5 1 num

next

cin>>stno;

while(stno!=-1) {

temp=new item; //申请新的节点 temp->num=stno; //向节点保存数据

temp->next=head; //初始表尾为 NULL,以后用于节点的连接 head=temp; //更新表头

cin>>stno; //输入新数据 }

cout<<"The output will be:"<<endl;

temp=head; //非空表可略 while(temp!=NULL)

{cout<<setw(6)<<temp->num;

temp=temp->next;}

cout<<endl;

}

运行结果如图 4.28 所示。

图 4.28 运行结果

思考:如要求每一新表元素都插入至已生成链表的表尾位置,该如何修改程序?

相關文件