资源描述
目 录
1 题目内容及设计规定 1
2 总体设计 1
2.1 总体功能框图 1
2.2 类设计阐明 1
2.3 重要算法流程图 1
3 程序清单及注释 1
4 运营成果与分析 1
5 总结 2
6 参照文献 2
1 题目内容及设计规定
题目17 复数计算器
内容及规定:
(1)所设计复数计算器可以进行+ - * += -= *= ++ -- >= <= == !=运算符,其中
>= <=是针对复数模进行运算。
(2)设计输入重载函数,规定能接受从键盘输入a+bi形式复数,在程序中可以辨认
出实部虚部并对的赋值。
(3) 设计计算器测试程序,对加减法进行测试,规定在两位数以内进行,对乘法进行测
试,乘法规定为一位数运算。
(4) 设计记录功能,可以记录下不同顾客使用计算器状况,记录以文献形式保存在
计算机内,开机时规定顾客输入顾客名,显示该名户此前记录。顾客记录取涉及:做了多
少次加减法、乘法、进行测试次数,后3次测试平均分等,在退出计算器程序时专心
顾客记录代替原有记录。
2 总体设计
2.1 总体功能框图
依照题中任务功能,一方面要弄清复数运算法则,
并使用c++语言表达。复数包括实部与虚部,如何将这两某些表达出来也使核心
定义一种复数类complex。
声明所需成员函数和友元函数对各运算符进行重载。
定义各成员函数。
定义主函数,实现对整个程序控制。
编译、运营并调试
2.2 类设计阐明
class CComplex //定义命名空间NameCComplex
{
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); //加法赋值重载
CComplex operator-=(CComplex &com); //减法赋值重载
CComplex operator*=(CComplex &com); //乘法赋值重载
CComplex operator++(); //自加
CComplex operator--(); //自减
double mod (void); //求复数模
int operator>(CComplex &com);
int operator<(CComplex &com);
int operator!=(CComplex &com);
int operator==(CComplex &com);
};
2.3 重要算法流程图
开始
声明一种complex类,并定义double,real,image;
声明类函数,构造函数,加减乘除和取模运算
c.real=real+c2.real;c.imag=imag+c2.imag;
c.real=real-c2.real;c.imag=imag-c2.imag;
c.real=(real*c2.real+imag*c2.imag)/a;c.imag=(imag*c2.real-real*c2.imag)/a
c.real=real*c2.real-imag*c2.imag;c.imag=real*c2.imag+imag*c2.real;
Sqrt(real*real=imag*imag);
输出c1,c2,c1+c2,c1-c2,c1*c2,c1/c2,∣c1∣值
终结
。。。。。。
图2-1 算法流程图
3 程序清单及注释
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <ctime>
//#define EPS len-5 // 定义精度常数
using namespace std;
namespace NameCComplex // 定义命名空间 NameCComplex
{
/*-----------------------------------------------------------------------
|某些A:
| 复数类 CComplex 声明和定义,以及构造体类型 顾客 User 定义
|
----------------------------------------------------------------------*/
/*---------------------------------
| 复数类 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); // 加法赋值重载
CComplex operator -= (CComplex & com); // 减法赋值重载
CComplex operator *= (CComplex & com); // 乘法赋值重载
CComplex operator ++ (); // 自加
CComplex operator -- (); // 自减
double mod(void);
int operator > (CComplex & com);
int operator < (CComplex & com);
int operator != (CComplex & com);
int operator == (CComplex & com);
};
/*------------------------------------
| 构造体类型 顾客 User 定义
-----------------------------------*/
struct User
{
char szName[20]; // 顾客名
int nTime; // 使用次数
int nTest; // 测试次数
double dlAve; // 平均成绩
int nAdd; // 加法次数
int nSub; // 减法次数
int nMul; // 乘法次数
double dlScore[3]; // 3次测试得分
} user;
/*---------------------------------------------------------------
| 复数类 CComplex 类外定义某些
---------------------------------------------------------------*/
// 重载运算符“++”,实部与虚部均加 1
CComplex CComplex::operator ++ ()
{
Real++;
Image++;
return *this;
}
// 重载运算符“--”,实部与虚部均减 1
CComplex CComplex::operator -- ()
{
Real--;
Image--;
return *this;
}
// 求复数模,返回 实部^2 + 虚部^2
double CComplex::mod()
{
return Real * Real + Image * Image;
}
// 重载运算符“>”,比较模大小
int CComplex::operator > (CComplex & com)
{
if ( mod() > com.mod() )
return 1; // 若大,则返回 1
else
return 0;
}
// 重载运算符“<”,比较模大小
int CComplex::operator < (CComplex & com)
{
if ( mod() < com.mod() )
return 1; // 若小,则返回 1
else
return 0;
}
// 重载运算符“!=”,分别判断复数实部与虚部
int CComplex::operator != (CComplex & com)
{
if ( *this==com )
return 0;
else
return 1;
}
// 重载复数输入, a+bi 形式
istream & operator >> (istream & is,CComplex & com)
{
cout << "输入复数:";
char s[80];
is >> s; // 用字符串形式接受复数
int len = strlen(s); // 求出字符串长度
int n = 0,sign = 1; // 其中 n 值 为当前从字符串中提取出数字,会在下面 while 语句中得到拟定值
// sign 为状态变量,表达数值正负符号,以辅助辨认正负值
com.Image = com.Real = 0;
// 判断接受字符串与否合法
for(int k=0;k<len;k++)
{
if ( (s[k]<'0' || s[k]>'9') && (s[k]!='+' && s[k]!='-' && s[k]!='i') )
{
cout << "error" << endl;
return is; // 错误,输出出错信息并返回
}
}
// 顺序辨认字符串中各字符
for(int k=0;k<len;)
{
if ( n!=0 && (s[k]=='--' || s[k]=='+') ) // 当前字符与否为符号位
{
com.Real = sign * n; // 是符号位,且 n!=0,即 n 已被赋值(通过下面whlie语句),表白当前读取是虚部符号
n = 0; // 将原 n*sign 值(带正负号数值)赋给实部后,将 n 清零,准备下一次继续接受并判断与否为虚部值
}
if ( s[k] == '-') // 当前字符若为负号
{
sign = -1; k++; // 给符号标志变量 sign 赋值,表达为负数
}
if ( s[k] == '+') // 当前字符若为正号
{
sign = 1; k++; // 给符号标志变量 sign 赋值,表达为正数
}
if ( s[k]=='i' ) // 若当前字符为“i”
{
if ( k!=len-1 ) // 判断字符 'i' 与否为字符串中最后一种字符
cout << "error\n"; // 如果不是,阐明复数数据格式错误
else
com.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',表达复数对象内只有实部,没有虚部,如:-a
com.Real = n * sign;
return is;
}
// 重载复数输出
ostream & operator << (ostream & os,CComplex & com)
{
if ( fabs(com.Image)==0 ) // 如果虚部为 0
os << com.Real; // 只输出实部
else if ( fabs(com.Real)==0 ) // 如果实部为 0
os << com.Image << "i"; // 只输出虚部
else if ( com.Image>0 )
os << com.Real << "+" << com.Image << "i"; // 虚部为正
else
os << com.Real << com.Image << "i"; // 如 实部为 3,虚部为 -6i,就变为 3 - 6i,而不是 3 + -6i
return os;
}
// 加法重载
CComplex CComplex::operator + (CComplex & com)
{
CComplex sum;
sum.Real = Real + com.Real; // 实部相加
sum.Image = Image + com.Image; // 虚部相加
return sum;
}
// 乘法重载
CComplex CComplex::operator * (CComplex & com)
{
CComplex multi;
multi.Real = Real * com.Real - Image * com.Image; // 乘积实部
multi.Image = Real * com.Image + Image * com.Real; // 乘积虚部
return multi;
}
// 减法重载
CComplex CComplex::operator - (CComplex & com)
{
CComplex sub;
sub.Real = Real - com.Real; // 实部相减
sub.Image = Image - com.Image; // 虚部相减
return sub;
}
// 加法赋值重载
CComplex CComplex::operator += (CComplex & com)
{
Real = Real + com.Real; // 实部
Image = Image + com.Image; // 虚部
return *this;
}
// 减法赋值重载
CComplex CComplex::operator -= (CComplex & com)
{
Real = Real - com.Real; // 实部
Image = Image - com.Image; // 虚部
return *this;
}
// 乘法赋值重载
CComplex CComplex::operator *= (CComplex & com)
{
double nReal = Real * com.Real - Image * com.Image; // 乘积实部
double nImage = Real * com.Image - Image * com.Real; // 乘积虚部
Real = nReal;
Image = nImage;
return *this;
}
// 重载 == 运算符,分别比较两个复数对象实部和虚部
int CComplex::operator == (CComplex & com)
{
if ( Real==com.Real && Image==com.Image )
return 1; // 实部与虚部某些相等,则返回 1
else
return 0;
}
/*----------------------------------------------------------------------------
|某些B:
| 测试函数 void Test(void)
| 实现复数加法函数 void Add()
| 实现复数减法函数 void Sub()
| 实现复数乘法函数 void Mul()
| 实现复数自加函数 void Add1()
| 比较两个复数大小函数 void Compare()
| 输出本次顾客使用计算器状况记录 void userprint()
| 当前顾客使用完计算器,保存或更新顾客资料函数 void SaveFile()
|
----------------------------------------------------------------------------*/
// 测试函数,随机出 10 道运算题,可以打分
void Test(void)
{
user.nTest++; // 顾客测试次数加 1
cout << "共10道题,作10以内加减运算,满分 100分:\n";
double real1,real2,image1,image2,real3,real4,image3,image4; // 1 和 2 分别代表两个待相加复数实部和虚部,3 和 4 则为相乘
CComplex answer,temp;
int score = 0;
char op;
for(int i=0;i<=9;i++)
{
real1 = rand()%200 - 100; // 产生随机数是两位数,可以是正数或负数
image1 = rand()%200 - 100;
real2 = rand()%200 - 100;
image2 = rand()%200 - 100;
CComplex a(real1,image1),b(real2,image2); // 用产生随机数对象分别初始化两个复数对象
real3 = rand()%20 - 10; // 产生随机数是一位数,可以是正数或负数
image3 = rand()%20 - 10;
real4 = rand()%20 - 10;
image4 = rand()%20 - 10;
CComplex c(real3,image3),d(real4,image4);
op = rand()%3; // 随机产生 3 种运算符
switch(op)
{
case 0:
answer = a + b;
cout << a << "加上" << b << "等于";
break;
case 1:
answer = a - b;
cout << a << "减去" << b << "等于";
break;
case 2: // 乘法运算,用实部和虚部都是 1 位数对象操作
answer = c * d;
cout << c << "乘以" << d << "等于";
break;
}
cin >> temp; // 接受顾客输入成果
if ( answer==temp ) score+=10; // 对的则加 10分
else
{
cout << "此题做错了\n";
cout << "对的答案为:" << answer << endl;
}
}
cout << "你最后得分是:" << score << endl;
// 计算最后 3次平均分
if ( user.nTest<=3 ) // 若合计次数没有超过 3次
{
user.dlAve = 0;
user.dlScore[user.nTest-1] = score; // 将本次测试成绩添加进记录中
for(int i=0;i<user.nTest;i++)
user.dlAve += user.dlScore[i]; // 若此前有记录,将其与本次记录合计相加起来,用以计算平均分
user.dlAve = user.dlAve / user.nTest; // 计算平均分,user.dlAve 从合计分数 变成了平均分
}
else // 如果合计测试超过 3次
{
user.dlScore[0] = user.dlScore[1]; // 最前面一次记录将被覆盖,即:删除
user.dlScore[1] = user.dlScore[2];
user.dlScore[2] = score; // 将本次记录添加进测试记录尾部
user.dlAve=0;
for(int i=0;i<3;i++) // 计算最新 3次平均分
user.dlAve += user.dlScore[i];
user.dlAve = user.dlAve / 3;
}
cout << "按任意键继续\n";
cout .flush();
cin.get();
cin.get();
}
// 实现复数加法
void Add()
{
user.nAdd++;
CComplex num1,num2,sum,Zero(0,0);
cout << "加法计算\n" << "至少输入两个复数,输入“0”结束\n";
cout << "第1个复数:";
cin >> num1; // 输入第 1个复数
cout << "第2个复数:";
cin >> num2; // 输入第 2个复数
sum = num1 + num2;
cout << "第3个复数:";
cin >> num1; // 输入第 3个复数
int i = 4;
while ( !(num1==Zero) )
{
sum = sum + num1; // 实现复数相加
cout << "第" << i << "个复数:";
cin >> num1; // 输入第 i个复数
i++;
}
cout << "成果是:" << sum << endl;
cout << "按任意键继续\n";
cout.flush();
cin.get();
cin.get();
}
// 实现复数减法
void Sub()
{
user.nSub++;
CComplex num1,num2,sub,Zero(0,0);
cout << "减法计算\n" << "至少输入两个复数,输入“0”结束\n";
cout << "第1个复数:";
cin >> num1; // 输入第 1个复数
cout << "第2个复数:";
cin >> num2; // 输入第 2个复数
sub = num1 - num2;
cout << "第3个复数:";
cin >> num1; // 输入第 3个复数
int i = 4;
while ( !(num1==Zero) )
{
sub = sub - num1; // 实现复数减法
cout << "第" << i << "个复数:";
cin >> num1; // 输入第 i个复数
i++;
}
cout << "成果是:" << sub << endl;
cout << "按任意键继续\n";
cin.get();
cin.get();
}
// 实现复数乘法
void Mul()
{
user.nMul++;
CComplex num1,num2,mul,Zero(0,0);
cout << "乘法计算\n" << "至少输入两个复数,输入“0”结束\n";
cout << "第1个复数:";
cin >> num1; // 输入第 1个复数
cout << "第2个复数:";
cin >> num2; // 输入第 2个复数
mul = num1 + num2;
cout << "第3个复数:";
cin >> num1; // 输入第 3个复数
int i = 4;
while ( !(num1==Zero) )
{
mul *= num1; // 实现复数减法
cout << "第" << i << "个复数:";
i++;
cin >> num1; // 输入第 i个复数
}
cout << "成果是:" << mul << endl;
cout << "按任意键继续\n";
cin.get();
cin.get();
}
// 实现复数自加,实部与虚部均自加 1
void Add1()
{
user.nAdd++; // 顾客加法记录次数加 1
CComplex num1;
cin >> num1; // 这里 输入数也许是虚部为0数,原书代码未作判断
num1++; // 实部与虚某些别加 1
cout << "自加成果为" << num1 << endl;
cout << "按任意键继续\n";
cout.flush();
cin.get();
cin.get();
}
// 实现复数自减
void Sub1()
{
user.nSub++; // 顾客减法记录次数加 1
CComplex num1;
cin >> num1;
num1--;
cout << "自减成果为" << num1 << endl;
cout << "按任意键继续\n";
cout.flush();
cin.get();
cin.get();
}
// 比较两个复数大小
void Compare()
{
CComplex num1,num2;
cout << "输入两个复数\n";
cout << "第1个复数:";
cin >> num1;
cout << "第2个复数:";
cin >> num2;
if ( num1==num2 )
cout << " 这两个复数相等\n";
else if ( num1>num2 )
cout << num1 << "模不不大于" << num2 << "模\n";
else if ( num1<num2 )
cout << num2 << "模不不大于" << num1 << "模\n";
else
cout << "这两个复数模相等\n";
cout << "按任意键继续\n";
cin.get();
cin.get();
}
// 输出本次顾客使用计算器状况记录
void userprint()
{
cout << user.szName << "使用次数为:" << user.nTime << "次" << endl;
cout << "其中:\t 加法次数:" << user.nAdd << "次\n"
<< "\t 减法次数:" << user.nSub << "次\n"
<< "\t 乘法次数:" << user.nMul << "次\n"
<< "\t 测试次数:" << user.nTest << "次\n"
<< "\t 平均成绩:" << user.dlAve << "次" << endl;
}
// 顾客登陆,开始启动计算器
void Login()
{
char szName[20];
cout << "请输入您姓名:";
cin.getline(szName,20);
ifstream infile;
User user1;
infile.open("user.dat",ios::binary|ios::in); // 打开顾客资料文献 (这个地方 若没有文献,则不会创立新文献,不知何问题
if ( !infile ) // 若没有顾客资料文献
{
cout << "没有原始记录文献, 您是第 1位顾客!\n";
strcpy(user.szName,szName); // 为全局变量 user 中 szName 成员赋值
user.nTime++;
return; // 函数返回
}
// 读取顾客资料文献(从该文献第1个字节开始逐个读取信息)
// 如果顾客资料中找到了当前姓名顾客,则阐明是老顾客,显示某些信息,并作某些使用次数记录。
infile.read( (char *)&user1,sizeof(User) );
while ( !infile.eof() ) // 只要没到文献末尾(未遇文献结束符),则始终进行此循环
{
if ( strcmp(user.szName,szName)==0 ) // 将顾客资料文献中顾客名与读取顾客名进行比较
{
user
展开阅读全文