资源描述
学号:201100834418 班级:软件114 姓名:赵阳阳
C++课程设计报告
一、 课程设计的报告及要求
1、 设计目的:
软件工程专业所开设的C++课程设计是教学实践环节中一项重要内容,进行此课程设计的旨在:
*提高和加强学生的计算机应用与软件开发能力,使学生由初学者向专业的程序员过渡。
*培养学生独立分析问题、解决问题、查阅资料以及自学能力,以适应计算机产业日新月异发展的形势。
*学习和掌握C++程序设计方法以及上机调试技巧,为今后学习其它专业课程打好基础。
本次课程设计是以学生独立思考解决问题为主,教师指导为辅,结合上机操作,完成指定的任务,作出设计报告。
2、 设计要求
1》基础题目:
(1)封装字符串:
l 定义一个串类CMyString,建立适当的构造函数
l 字符串使用指针保存字符串
l 必须实现如下操作,字符串比较、求串的长度、判断串是否为空、将串置空、字 符串赋值(包括两个字符串类复制,一个字符串赋值到CmyString对象)、求字符串中的一个字符或改变字符串中的一个字符(采用重载[]),完成串的赋值与合并(重载+),得到表示字符串的指针地址矚慫润厲钐瘗睞枥庑赖。
(2)链表 操作 :利用C++中的类实现线性链表的常见操作
l 带表头结点(存放的是该线性链表的长度),结点存放的是整型数值;
l 实现以下操作 :
n 置空MakeEmpty()
n 求长度Length()
n 插入Insert(int x,int i): 将x插入到第i个结点(不含头结点)的之后;
n 删除Delete(int x):删除链表中值为x的结点,成功返回1,否则返回0;
n 删除 ReMove(int i):删除链表中第i个结点,成功返回1,否则返回0;
n 搜索 Find(int x):在链表中查找数值为x的结点,成功返回1,否则返回0;
n 显示 Display():显示整个链表各结点的数值。
l 写出类的构造函数、复制构造函数及析构函数
编写一个函数,使用户通过选择进行相关链表操作。
2》编写一个银行ATM自动取款机模拟程序
要求:实现ATM取款机的基本功能,如给用户提供查询余额、取款、修改密码、吃卡、退出系统等服务,可根据实际情况添加(如缴费、转账等服务)。 聞創沟燴鐺險爱氇谴净。
l 对于用户要求输入相应的帐号和密码,如果三次出错则将卡吃掉并打印出相应凭条。
l 若输入的取款金额超出账户余额,则提示用户输入有误并提供更正功能
二、课程设计的具体实现
1》基础题目
(1)封装字符串:
A。总体设计:下表给出类图,以概要给出设计方案,采用C++类实现。
CMyString类
- str :char*;
+CMyString();
+CMyString(char *substr);
+CMyString(const CMyString & p) /
+ Comstr(CMyString &substr);int
+Length(); int
+IsEmpty();char*
+MakeEmpty();void
+Copy(CMyString substr); void
+Copy(char *substr); void
+operator[](int i); char &
friend operator+(const CMyString &str, const CMyString &substr); CMyString //
+perator=(const CMyString & p); CMyString &
+Transtr(int i,char ch); void
+GetAdd();char **
~CMyString();
+Display();void
B。详细设计:
a.构造函数:CMyString(); CMyString(char *substr);CMyString(const CMyString & p)完成字符串的函数的初始化,分别为三种,即无参数、有一个参数、用一个已有对象初始化。现在详细列出复制构造数代码:残骛楼諍锩瀨濟溆塹籟。
/////////////////////////////////////////////////////////////////////////////////////酽锕极額閉镇桧猪訣锥。
CMyString::CMyString(const CMyString & p)//拷贝构造函数
{
str=new char[strlen(p.str)+1];
strcpy(str,p.str);
cout<<"拷贝构造函数被执行"<<endl;
}
////////////////////////////////////////////////////////////////////////////////////////彈贸摄尔霁毙攬砖卤庑。
b. 比较两个字符串:int Comstr(CMyString &substr);.本函数适用对已初
始化过的两个字符串对象来比较。其中参数是对另一个字符串对象
引用,返回值分别是1,-1,0;分别代表str>substr,str<substr,str=substr 謀荞抟箧飆鐸怼类蒋薔。
c. 求长度:int Length(); 返回值是字符串的长度(单位:字节)
d. 判断是否为空及置空功能:
char* IsEmpty();//判断字符串是否空。返回是“空”,或是“非空”。
void MakeEmpty(); //将字符串置空
e. 复制功能的实现:分为两种复制:Copy(CMyString substr); void //将一个字符串类赋值给另一个对象;void Copy(char *substr); //将一个字符串赋值给一个对象;厦礴恳蹒骈時盡继價骚。
///////////////////////////////////////////////////////////////////////////茕桢广鳓鯡选块网羈泪。
void CMyString::Copy(char *substr) //复制字符串
{ str=new char[strlen(substr)+1]; //动态分配内存,防止内存不够鹅娅尽損鹌惨歷茏鴛賴。
strcpy(str,substr);
}
void CMyString::Copy(CMyString substr)//复制对象
{ str=new char[strlen(substr.str)+1];
strcpy(str,substr.str);
}
////////////////////////////////////////////////////////////////////////////// 籟丛妈羥为贍偾蛏练淨。
f. 查找及修改字符:
查找某个字符,采用重载下标运算符的方式char & operator[](int i); //将对象中的第i个字符替换为ch,并返回ch.;預頌圣鉉儐歲龈讶骅籴。
void Transtr(int i,char ch); //将第i个字符换为ch
g.串值合并赋值操作:
friend CMyString operator+(const CMyString &str, const CMyString &substr); //通过对两个对象的引用,实现两个字符串的合并,并返回合并后的对象。渗釤呛俨匀谔鱉调硯錦。
CMyString perator=(const CMyString & p); &o//重载=,实现字符串的赋值铙誅卧泻噦圣骋贶頂廡。
/////////////////////////////////////////////////////////////////////////////////// 擁締凤袜备訊顎轮烂蔷。
CMyString operator+(const CMyString & str, const CMyString & substr)//串值合并赋值操作贓熱俣阃歲匱阊邺镓騷。
{ char *p;
p=new char[strlen(str.str)+strlen(substr.str)+1];
strcpy(p,str.str);
strcat(p,substr.str);
CMyString result(p); //重新定义一个对象来返回
return result; }
h..得到字符串的指针地址:char ** GetAdd();
析构函数~CMyString(); 功能是回收内存
输出函数void Display(); 功能是输出字符串的指针地址。
C》调试及问题解决:
字符串的调试问题主要是内存的动态分配。当一个较长的字符串赋值给另一
短的字符串,出现内存不够用,并出现乱码现象。调试程序解决此类的问题时需
注意内存的分配。
(2)链 表 操 作:
1》总体设计:
现给出类体中的成员函数的定义和变量来概括链表功能实现
List 类
-head: Node*
+list();//构造函数
+list(list &n);
+~list();
+MakeList();void
+Length();int
+Insert(int x,int i); int
+ Delete(int x); int
+ ReMove(int i); int
+ Find(int x); int
+ Display();void
+ MakeEmpty();void
};下面详细介绍各个函数的功能
2》详细设计:
a.构造函数:在构造函数中,主要是以链表的头指针操作来实现链表的初始化。
有两个函数。
list();//构造函数
list(list &n); //复制构造函数
b.析构函数:其功能是通过删除头指针来实现的
c. 创建链表: void MakeList();通过每创建一个节点,输入一个数据,来创建链表。
主要代码是:
void list::MakeList() //创建链表
{
Node *tail,*p;
int n=0;
int da;
cout<<"请输入整型数据(0为结束标志)[请不要建立空表,即开始数据不能输入0!]:"<<endl;坛摶乡囂忏蒌鍥铃氈淚。
cin>>da;
while(da!=0)
{ n++;
if(n==1){head =new Node; tail=head; head->data=da; }////先创建头节点,切记蜡變黲癟報伥铉锚鈰赘。
else { p=new Node;p->data=da;tail->next=p;tail=p; }買鲷鴯譖昙膚遙闫撷凄。
cin>>da;
}
tail->next=NULL; 尾节点赋值为NULL,标志链表结束
}
d.链表长度:int Length(); 通过每找到一个节点,数值增加1,直到节点指针为NULL,返回链表的指针节点的个数与sizeof(int)的乘积。綾镝鯛駕櫬鹕踪韦辚糴。
e. 插入节点: int Insert(int x,int i);函数用来实现插入操作,即在第I 个节点后插入一个数值为X的节点,成功则返回1,否则返回0;驅踬髏彦浃绥譎饴憂锦。
int list::Insert(int x,int i)//在第i个节点后插入X值
{ bool flag=false; int j=1; Node*p,*q; p=head;
while(p->next!=NULL){
if(j==i) { q=new Node; q->next=p->next; q->data=x;猫虿驢绘燈鮒诛髅貺庑。
p->next=q; flag=true; }
j++; p=p->next;
if(i==j&&p->next==NULL)
{ q=new Node;q->next=NULL; q->data=x;p->next=q; flag=true; break; }锹籁饗迳琐筆襖鸥娅薔。
if(flag==true) break;
}
if(flag==true){ return 1;}
else return 0;
}
代码解释:定义一个节点,首先判断所要插入的节点是在哪个位置,并保存其尾指针,然后将新建的节点的头指针赋值尾指针。将尾指针赋值给新尾指针。構氽頑黉碩饨荠龈话骛。
注意。
f. 删除某个结点数值:int Delete(int x);该函数功能是用来删除链表某个为X的值,若存在并删除则为成功,返回1,否则返回0;輒峄陽檉簖疖網儂號泶。
int list::Delete(int x) //删除某个值为X的节点
{ bool flag=false; Node*p,*q; p=head;
while(head->data==x){ head=p->next; flag=true; }
///判断头节点是否含有值X,若有则将尾指针赋值给头指针
//继续判断头节点是否含有值X,若有执行上操作,否则循环停止
for(q=head;q->next!=NULL;)
{ if(q->next->data==x) { p=q->next; q->next=p->next; flag=true; }尧侧閆繭絳闕绚勵蜆贅。
else q=q->next;
if(p->next==NULL) break;//
}
if(flag!=false) return 1;
else return 0;
}
g.删除某个节点:int ReMove(int i);函数是用来删除第i个节点。即将所删除节点的尾指针赋值给上一节点的尾指针即可。识饒鎂錕缢灩筧嚌俨淒。
h.查找某个值:int Find(int x); 函数在链表中查找数值为X的节点,如果存在返回1,否则返回0.功能需要遍历链表。凍鈹鋨劳臘锴痫婦胫籴。
i.链表的显示和置空: void Display(); //显示链表的数值
void MakeEmpty(); //将链表置空
(3)银行ATM自动取款机模拟程序:
1. ATM系统需求描述:
ATM机的对象主要是合法的存款用户,来方便用户取款,以及实现查询余额,修改密码,吃卡,退出功能,并且其存在一个安全机制。即连续三次输入错误,则实现锁定本卡。恥諤銪灭萦欢煬鞏鹜錦。
现将功能描述为下:
(1) 查询余额:用户选择“查询余额”功能,来查询用户当前的用户余额
(2) 取款功能:用户选择取款功能 ,输入取款金额,若,输入金额大于账户余额, 则提示用户输入有误并提供更正,及重新输入。鯊腎鑰诎褳鉀沩懼統庫。
(3) 修改密码:用户可以选择修改密码功能,来改变卡的密码
(4) 退出系统:用户可能选择退出系统,并将卡退出。
(5) 吃卡功能:
(6) 缴费功能:用户可以选择缴费功能,来实现账户的充值
(7) 转账功能:用户可以选择转账功能 ,并输入另一个用户账号,来实现对另一个账号的充值。
2. ATM自动取款机系统需求模型
本项目采用面向对象分析作为主要的系统建模方法,使用UML建模语言,从几个角度对系统建立模型。系统的需求模型主要包含用例图和用用例规约。硕癘鄴颃诌攆檸攜驤蔹。
1> 系统总体用例图如下图所示。
本系统针对用户而言,介绍了用户的简单基本操作及其相关功能。用户在登录成功的情况下,可选择实现查询余额,修改密码,取款,缴费,转账及退出系统等操作。阌擻輳嬪諫迁择楨秘騖。
2> ATM自动取款机系统用例规约
(1) 登录功能
用户是本系统内注册的合法用户,,每次进入系统需要进行身份验证,其用例规约如下表所示:
表3.1 登录功能用例规约
用例编号:
UC-01
用例名称:
登录功能
用例描述:
用户输入账号和密码,正确后进入系统
参与者:
用户
前置条件:
身份验证合格
后置条件:
基本路径:
1. 根据提示用户输入账号
2. 若账号存在,则进行下一步操作,否则进行1
3. 根据提示用户输入密码
4. 密码正确,进入系统,否则继续进行3
业务规则:
用户密码三次输入错误,则吃卡,并打出相关凭据
非功能需求:
系统判断用户账号是否存在
补充说明:
(2) 查询余额:
登录成功的用户可以进行查询余额操作。
表UC-02 查询余额功能用例规约
用例编号:
UC-02
用例名称:
查询余额
用例描述:
用户登录成功后实现查询余额功能
参与者:
用户
前置条件:
用户登录成功
后置条件:
查询余额成功
基本路径:
用户登录后,选择查询余额操作
业务规则:
非功能需求:
补充说明:
(3) 取款功能
用户登录成功后,可以进行取款。
表UC-03取款用例规约
用例编号:
UC-03
用例名称:
取款
用例描述:
实现取款操作
参与者:
用户
前置条件:
用户登录成功
后置条件:
取款成功
基本路径:
1. 用户登录成功,选择取款操作
2. 根据提示输入取款金额
3. 系统判断取款金额是否符合要求
4. 符合则取款成功,否则提示用户重新输入
业务规则:
用户需要输入正确的金额
非功能需求:
系统每次保存用户的信息到文件中
补充说明:
(4) 修改密码
表UC-04 修改密码功能用例规约
用例编号:
UC-04
用例名称:
修改密码
用例描述:
用户选择可进行密码的修改操作
参与者:
用户
前置条件:
用户登录成功
后置条件:
修改密码成功
基本路径:
1. 用户登录成功,选择修改密码操作
2. 提示输入新的密码
3. 判断密码是否符合要求
4. 符合则修改密码成功,否则提示用户重新输入
业务规则:
新密码必须符合要求
非功能需求:
补充说明:
(5) 缴费功能
用户登录成功后,可以选择进行存款功能 ,来实现账户的充值缴费功能
表UC-05 缴费功能用例规约
用例编号:
UC-05
用例名称:
缴费
用例描述:
用户可以选择进行充值
参与者:
用户
前置条件:
用户登录成功
后置条件:
充值成功
基本路径:
1. 用户登录成功后,选择存款
2. 根据提示用户输入缴费金额
3. 提示用户缴费成功
业务规则:
非功能需求:
补充说明:
(6) 转账功能
用记可以向其他账户转账,来实现汇款功能。
表UC-01 转账功能用例规约
用例编号:
UC-06
用例名称:
转账
用例描述:
用户向其他的账户转账
参与者:
用户
前置条件:
用户登录成功
后置条件:
转账成功
基本路径:
1. 选择转账功能
2. 系统提示用户输入转账账号
3. 判断账号是否存在
4. 存在则转账,否则重新输入
5. 提示输入转入金额
6. 判断转入金额是否符合要求
7. 符合则转账,否则重新输入
业务规则:
所输入账号和金额要符合要求
非功能需求:
补充说明:
(7) 退出系统
用户不想继续进行操作,可选择退出操作。
表UC-07 退出系统功能用例规约
用例编号:
UC-07
用例名称:
退出系统
用例描述:
不进行操作,选择退出
参与者:
用户
前置条件:
用户登录成功
后置条件:
退出系统成功
基本路径:
选择退出系统操作,退出成功
业务规则:
非功能需求:
补充说明:
4. ATM自动取款机的系统设计
1> 分析类:用户的信息包括用户的账号,密码,账户金额,功能包括查询余额,修改密码,取款,转账,缴费,退出系统。氬嚕躑竄贸恳彈瀘颔澩。
2> 顺序图:参照系统总体用例图。
3> 设计类图
通过参看系统总体用例图,可以得到用户类的相关信息,现将类图表求如下:
CAtm
-User:int
-Password:int
-Money:int
+GetBalance() : void
+ChangePassword() : void
+DrawMoney() : void
+TransferAccounts() :void
+BankSaving () :void
+Exit() : void
+Login() :int
4> 系统结构设计
设计系统的结构架构:
ATM自动取款机系统实现:,请详看后面代码!!!
三、课程设计总结:
首先在这里,感谢王海龙王老师陪我们度过这三个星期的课程设计,并帮助我们解决编程中的许多问题,在这里表示致谢!!!。釷鹆資贏車贖孙滅獅赘。
其次,感谢身边的同学们,在课后,给予的编程帮助!!!
然后,致谢校方提供我们良好的编程环境和上机教室以及机房老师的努力工作,在这里表示感谢。
最后个人编程总结:只有不断地去努力学习和上机编程,还有不懂要问的态度,对自己的编程能力肯定会有一定的提高。怂阐譜鯪迳導嘯畫長凉。
在此祝愿每个编程人员都能编出高质量的程序!!!
四、源代码:
字符串
///// CMyString.h文件 ////////
class CMyString
{
private:
char *str;
public:
CMyString();
CMyString(char *substr); //构造函数
CMyString(const CMyString & p); //拷贝构造函数
int Comstr(CMyString &substr); //比较两个函数
int Length(); //求字符串的长度
char* IsEmpty(); //判断字符串是否空
void MakeEmpty(); //将字符串置空
void Copy(CMyString &substr); //将一个字符串类赋值给另一个对象
void Copy(char *substr); //将一个字符串赋值给一个对象
char & operator[](int i); //将对象中的某个字符替换为ch
friend CMyString operator+(const CMyString &str,const CMyString &substr); //实现两个字符串的合并与赋值谚辞調担鈧谄动禪泻類。
void Display();
CMyString &operator=(const CMyString & p);//重载[],实现字符串的赋值嘰觐詿缧铴嗫偽純铪锩。
void Transtr(int i,char ch); //将第i个字符换为ch
~CMyString(); //析构函数
char **GetAdd(); //得到指针的地址
};
///////// MyString.cpp 文件 ////////
#include<iostream.h>
#include<string.h>
#include"CMyString.h"
CMyString::CMyString(){ str=NULL;cout<<"无参数构造函数被执行"<<endl; } //构造函数熒绐譏钲鏌觶鷹緇機库。
CMyString::CMyString(char *substr) //含一个参数的构造函数鶼渍螻偉阅劍鲰腎邏蘞。
{
str=new char[strlen(substr)+1];
strcpy(str,substr);
cout<<"含一个参数的构造函数被执行"<<endl;
}
CMyString::CMyString(const CMyString & p)//拷贝构造函数
{
str=new char[strlen(p.str)+1];
strcpy(str,p.str);
cout<<"拷贝构造函数被执行"<<endl;
}
CMyString::~CMyString() //析构函数
{ if(str!=NULL) delete []str;
str=NULL;
cout<<"析构函数被执行"<<endl;
}
int CMyString::Comstr(CMyString &substr)//比较两个字符串
{
return strcmp(str,substr.str);
}
int CMyString::Length() //求字符串的长度
{
return strlen(str);
}
char* CMyString:: IsEmpty() //判断字符串是否为空
{
if(str!=NULL) {return "非空";}
else return "空";
}
void CMyString::MakeEmpty() //将一个字符串置空
{
if(str!=NULL) delete[]str;
str=NULL;
// cout<<"置空成功"<<endl;
}
void CMyString::Copy(CMyString substr)//复制对象
{ str=new char[strlen(substr.str)+1];
strcpy(str,substr.str);
}
void CMyString::Copy(char *substr) //复制字符串
{ str=new char[strlen(substr)+1];
strcpy(str,substr);
}
void CMyString::Display() //输出字符串
{
cout<<str<<endl;
}
CMyString operator+(const CMyString & str,
const CMyString & substr)//串值合并赋值操作
{
char *p;
p=new char[strlen(str.str)+strlen(substr.str)+1];
strcpy(p,str.str);
strcat(p,substr.str);
CMyString result(p);
return result;
}
CMyString &CMyString::operator =(const CMyString &p)纣忧蔣氳頑莶驅藥悯骛。
{
if(str!=NULL) delete []str;
str=new char[strlen(p.str)+1];
strcpy(str,p.str);
return *this;
}
char & CMyString::operator[](int i)//重载下标运算符,查找字符
{
return *(str+i-1);
}
void CMyString::Transtr(int i,char ch)//改变字符
{
*(str+i-1)=ch;
}
char **CMyString::GetAdd()//得到字符指针
{
return &str;
}
///////// main.cpp ///////////
#include<iostream.h>
#include<string.h>
#include"CMyString.h"
int main()
{
CMyString str1("ZhongYuangGongXueYuan"),str2("JiSuanJiXueYuan"),str3; //定义字符串对象并初始化颖刍莖蛺饽亿顿裊赔泷。
cout<<"字符串str1:";str1.Display();
cout<<"字符串str2:";str2.Display();
cout<<"比较操作:";
if(str1.Comstr(str2)>0) { cout<<"str1大于str2"<<endl;} //比较两个字符串濫驂膽閉驟羥闈詔寢賻。
else if(str1.Comstr(str2)<0) {cout<<"str1小于str2"<<endl;}銚銻縵哜鳗鸿锓謎諏涼。
else if(str1.Comstr(str2)==0) { cout<<"两个字符串相等"<<endl;}挤貼綬电麥结鈺贖哓类。
cout<<"复制操作(将You are clever复制给str1):"<<endl;
str1.Copy("You are clever!");//将You are clever复制给str1赔荊紳谘侖驟辽輩袜錈。
str1.Display();
str1.Copy(str2);//将字符串对象str2复制给str1
str1.Display();
cout<<"str1字符串:";str1.Display();
cout<<"串值合并赋值操作:"<<endl; //将str1和str2合并并赋值给str3塤礙籟馐决穩賽釙冊庫。
str3=str1+str2;
cout<<"str3字符串:";str3.Display();
cout<<"str3的指针地址"<<str3.GetAdd()<<endl;//得到表示字符串的指针地址裊樣祕廬廂颤谚鍘羋蔺。
cout<<"str3的字符串长度:"<<str3.Length()<<endl;//字符串长度
cout<<"查找第2个字符:";cout<<str3[2]<<endl;//重载[]
cout<<"改变字符:"<<endl;
cout<<"改变前:";str3.Display();
str3.Transtr(2,'A'); //将第2个字符改为A仓嫗盤紲嘱珑詁鍬齊驁。
cout<<"改变后:";str3.Display();
str3.MakeEmpty(); //字符串置空
cout<<"str3字符串"<<str3.IsEmpty()<<endl;//判断字符串是否为空
return 0;
}
链表操作:
//////// Clist.h 文件////////
#include<iostream.h>
struct Node
{
int data;
Node *next;
};
class list
{
private:
Node*head;
public:
list(){head=NULL;}//构造函数
list(list &n); //复制构造函数
~list(); //析构函数
void MakeEmpty(); //将链表置空
int Length(); //求链表的长度
int Insert(int x,int i);//插入节点
int Delete(int x);//删除某个结点数值
int ReMove(int i);//删除某个节点
int Find(int x); //在链表中查找数值为X的节点
void Display(); //显示链表的数值
void MakeList();
};
///////// list.cpp /
展开阅读全文