C++课程设计实验报告姓名学号班级合作者学号班级任课教师时间教师指定题目复数计算器评定难易级别 A级实验报告成绩复数计算器程序功能设计1.程序功能的总体结构复数计算器的程序总体功能可设计成如图1所示,可以看出,复数计算器的各种功能都用菜单选项列出,用户可以根据需要选择相应的菜单项,从而执行不同的子程序以完成相应的功能。
2.课程设计要求(1)一开始运行程序,要有详细的菜单选项界面,用户不选择退出就可以反复运算。
(2)可以进行多个操作数的复数运算,输入0+0*i时为止。
(3)编写可以对输入的复数求模的成员函数。
(4)编写具有测试功能的函数,即计算机能够自动出题,并要求用户计算,同时计算机判断用户计算的对错并打分,要求十题为一个单元,每题一个运算符,运算符包括+,-,*三种,参与加减运算实部虚部为一位数。
(5)重载输入输出运算符,对复数的输入既可采用实部虚部分开提示输入,也可直接输入诸如a+i*b或a+ib这种形式,对复数的输出要考虑实部虚部的正负号,通过判断给出的输出结果。
2.程序设计思想1)类的封装程序中将复数形式的数据定义成一个复数类CComplex,重载了加法及减法等运算符,使函数的加减等运算像一般数据一样方便.每个运算符重载都用一个函数去实现。
参考类的定义如下:class CComplex{private:double Real,Image;public:CComplex(double real=0,double image=0) //构造函数{Real=real;Image=image;}friend istream&operator>>(istream&is,CComplex&com); //重载输入friend ostream&operator<<(ostream&os,CComplex&com); //重载输出CComplex operator+(CComplex&com);CComplex operator-(CComplex&com); //减法重载CComplex operator*(CComplex&com); //乘法重载CComplex operator/(CComplex&com); //除法重载int operator==(CComplex&com);int operator!=(CComplex&com);int operator>(CComplex&com);int operator<(CComplex&com);float Module(void); //复数求模};(2)设计的任务要求1在实际应用中,输入复数可能为a+bi, a, bi, -a, -bi, +i. –i. I等形式。
重载输入运算符应该能识别这样形式多样的复数。
所以在重载输入函数时要综合考虑上述各种输入形式。
可行的处理方式是:在重载输入函数中,设计用(3)设计的任务要求2在程序中设计一个复数运算的测试函数Test(),其功能是让计算机随机出10道运算题,用户给出答案,同时计算机实时判断对错并可以打分。
这个函数的关键是让计算机随机产生复数对象和运算符,计算机内部有一个随机数发生器,可以产生一个固定顺序的整型随机数序列,调用语句为“int a = rand();”这时,a就是该随机数发生器产生的随机数。
由于产生的随机书数在整数范围内,为测试方便,按程序设计要求,产生的随机复数对象实部和虚部在100以内,运算符只有加减两种。
因此,需要对产生的随机数进行进一步的处理,用随机数模除以除以100,产生出100以内的随机整数;同样,用随机数模除以3,可以产生出0、1、3三个随机数据,定义0为加法,1为减法,2为乘法,这样就可以产生出随机的复数对象的加减乘运算了。
可以参见图2测试子程序Test()结构框图。
在程序中重载了>>运算符,其功能是让用户能够直接输入a+bi,a+b*i两种形式的复数,其结构框图如图3所示。
N YY N3. 程序界面开始界面将字符转变为数值NY‘i ’是否是最后一个字符 当前字符是否是数字输出错误信息,函数返回NN运行结果界面4.程序源代码及详细注解:# include<iostream.h># include<math.h># include<stdlib.h># include<string.h>#define Z 1e-6class CComplex{private:double Real,Image;public:CComplex(double real=0,double image=0) //构造函数{Real=real;Image=image;}friend istream&operator>>(istream&is,CComplex&com); //重载输入friend ostream&operator<<(ostream&os,CComplex&com); //重载输出CComplex operator+(CComplex&com);CComplex operator-(CComplex&com); //减法重载CComplex operator*(CComplex&com); //乘法重载CComplex operator/(CComplex&com); //除法重载int operator==(CComplex&com);int operator!=(CComplex&com);int operator>(CComplex&com);int operator<(CComplex&com);float Module(void); //复数求模};CComplex CComplex::operator +(CComplex&com) //加法重载{CComplex t; //定义类对象t.Real=Real+com.Real; //实部相加t.Image=Image+com.Image; //虚部相加return t;}CComplex CComplex::operator -(CComplex&com) //减法重载{CComplex t; //定义类对象t.Real=Real-com.Real; //实部相减t.Image=Image-com.Image; //虚部相减return t;}CComplex CComplex::operator*(CComplex&com) //乘法重载{CComplex t; //定义类对象t.Real=Real*com.Real-com.Image*Image; //乘法实部t.Image=Real*com.Image+Image*com.Real; //乘法虚部return t;}CComplex CComplex::operator/(CComplex &com) //除法重载{CComplex t; //定义类对象t.Real=(Real*com.Real+Image*com.Image)/(com.Real*com.Real+com.Image*c om.Image);//除法实部t.Image=(Image*com.Real-Real*com.Image)/(com.Real*com.Real+com.Image* com.Image);//除法虚部return t;}/*int CComplex:: operator!=(CComplex&com) //重载“!=”运算符,分别判断复数的实部与虚部{if(*this==com)return 0;elsereturn 1;}*/int CComplex:: operator>(CComplex&com) //重载“>”运算符,比较复数的模{if(Module()>com.Module())return 1; //大于,则返回1elsereturn 0;}int CComplex:: operator<(CComplex&com) //重载“<”运算符,比较复数的模{if(Module()<com.Module())return 1; //小于,则返回1elsereturn 0;}float CComplex::Module(){float t;t=sqrt(Real*Real+Image*Image);return t;// cin.get();// cin.get();}int CComplex::operator==(CComplex&com) //重载“==”运算符,分别判断两个复数对象的实部与虚部{if(Real==com.Real&&Image==com.Image)return 1; //实部与虚部分别相等返回1else return 0;}void Add(){CComplex a1,a2,sum,f(0,0);cout<<"加法计算"<<endl<<"最少输入两个复数,并以零结束"<<endl; cout<<"第一个复数"<<endl;cin>>a1;cout<<"第二个复数"<<endl;cin>>a2;sum=a1+a2;cout<<"第三个复数"<<endl;cin>>a1;int i=4;while(!(a1==f)){sum=sum+a1;cout<<"第"<<i<<"个复数"<<endl;cin>>a1;i++;}cout<<"结果"<<sum<<endl;cout<<"按任意键继续"<<endl;//cout.flush();cin.get();}void Sub(){CComplex a1,a2,sub,f(0,0);cout<<"减法计算"<<endl<<"最少输入两个复数,并以零结束"<<endl; cout<<"第一个复数"<<endl;cin>>a1;cout<<"第二个复数"<<endl;cin>>a2;sub=a1-a2;cout<<"第三个复数"<<endl;cin>>a1;int i=4;while(!(a1==f)){sub=sub-a1;cout<<"第"<<i<<"个复数"<<endl;cin>>a1;i++;}cout<<"结果:"<<sub<<endl;cout<<"按任意键继续"<<endl;//cout.flush();cin.get();}void Mul(){CComplex a1,a2,mul,f(0,0);cout<<"乘法计算"<<endl<<"最少输入两个复数,并以零结束"<<endl; cout<<"第一个复数"<<endl;cin>>a1;cout<<"第二个复数"<<endl;cin>>a2;mul=a1*a2;cout<<"第三个复数"<<endl;cin>>a1;int i=4;while(!(a1==f)){mul=mul*a1;cout<<"第"<<i<<"个复数"<<endl;cin>>a1;i++;}cout<<"结果:"<<mul<<endl;cout<<"按任意键继续"<<endl;//cout.flush();cin.get();}void Div(){CComplex a1,a2,div,f(0,0);cout<<"除法计算"<<endl<<"最少输入两个复数,并以零结束"<<endl; cout<<"第一个复数"<<endl;cin>>a1;cout<<"第二个复数"<<endl;cin>>a2;div=a1/a2;cout<<"第三个复数"<<endl;cin>>a1;int i=4;while(!(a1==f)){div=div/a1;cout<<"第"<<i<<"个复数"<<endl;cin>>a1;i++;}cout<<"结果:"<<div<<endl;cout<<"按任意键继续"<<endl;//cout.flush();cin.get();}void Compare(void){cout<<" 复数模比较"<<endl;CComplex a1,a2;cout<<"输入两个复数:"<<endl;cout<<"第一个复数:";cin>>a1;cout<<"第二个复数";cin>>a2;if(a1==a2)cout<<"这两个复数相等"<<endl;else if(a1>a2)cout<<a1<<"的模大于"<<a2<<"的模"<<endl;else if(a1<a2)cout<<a1<<"的模小于"<<a2<<"的模"<<endl;cout<<"按任意键继续"<<endl;cin.get();}istream& operator>>(istream&is,CComplex&com){ //重载输入,可以输入a+bi,也可以输入a+b*ichar s[100];is>>s; //字符串s用于接收复数int len=strlen(s);int n=0,sign=1; //n为当前从字符串中提取出来的数字,初始化为0;sign 为n的符号,初始化为正com.Image=com.Real=0;if(len==4){for(int k=0;k<len;k++) //判断字符串是否合法if((s[k]<'0'||s[k]>'9')&&(s[k]!='+'&&s[k]!='-'&&s[k]!='i')){cout<<"Error"<<endl; //若字符串不是1~9的数字或“+”、“-”、“=”则错误,输出Errorreturn is;}}for(k=0;k<len;) //依次识别字符串中和字符{if(n!=0&&(s[k]=='-'||s[k]=='+')) //判断是否为符号位{com.Real=sign*n; //是符号,且n!=0,n已被赋值,当前读取的是虚部的符号n=0; //将sign*n的值赋给实部,然后n清零,准备接受虚部的值}if(s[k]=='-'){sign=-1;k++; //给符号标志赋值}if(s[k]=='+'){sign=1;k++; //给符号标志赋值}if(s[k]=='i') //若当前字符为i{if(k!=len-1) //判断i是否为最后一个字符cout<<"error\n"; //若不是,则复数输入格式错误elsecom.Image=sign*n;//是最后一个字符,复数对象已接收完毕,用sign*n给虚部赋值break;}while(s[k]>='0'&&s[k]<='9') //当字符在0~9之间是,将数字字符转化为数字数值{n=n*10+s[k]-'0';k++;}if(s[len-1]!='i'&&n!=0) //如果最后一个字符不是i,表示复数只有实部,没有虚部com.Real=n*sign;return is;}else{for(int k=0;k<len;k++) //依次识别字符串中和字符{if((s[k]<'0'||s[k]>'9')&&(s[k]!='+'&&s[k]!='-'&&s[k]!='i'&&s[k]!='*')) //若字符串不是1~9的数字或“+”、“-”、“=”、“*”则错误,输出Error{cout<<"Error"<<endl;return is;}}for(k=0;k<len;) //依次识别字符串中和字符{if(n!=0&&(s[k]=='-'||s[k]=='+')) //判断是否为符号位{com.Real=sign*n;n=0;}if(s[k]=='-'){sign=-1;k++; //给符号标志赋值}if(s[k]=='+'){sign=1;k++; //给符号标志赋值}if(s[k]=='*') //若当前字符为*{k++;com.Image=sign*n;}if(s[k]=='i') //若当前字符为i{if(k!=len-1) //判断i是否为最后一个字符cout<<"error\n"; //若不是,则复数输入格式错误//else//com.Image=sign*n;break;}while(s[k]>='0'&&s[k]<='9') //当字符在0~9之间是,将数字字符转化为数字数值{n=n*10+s[k]-'0';k++;}}if(s[len-1]!='i'&&n!=0) //如果最后一个字符不是i,表示复数只有实部,没有虚部com.Real=n*sign;return is;}}ostream&operator<<(ostream&os,CComplex&com) //重载输出{if(fabs(com.Image)<Z) //如果虚部为零os<<com.Real; //只输出实部;else if((fabs(com.Real)<Z)) //如果实部为零os<<com.Image<<"i"; //只输出虚部else if(com.Image>0)os<<com.Real<<"+"<<com.Image<<"i"; //虚部为正,用“+”连接实部与虚部elseos<<com.Real<<com.Image<<"i"; //虚部为负,虚部的符号连接实部与虚部return os;}void Test(void){double real1,real2,real3,real4,image1,image2,image3,image4;CComplex answer,f5;int score=0;char op;for(int i=1;i<=10;i++){real1=rand()%200-100; //产生随机的两位数,可正可负image1=rand()%200-100;real2=rand()%200-100;image2=rand()%200-100;CComplex f1(real1,image1),f2(real2,image2);//用随机产生的两位数初始化类对象real3=rand()%20-10;//产生随机的一位数image3=rand()%20-10;real4=rand()%20-10;image4=rand()%20-10;CComplex f3(real3,image3),f4(real4,image4);//用随机产生的一位数初始化类对象op=rand()%3; //随即产生3种运算符cout<<"第"<<i<<"题:";switch(op){case 0:answer=f1+f2;cout<<f1<<"加上"<<f2<<"等于";break;case 1:answer=f1-f2;cout<<f1<<"减去"<<f2<<"等于";break;case 2: //乘法用实部、虚部都是一位的对象answer=f1*f2;cout<<f1<<"乘以"<<f2<<"等于";break;}cin>>f5;if(answer==f5){ //判断结果是否正确cout<<"此题做对了"<<'\n';cout<<"加十分:"<<'\n';score+=10;} //正确,加十分else{cout<<"此题做错了"<<'\n';cout<<"不得分:"<<'\n'; //错误,不得分}}cout<<"你的最后得分为:"<<score<<endl;}void main(void) //输出程序主菜单,并接收用户选择{char input;CComplex a,b,c,d,e,f,g;system("cls");cout<<"\t这是一个复数计算器程序,拥有以下功能,请按照菜单选择进入功能。