1.1. 实验内容
定义一个学生信息结构体(或类)
定义一个学生类,能够增加学生、删除学生、查找学生
编写测试代码,验证学生类编写是否正确
其中操作符重载=
1.2. 实验目的
理解指针的定义
理解类的结构
1.3. 预备知识
内存:计算机存储硬件。为了区别内存的不同位置,内存被分成字节,内存的全部字节顺序地赋予一个称为地址的编号。因此,内存地址是物理的,计算机设计好就给定了。
变量:在内存中占据一定的内存字节,在这些字节中存储的数据信息称为变量的内容。因此,通过变量就可以操作内存,也就是说要操作某块内存,就必须先将这块内存的首地址和一个变量名绑定起来。换句话说,当我们声明一个变量后,就意味着我们申请使用一块特定大小的内存,用于存储我们的数据。
指针变量:在变量中,有一类变量比较特殊,其形式为int *ptr。其特殊性是指该变量不是直接存储数据,而是存储内存地址。因此,通过该变量,我们可以得到另外一个内存空间所存储的信息。
数组:由于变量所申请的内存空间是非常有限的,很多情况下,我们需要更大的空间,例如存储字符串”C++ is difficult but interesting”。如果采用一系列char变量,则需要数10个变量。这种情况显然不是我们所希望看到的。这时候,我们就可以采用数组非常方便地完成字符组的存储:char str[] = ”C++ is difficult but interesting”。
动态分配:数组虽然可以申请更大的内存空间,但是其存在一个基本缺点是需要事先指定内存大小。但是,在很多情况下,我们无法知道需要分配内存的大小。例如,我们需要设计一个读取图像的程序。但是,不同图像的宽带和高度显然是不一样的,因此,需要的内存大小也不一样。因此,我们需要根据图像宽带和高度动态分配内存大小。在这种情况下,数组是无能为力的。而在C++中,采用new操作符来完成动态内存分配。
1.4. 技术难点
C++如何管理内存
内存和指针的关系
删除一个学生时,需要改变两个学生之间的指针位置关系
1.5. 参考思路
对于该问题,注意到这是一个学生信息动态管理的问题,涉及到学生的增加和删除。因此,需要考虑采用动态数组。其基本思路是:
1)首先把学生信息定义成一个结构体,这个结构体包含两部分信息:一部分是学生信息的基本数据,另外一部分是另外一个学生的存在位置(指针)。因此,形成如下的学生信息结构类:
struct StudentData //学生信息结构类
{
int StudentID;
unsigned char StudentName[256];
StudentData *NextDataAddress;
};
2)在结构体基础上,构造一个学生类,把学生信息和相关操作关联起来。其抽象数据类型如下:
class Student
{
private:
StudentData* m_StudentList;
public:
Student();
~Student();
public:
Student & operator=(const Student &s1);
public:
StudentData* FindStudentByID(int StuID); //查找一个学生
AddStudent(StudentData NewStudent); //增加一个学生
DeleteStudentByID(int StuID); //删除学生
StudentData* GetStudentList(); //得到当前学生信息的首地址
InsertStudent(StudentData* ParentAddress, StudentData NewStudent); //插入一个学生
int GetStudentCount( ); //得到学生总数
/*
显示学生名称中包含字符串subStr的结果。如果subStr为空,则显示所有学生
*/
DisplayStudentInfo((char *subStr);
UpdateStudentInfo(StudentData* pPtr, StudentData newData); //更新学生信息
ExportToFile(char *file); //导出学生信息到文件中,每行包含学生姓名和学号
DeleteRepeatedStudent( ); //删除学号重复的学生
}
显然,对于上述类,初始化是需要使m_StudentList=NULL,表明当前没有任何一个学生。增加一个学生操作部分代码如下:
StudentData* NewStudentData = new StudentData;
memcpy(NewStudentData, &NewStudent , sizeof(StudentData));
NewStudentData-> NextDataAddress = NULL; //这是最后一个学生
m_StudentList = NewStudentData;
1.6. 有用资料
1.6.1. 程序设计知识点
为了区别内存的不同位置,内存被分成字节,内存的全部字节顺序地赋予一个称为地址的编号。程序中的变量将在内存中占据一定的内存字节,在这些字节中存储的数据信息称为变量的内容。一个变量占用连续的若干个内存字节时,最前面的一个字节的地址就作为该变量的地址。指针就是内存地址,是变量的地址,或函数的入口地址。变量的地址在程序执行时,起着非常重要的作用。当计算机在计算含有变量的表达式时,计算机按变量的地址取出其内容,并按变量的地址将计算结果存入到变量占据的内存中。如代码:
int x=l;
x=x+2;
其中语句“x=x+2;”中的第一个x涉及到变量x占据的内存,第二个 x是引用变量 x的内容。该语句的意义是“取X的内容,完成加上2的计算,并将计算结果存入变量X占据的内存中。”(http://itpx.eol.cn/ks_dagang_7867/20100414/t20100414_465553.shtml)
1.6.2. C++程序设计从零开始之指针
在C++中是通过变量来对内存进行访问的,但根据前面的说明,C++中只能通过变量来操作内存,也就是说要操作某块内存,就必须先将这块内存的首地址和一个变量名绑定起来,这是很糟糕的。比如有100块内存用以记录100个工人的工资,现在要将每个工人的工资增加5%,为了知道各个工人增加了后的工资为多少,就定义一个变量float a1;,用其记录第1个工人的工资,然后执行语句a1 += a1 * 0.05f;,则a1里就是增加后的工资。由于是100个工人,所以就必须有100个变量,分别记录100个工资。因此上面的赋值语句就需要有100条,每条仅仅变量名不一样。
上面需要手工重复书写变量定义语句float a1;100遍(每次变一个变量名),无谓的工作。因此想到一次向操作系统申请100*4=400个字节的连续内存,那么要给第i个工人修改工资,只需从首地址开始加上4*i个字节就行了(因为float占用4个字节)。
为了提供这个功能,C++提出了一种类型——数组。数组即一组数字,其中的各个数字称作相应数组的元素,各元素的大小一定相等(因为数组中的元素是靠固定的偏移来标识的),即数组表示一组相同类型的数字,其在内存中一定是连续存放的。在定义变量时,要表示某个变量是数组类型时,在变量名的后面加上方括号,在方括号中指明欲申请的数组元素个数,以分号结束。因此上面的记录100个工资的变量,即可如下定义成数组类型的变量: float a[100];
上面定义了一个变量a,分配了100*4=400个字节的连续内存(因为一个float元素占用4个字节),然后将其首地址和变量名a相绑定。而变量a的类型就被称作具有100个float类型元素的数组。即将如下解释变量a所对应内存中的内容(类型就是如何解释内存的内容):a所对应的地址标识的内存是一块连续内存的首地址,这块连续内存的大小刚好能容纳下100个float类型的数字。
11 个解决方案
#1
把你的试验的作业贴出来了??唉。以前的帖子上有一个和你的一摸一样的,你搜一下吧,如果那个不是你的话
#2
文档好详细,只剩下填代码的工作了。。
#3
好好编码,
#4
好像没啥难点
#5
需求分析很详细。
#6
又是作业啊,如今的学生怎么了?
#7
不是作业,我一个女同学不会做来问我,我也不是很懂就来请教大家了啊
#8
ing
#9
泡妞用的吧,哈
#10
#11
那更要两个人一起慢慢做。
#1
把你的试验的作业贴出来了??唉。以前的帖子上有一个和你的一摸一样的,你搜一下吧,如果那个不是你的话
#2
文档好详细,只剩下填代码的工作了。。
#3
好好编码,
#4
好像没啥难点
#5
需求分析很详细。
#6
又是作业啊,如今的学生怎么了?
#7
不是作业,我一个女同学不会做来问我,我也不是很懂就来请教大家了啊
#8
ing
#9
泡妞用的吧,哈
#10
#11
那更要两个人一起慢慢做。