C++实习报告

更新时间:2024-03-06 22:29:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

计算机高级语言(C++)实习报告

题 目

学生姓名: 班 学 号: 指导老师:

中国地质大学(武汉)机械与电子信息学院

2014 年 4 月

实验一、成绩管理系统 Grade Management System

一、 需求规格说明

1、 设计三个结构体:学生类(存储学生的基本信息,如学生姓名Stu_Name、学生学号

Stu_ID、且包含结构体嵌套,嵌入Course,Score,采用结构体);课程科目Course(存储科目名称采用结构体);分数Score (储存各科成绩,采用结构体)。 2、 实现功能:

a、计算平均值Avg:包括每门课程的平均值,和每个学生所有课程的平均值。 b、计算最高分Max:包括每门课程的最高分,和学生平均分的最高分,并给出最高分对应的学生姓名和学号。

c、计算最低分Min:包括每门课程的最低分,和学生平均分的最低分,并给出最低分对应的学生姓名和学号。

d、计算每门课程成绩不及格(<60分)以及优秀(大于90分)的学生个数Count。 e、计算每门课程的标准方差Variance。

f、查询功能Query:可以根据输入的学生姓名或者学号,查询该学生的所有课程的成绩。

g、排序功能Sort:按照从高到低的顺序,对每门课程的成绩进行排序,对学生平均分进行排序,并给出排序后成绩所对应的学生姓名和学号。 3、需求分析:

a、能对学生按学生姓名,学号和各科成绩进行录入:。 b、能按学号和姓名查询学生信息。

c、能统计学生所有课程的平均分并排序,统计各科成绩的最高分和最低分,优秀和不及格人数,各科成绩的平均分和方差。 4、系统性能要求: a、系统安全、可靠; b、功能齐全;

c、操作方便、界面友好; d、易于维护和扩充。 5、系统的功能分析:

资料维护:系统维护包括对学生信息的录入操作及数据表中的信息进行浏览。 系统功能:可以对数据表中的信息进行浏览。 系统查询:可以对学生的信息进行查询。 6、系统功能模块 学生成绩查询系统有:学生成绩信息输入模块,数据统计模块,查询模块,排序显示构成。

提示:

把初始化部分和7个功能设置为可以选择的菜单方式,也就是每次运行程序,可以让用户选择实现某个功能,各个功能用函数来实现。

每个功能的输出可以输出到屏幕,也可以输出到文件。

二、 算法设计

(1)设计思想:该学生成绩管理系统用结构体student作为基本数据结构,其中数组保 存学生信息数据。以switch...case...语句进入功能选择界面,用户可以根据需要连接其中的模块。

(2)设计表示:主菜单函数包含八个功能函数,其分别为:初始化输入学生数据功能(input)、计算平均分(Avg)、计算最高分(Max)、计算最低分(Min)、计算及格及优秀(Guake_count)人数、计算标准方差(Fangcha_count)、查询(chaxun)功能、排序功能(paixu)。为实现以上几个函数还必须使用辅助函数,他们分别为:选择函数(choice) 清行函数(new_line)初始化输入函数(input1)。

(3)详细设计表示: 主函数 计算 排序 查询 计算 及格人数计算 计算计算 最低分 优秀人数 方差 平均值 最高分 三、调试报告

(1)用于保存学生基本信息的文本文档打开失败(未经初始化)。 (2)个人认为可以将最大值和最小值归于一个模块,可以改进。 (3)使用结构体时未定义成员变量就使用,运行出错。 (4)程序编写时漏写分号、花括号、圆点等。

(5)计算最大值,最小值模块时,错误的将待比较的书与最大值或最小值直接进行大小比 较而忽略了其类型为double类型,最后通过比较两者之间的差值是否小于0.000001一个较小的数,从而成功的比较了两个double类型数大小是否相等,虽然此方法结果不是十分精确,但已经完全能满足本题目的要求。

(6)通过采用从键盘读入一个数据来判断执行具体哪个功能时,忽略了每次键盘输入时遗留的换行符,从而产生了一些错误,最终通过编写一个清行函数new_line成功的解决了这个问题。

(7)采用for循环语句读入数据时,错误的多读入或少读入一个数据,从而造成逻辑错误,解决方法是将实际运行结果与理想结果分析比较,检查源程序具体的实现部分语句从而发现错误并改正。

实验二、MyString类定义和应用

一、需求规格说明

定义一个类MyString,其对象是字符串。该类包含两个成员变量,一个是指向一个容纳字符串的动态数组的指针变量,另一个是该动态数组的长度(也就是所包含的字符的个数)。

1、 定义3个构造函数,第一个是默认构造函数,使得对象为空字符串,字符串长度为0;第二个接收一个C字符串作为参数,使得对象初始化为该参数的值;第四个是复制构造函数,接收MyString类型的对象为参数。

2、定义析构函数,将对象占用的内存返回给自由存储。 3、定义两个重载的赋值=操作符(定义为成员函数),一个可以将一个C字符串赋值给当前调用对象,一个可以将另外一个MyString类型的字符串赋值给当前调用对象。

4、定义两个重载的等号==操作符(可以用友元函数实现,也可以用成员函数实现),一个用来判断MyString类型字符串是否等于一个C字符串,另外一个用来判断两个MyString类型的字符串是否相等。

5、定义两个重载的加号+操作符(可以用友元函数实现,也可以用成员函数实现),一个用来将MyString类型对象和C字符串相连接,一个用来连接两个MyString类型对象。注意连接的两个字符串之间加一个空格。

6、定义大于(>)和小于(<)操作符,用来比较两个MyString类型的字符串(可以用友元函数实现,也可以用成员函数)。

7、定义输入操作符(>>)和输出操作符(<<),用来将MyString类型的字符串输入和输出(只能用友元函数实现)。并且,选择合适的流参数,使得既可以从键盘输入,也可以从文件输入,既可以输出到屏幕,也可以输出到文件。

8、定义成员函数length(),用来得到MyString类型字符串的长度。

9、定义成员函数c_str(),用来将MyString类型的字符串转变为C字符串。

10、定义成员函数input_line(),用来输入一行MyString类型的字符串。既可以从键盘输入,也可以从文件输入。

11、定义成员函数substr(),用来得到并返回MyString类型调用对象的一个子字符串,该子字符串开始于调用对象的某位置position,长度是length(包含length个字符)。

12、定义成员函数find(),返回某一个字符串在调用对象中首次出现的位置。 要求:

1、使用三个文件:类的接口文件;类的实现文件;应用程序文件。 2、给自己定义的类创建一个命名空间。

3、main部分中,要对类中的成员函数和友元函数进行使用和测试。

二、算法设计<五号宋体加粗>

1、设计思想:定义一个MyString类,其对象是字符串。参照string类的功能。

2、设计表示: 构造函数,析构函数,重载赋值=操作符,重载等号==操作符。重载加号+操作符,大于(>)操作符,小于(<)操作符,输入操作符(>>),输出操作符(<<),成员函数length(),成员函数c_str(),成员函数input_line,成员函数substr(),成员函数find()。

3、详细设计表示:按照课本上类的成员函数,一个一个往下写

三、调试报告

在调试的过程中,编译器一直报错,友元函数无法使用类的私有变量。通过网上搜索解决方案,刚开始使用命名空间的using声明解决,但编写到最后几个子函数时又出现了新的问题,这主要是由于C++6.0对友元函数的一些BUG所致,最后通过询问老师,最终在网上下载了VS2008编译器,从而完美的解决了该问题。

四、用户手册

三、 附录

测试数据为:依次从键盘输入“hanyiting”和“tangshengqin”字符串。

源程序如下:

一 类的接口文件:

#include #include #include using namespace std; #ifndef MYSTRING_H #define MYSTRING_H class MyString {

public: MyString(); MyString(char s[]); MyString(const MyString& mystring); ~MyString(); //析构函数 int length()const; char* c_str() const; //将MyString类型的字符串转变为C字符串 void input_line(std::istream & ins); //输入一行MyString类型的字符串。既可以从键盘输入,也可以从文件输入

MyString substr(int position,int length); //得到并返回MyString类型调用对象的一个子字符串,该子字符串开始于调用对象的某位置position,长度是length

void operator =(const char right_side[ ]); void operator =(const MyString& right_side);

int find(const MyString& mystring); friend bool operator ==(const MyString& myString, const char right_side[ ]); //用来判断MyString类型字符串是否等于一个C字符串

friend bool operator ==(const MyString& myString_1,const MyString& myString_2); //用来判断两个MyString类型的字符串是否相等 //例如可以这样使用:if (s1= =\或者if (s1= =s2)

friend MyString operator +(const MyString& myString_1,const char string2[ ]); //用来将MyString类型对象和C字符串相连接

friend MyString operator +(const MyString& myString_1,const MyString& myString_2); //用来连接两个MyString类型对象 例如s3=s1+s2; s3=s1+\

friend bool operator <( MyString& string1, MyString& string2) ; //例如if (s1>s2); if (s1

friend bool operator >( MyString& string1, MyString& string2); friend std::istream& operator >>(std::istream& ins ,MyString &myString); friend std::ostream& operator <<(std::ostream& outs ,const MyString &myString);

private: char *value; int size; };

#endif

二 类的实现文件

#include //类的实现文件 #include #include #include%using namespace std;

MyString::MyString() //默认构造函数一 { value=new char[1]; value[0]='\\0'; size=0; }

MyString::MyString(char s[]) //默认构造函数二 { int n,i; n=strlen(s); size=n; value= new char[n+1];

for(i=0;i

MyString::MyString(const MyString& mystring) //默认构造函数三 { int i; size=mystring.size ; value= new char[size+1]; for(i=0;i

MyString::~MyString() { delete [] value; }

int MyString::length()const //返回MyString类对象所指的字符串的长度 { return size; }

char* MyString::c_str() const { return value; }

void MyString::input_line(std::istream & ins) //输入一行MyString类型的字符串。既可以从键盘输入,也可以从文件输入

{ char next; char a[100]; //临时用来存放输入的字符 int i=0,j; ins.get(next); while(next!='\\n') //输入字符到数组a中 { a[i]=next; i++; ins.get(next); }

size=i; //长度为i

delete [] value; //释放以前的内存单元 value= new char[i+1]; for(j=0;j

value[j]='\\0'; }

MyString MyString::substr(int position,int length) { MyString temp; temp.size=length;

delete [] temp.value;

temp.value= new char[length+1]; if((position+length)>size) { cout<<\ exit(1); } int j=0; for(int i=position;i<(position+length);i++) { temp.value[j]=value[i]; j++; }

return temp; }

void MyString::operator =(const char right_side[ ]) { int i,length=strlen(right_side); size=length; value=new char[size+1]; for(i=0;i

void MyString::operator =(const MyString& right_side) {

int i; size=right_side.size ; value=new char[size+1]; for(i=0;i

bool operator ==(const MyString& myString, const char right_side[ ]) { int i; bool jieguo; if(myString.size!=strlen(right_side)) jieguo=0; else for(i=0;i

bool operator ==(const MyString& myString_1,const MyString& myString_2) { int i; bool jieguo; if(myString_1.size !=myString_2.size ) jieguo=0; else for(i=0;i

jieguo=1; } return jieguo; }

MyString operator +(const MyString& myString_1,const char string2[ ]) //将一个MyString类对象和C字符串相连

{ MyString temp; int i,j=0; temp.size =myString_1.size +strlen(string2)+1; temp.value =new char[temp.size+1]; for(i=0;i

MyString operator +(const MyString& myString_1,const MyString& myString_2) 个MyString类对象相连

{ MyString temp; int i,j=0; temp.size =myString_1.size +myString_2.size+1; temp.value =new char[temp.size+1]; for(i=0;i

//将两

bool operator <( MyString& string1, MyString& string2) //重载<操作符 { int n; if(string1.size>string2.size) n=string2.size; else n=string1.size; for(int i=0;istring2.value[i]) //阿斯克码与字母顺序相反 return 1; else if(string1.value[i]

bool operator >( MyString& string1, MyString& string2) //重载>操作符 { int n; if(string1.size>string2.size) n=string2.size; else n=string1.size; for(int i=0;istring2.value[i]) return 0; } return 0; }

istream& operator >>(istream& ins ,MyString& myString) { char next; char a[100]; //临时用来存放输入的字符 int i=0,j; ins.get(next); while(next!='\\n') //输入字符到数组a中 {

a[i]=next; i++; ins.get(next); }

myString.size=i; //长度为i

delete [] myString.value; //释放以前的内存单元 myString.value= new char[i+1]; for(j=0;j

ostream& operator <<(ostream& outs ,const MyString& myString) { int i; for(i=0;i

int MyString::find(const MyString& mystring) {

int size_n=mystring.size; int flag=0,j; for(int i=0;i

for(j=flag;j

if(mystring.value[j-flag]==value[j]); else break; }

if(j==(flag+size_n)) return flag; else {

cout<<\ return 0; } }

三 类的执行文件(主函数部分): #include #include #include #include%using namespace std; int main() { //声明并初始化s1,s2,s3 MyString s1; //调用默认构造函数将s1初始化为空字符串,长度为. MyString s2(\调用带有一个c字符串参数的构造函数初始化s2为hello,长度为.

//s2=\调用重载的赋值操作符 cout<<\请输入一个长度小于的字符串:\ cin>>s1; //调用重载的>>操作符,例如s1=\ MyString s3(s1); //调用拷贝构造函数(用s1对s3初始化)

//输出s1,s2,s3的值,使用重载的输出<<操作符,以及使用成员函数length cout<<\ cout<<\ cout<<\ //连接s1和s2,并输出 s3=\连接C字符串\和MyString类型变量s1,s2。 cout<<\ //判断s1和s2大小,使用重载的==,>,<操作符 if (s1==s2) cout<<\ else if (s1>s2) cout<<\ else if (s2

//使用重载的==操作符,判断MyString类型字符串和一个C字符串是否相等 if (s1==\ cout<<\

//使用input_line和c_str函数 cout<<\请输入一个长度小于的一行字符串:\ s3.input_line(cin); //例如输入nice to meet you. cout<<\ char cs[100]; strcpy(cs,s3.c_str()); //将s3转变为C字符串,赋值给C字符串cs。

cout<<\ //使用substr函数 MyString s4; s4=s3.substr(5,2); //返回s3从index=处的子字符串,大小为.得到s4=\ s1=s3.substr(5,2);//返回s3从index=处的子字符串,大小为.得到s1=\ cout<<\ cout<<\ //使用find函数 int index=s3.find(s4); //找出s4(\)在s3(\)中首次出现的位置为.

cout<<\ return 0; }

实验总结:

学生成绩管理系统是个综合性强的程序设计题目,其涉及到了对文件的操

作,函数的重载,以及一些基本的程序设计技巧与操作。通过这个题目的练习,我学会了编写一个较大的程序的流程,即首先设计一个基本框架,包括一些基本的子函数,以及所涉及的类,头文件等。然后则是具体实现程序的每个功能了,为每一个子函数编写出具体的实现程序。最后,进入主函数的编写过程。由于要实现的功能比较多,所以说要编写一个菜单函数,通过键盘输入让用户选择具体实现哪一个功能。,

Mystring类的定义和实现涉及到类和对象,成员和友元,重载和动态数组等方方面面知识,要完成这个实验需要比较扎实地掌握前面所学知识,所以难度较大。编译过程中可以发现很多自己曾经忽略的问题,比如虚构函数的定义,动态数组的实现,字符串拷贝容量问题,以及二元操作符<<和>>的重载问题。 通过这次C++实习,不仅巩固了自己的C++知识,同时也让我领悟到了编程的魅力,最后感谢马丽老师上课时对我们的悉心教诲。

本文来源:https://www.bwwdw.com/article/qmra.html

Top