📄 c++8.dat
字号:
第八章 结构与链表
第一节 结构及使用
我们进行程序设计时,很少仅用到一些简单的数据类型,常常要将一些数据类型组合在一起.例如,假定要记录一批小孩的身高、重量、年龄和性别.可以用数组来处理:
const int nMaxChildren = 1000;
double heights[nMaxChildren];
double weights[nMaxChildren];
int years[nMaxChildren];
int months[nMaxChildren];
char gender[nMaxChildren];
如果我们要查找某一个小孩的身高、体重等,可以通过读取有相同下标的数组元素得到,如heights[5], weights[5]等.但是,一个小孩到底有哪些相关的数据项,不是很明显.况且,不能排除要将某些数组排序,如按身高排序,在这种情况下,要获取某一个小孩的相关数据项将十分困难.
C++中,提供了结构(struct)数据类型,它能够识别一组相关的数据.
我们已经知道数组,它用来保存线性数据,但是它有许多缺点:
* 数组的大小是固定的,在程序运行期间是不能改变的.我们在定义数组时必须足够大,保证程序运行时不会溢出.但是,这也常常导致大量数组存储单元的浪费.
* 数组需要一块连续的内存空间.但当应用程序较大,数组需要的内存块也较大时,这可能会降低程序的效率.
* 如果在数组元素中,有较多的插入操作,则被插元素后的元素需要向后移位,这也浪费机器的运行时间.
链表也是表示线性数据最有用的方法之一,用链表保存线性数据,可以克服数组的问题.使用链表数据结构需要结构和指针作为基础,本章中,我们将学习结构和链表的有关知识.
在定义C++结构时,允许指定一组数据变量:
struct Child {
double height;
double weight;
int years;
int months;
char gender;
};
这样,我们就定义了一个结构类型Child,struct是关键字.Child类型包含两个double、两个int和一个char域(或成员),它可以与C++的基本数据类型一样地使用.(注意)结构类型定义也是一个语句,所以结尾必须有分号(;),否则,会产生编译错误.
同标准的char、long、double 等类型一样,定义结构类型以后,便可以定义结构类型的变量,结构类型的变量在内存中占的字节数 是其各个成员在内存中占的字节数的总和.例如:
Child cute;
Child kid;
Child brat;
也可以定义结构类型数组:
Child surveyset[nMaxChildren];
定义结构变量时,可以同时初始化它的数据成员:
Child example = {
125.0, 32.4, 13, 2, 'f'
};
结构变量也能够在定义结构类型时定义:
struct Rectangle {
int left, top;
int width, height;
} r1, r2, r3;
在定义Rectangle类型时,同时定义了三个Rectangle变量:r1、r2和r3.不过,我们应尽可能避免这种定义方式,把类型定义和变量定义分开,否则它很容易产生错误.
访问结构变量数据成员的方式为:
结构变量名.成员名
例如,我们要检查brat的身高是否超过某一个限度:
if(brat.height > h_limit)
…
同样,如果要设置cute的体重:
cute.weight = 35.4;
在大多数的语句和表达式中,是要访问结构的数据成员.但是,在C++中,整个结构变量的赋值也是允许的:
Child Tallest;
Tallest.height = 0;
for(int i = 0; i < NumChildren; i++)
if(surveyset[i].height > Tallest.height)
Tallest = surveyset[i];
编译器处理这样的赋值,是通过复制一个位置的内存块到另一个位置.
第二节 结构变量做为函数参数
函数参数有值传递和引用传递两种方式.结构变量作为函数参数时可以这两种方式中的任一种方式传递,也可以作为函数的返回值.结构变量作为函数参数传递和作为函数结果返回时,坚持下面的基本规则:
* 对于小的结构数据,可以采用传值的方法.
* 对于大的结构数据,采用传地址或引用.因为占用内存大的结构变量,在复制时,对时间和空间的开销都较大.
* 如果需要修改结构变量数据,要传地址或引用,而传值是不能修改变量数据的.
* 如果要返回函数的一个局部变量的值,用return返回,不必考虑变量数据的大小.虽然有复制的开销,但不能返回局部变量的指针或引用,不过,可以返回用new申请内存的指针.
* 如果不需要改变所传递的参数或函数的返回结果,可以用const修饰形参(当形参为引用或指针时)或用const修饰返回类型.
例如:
double addsalary(double x)
{
x=x+x*0.05;
return x;
}
main()
{
……
first_employee.salary=addsalary(first_employee.salary);
……
}
第三节 结构数组
在1节我们已经知道,结构可以定义为数组,结构数组的初始化也与其它数组的初始化方法类似.下面 以1节中定义的结构Rectangle为例,说明结构数组初始化的方法.
Rectangle r[3] = {{0, 0, 10, 10}, {10, 5, 10, 10}, {20, 20, 15, 10}};
我们也可以用结构变量初始化结构数组元素,例如:
Rectangle r[3];
Rectangle temp = {0, 0, 0};
for(int i = 0; i<3; i++)
r[i] = t;
但是,下面的初始化是错误的:
Rectangle temp = {0, 0, 0};
Rectangle r[3] = {t, t, t};
定义数组r时,也可以不指定数组元素的个数:
Rectangle r[ ] = {{…}, {…}, {…}};
编译器根据给出的初值的个数来确定数组元素的个数.
例:
#include <iostream.h>
const int MAXIMUM_NAME_LENGTH = 50;
const int NUMBER_OF_EMPLOYEES = 10;
typedef char name_string[MAXIMUM_NAME_LENGTH];
struct employee
{
name_string name;
int age;
double salary;
};
void input_details(employee& this_employee);
void display(employee this_employee);
int main()
{
employee employee_list[NUMBER_OF_EMPLOYEES];
int count;
for (count = 0 ; count < NUMBER_OF_EMPLOYEES ; count++)
{
cout << "EMPLOYEE NUMBER " << (count +1) << ":\n";
input_details(employee_list[count]);
cout << endl;
}
for (count = 0 ; count < NUMBER_OF_EMPLOYEES ; count++)
display(employee_list[count]);
return 0;
}
void input_details(employee& this_employee)
{
cout << "Please enter the employee's last name: ";
cin >> this_employee.name;
cout << "Please enter the employee's age: ";
cin >> this_employee.age;
cout << "Please enter the employee's current salary: ";
cin >> this_employee.salary;
}
void display(employee this_employee)
{
cout << this_employee.name << " has age " << this_employee.age;
cout << " and salary " << this_employee.salary << ".\n";
}
从给出的程序可以看出:对结构数组的操作实际上是对每个数组元素进行操作,即对每个结构变量进行赋值和引用.需要注意的是:不能把一个结构数组元素整体进行输入输出,而相同结构类型的数组元素和变量之间可以相互赋值.
第四节 指向结构的指针
在上一节里,我们定义了结构数组.实际上,我们常常要为结构动态地分配内存,这就需要指向结构类型变量的指针,定义指向结构类型变量指针的方法与定义其它类型(如int型、float型)变量指针的方法类似.我们知道:结构类型变量访问其成员要用"﹒"运算符,而结构类型指针访问结构成员要用"->"运算符,它的语法为:
指针变量->成员名
下面举一个例子加以说明
#include <iostream.h>
#include <string.h>
struct Person_Info {
char name[10];
int age;
long ssn;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -