一、任务描述
实验1:工具与语法训练
在Visual C++ 6.0中新建一个控制台应用程序,在新生成的程序中输入如下含有错误的程序,其功能是计算 1+2+…+100,保存并进行调试,直到程序能够正常运行并输出正确的结果。
#include
int main(int argc, char* argv[])
{
int i, sum;
do
{
i++;
sum += i;
}while(i<=100)
cout << s << endl;
system(“pause”); //使程序暂停的函数调用语句
return 0;
}
#include
using namespace std;
int main()
{
cout<<"计算 1+2+…+100\n输出"<<endl;
int i;
int sum=0;
for(i=1;i<101;i++)
{
sum+=i;
}
cout<<sum<<endl;
system("pause");
return 0;
}
在Visual C++ 6.0中新建一个控制台应用程序,在其主函数中添加如下所示的代码,然后调试这段代码,说出程序执行之后变量iLastVlaue的值,并解释为什么是这个值。(提示:通过断点、跟踪、查看变量的值等方法)
int iLastVlaue = 0;
for (int i=0; i<2; i++)
{
printf(“i = %d\n”, i);
for (int j=0; j<5; j++)
{
printf(“j = %d\t”, j);
if (j>2)
{
break;
}
iLastVlaue = 4;
}
iLastVlaue = 5;
}
iLastVlaue = 6;
#include
#include
int main()
{
int iLastVlaue = 0;
for (int i=0; i<2; i++)
{
printf("i = %d\n", i);
for (int j=0; j<5; j++)
{
printf("j = %d\t", j);
if (j>2)
{
break;
}
iLastVlaue = 4;
}
iLastVlaue = 5;
}
iLastVlaue = 6;
return 0;
}
附件:Visual C++程序的调试过程
Visual C++ 允许程序进行调试,常见的调试指令与快捷键如下表所示:
表1 调试指令与快捷键表
快捷键 说明
F9 设置断点/取消断点
F5 继续运行
F10 单步,如果涉及到子函数,不进入子函数内部
F11 单步,如果涉及到子函数,进入子函数内部
CTRL+F10 运行到当前光标处。
Shift+F5 结束调试
详细介绍如下:
(1)改正程序的编译期错误
源程序编写完成后,首先由C++编译程序编译成.obj文件,再由连接程序连接成可执行文件。在编译时,如果源程序存在语法错误(errors),则系统不允许连接,直到改正了所有的语法错误后,才能进行连接。另外,编译时还可能存在另一类错误,即警告性错误(warnings),这类错误一般不影响程序的连接,在很多情况下也不影响程序的执行结果,但建议还是尽量把这类错误改正。
选择编译菜单(Compile)(或者直接单击快捷工具栏上的编译按钮)对编译好的源程序进行编译,在集成环境下方的OutPut窗口中将会显示相应的编译信息(若OutPut窗口没有出现,则可以在快捷工具栏上右键单击并在弹出的菜单中选择OutPut菜单项即可打开(或关闭)OutPut窗口。若程序编译没有发现错误,则该窗口中显示“***.exe - 0 error(s), 0 warning(s)”,这时可以进行程序的连接;若编译后存在语法错误或警告错误,该窗口中则显示两类错误的个数,并列出相应的错误位置和原因。
改正编译期错误的方法和一般原则为:
①改正错误时一般从第一个错误开始,然后依次改正后续的错误。因为前面错误的出现,往往会导致编译系统在编译时错位,把本来正确的语句认为是错的,也可能把某些语句的错误掩盖掉。所以当改正了前面的错误后,可能会使错误量减少很多,也可能增加很多;
②在OutPut窗口中双击指定错误,则系统会自动定位到该错误出现的位置,并在错误语句前面用一个蓝色子弹头标识。注意,该标识只是告诉程序员编译时在此位置出错了,真正的错误可能出现在该标识语句的前一语句或后一语句,如函数定义时,在小括号后加了分号,错误标识将出现在左大括号处;
③根据情况,每改正一个或几个错误后,应重新编译一下,然后再从第一个错误进行改错,直到所有错误都被改正过来。
(2)程序执行时的调试
实践中发现,往往很小的程序在执行时也会出现错误。当一个程序可以被连接成功,但执行时却存在不正常现象,如不能得到预期的运行结果或出现死机等,而一下子又很难找出出错原因时,可以采取以下方法查错、改错。
①单步跟踪执行命令
单步跟踪执行程序,能够清楚地看到程序的一步步执行过程,从而判断出源程序的执行流程是否与事先设计的流程一致,从中发现造成死循环或死机的原因所在。C++集成环境提供的单步跟踪命令有“Step Into”和“Step Over”两种,当选择这两个命令时,程序进入DEBUG(调试)状态,并在main函数的左大括号处出现一个黄色的子弹头标识,意味着程序从此处开始执行,以后每执行一次这两个命令之一,则程序执行一行,若程序每一行只有一个语句,则相当于一次执行了一个语句。这两个命令的区别如下:
“Step Into”:对应的快捷键为F11,在单步执行过程中,若当前执行的语句是函数调用语句,则执行一次该命令将会跟踪至被调用函数内部继续单步跟踪执行。
“Step Over”:对应的快捷键为F10,在单步执行过程中,若当前执行的语句是函数调用语句,也不会跟踪到被调用函数内部执行,而是直接把该函数调用作为一个语句一次执行完成,到当前函数的下一语句继续跟踪执行。
在具体操作时,这两种单步跟踪命令往往配合使用:一般先使用“Step Over”命令单步跟踪执行,当执行到某函数调用处时,如果需要跟踪至被调用函数内部,则再使用一次“Step Into”,然后继续使用“Step Over”命令。
②执行到光标所在行命令
该命令可以一次执行到鼠标光标所在的程序语句位置。
在进行程序的调试时,有时能够确认在某语句之前的所有语句都是正确的,如果对这些语句进行单步跟踪会增加不必要的调试时间,此时可以使用该命令,执行让程序执行到光标所在行,然后在配合单步跟踪,能够有效地提高调试的效率。
该命令对应的快捷键为:Ctrl+F10。
③设置断点命令
设置断点是另一种能够快速执行到程序指定行的方法:首先把光标停在需设置断点的位置,然后按F9(或工具栏上的“手形”按钮),则在指定行出现一个红色的实心圆,表示一个断点设置完毕。如果需要设置其它的断点,则重复以上步骤即可。断点设置完毕,按F5,则程序一次性执行到第一个断点所在位置,以后每按一次F5,程序将执行到下一断点,执行程序执行完毕。在执行过程中,也可以增加其它的断点。
在有断点的位置,再按一次F9(或工具栏上的“手形”按钮),则可以取消该断点的设置。
在编制的程序比较短,特别是只有一个源程序文件的情况下,单步跟踪和执行到光标所在行命令已经能够很好地完成调试任务。该命令在多文件组织的程序中能够有效地发挥其调试功能。
④观察程序执行过程中变量和表达式值的变化
在使用以上命令进行调试过程中,通过观察当前执行点相关变量或表达式的值,能够有效地发现错误出现的原因和位置。
在调试状态下,集成环境窗口下方会出现两个窗口(如果这两个窗口没有出现,可以在调试状态下右键单击工具栏空白处,在弹出的菜单中进行选择),如图1所示。
一个是变量(Variables)窗口,另一个是观察(Watch)窗口,前者实时地列出了当前执行点前后最近位置的变量的当前值。后者提供了4个观察子页面,可以在其中任何一个页面中输入想观察值的变量或表达式,然后观察其值。
该调试功能可以与以上的调试命令配合使用,以完成调试任务。程序调试完毕,或想取消程序的调试状态回到编辑状态,可以选择集成环境调试(Debug)菜单中的“Stop Debugging”命令或直接按“Shift+F5”快捷键,即能够达到目的。
实验2:类与对象(一)
最少数量要求:题1~题3选一;题4~题6选一。
设计一个三角形处理类,包含三条边长为数据成员,实现并测试这个类。类中包括的成员函数(要完成操作)有:
(1)构造函数;
(2)析构函数;
(3)判别是否构成三角形函数;
(4)是否构成直角三角形函数;
(5)计算面积函数。
#include
#include
using namespace std;
class Sanjiao //三角形类
{
private:
double x,y,z;
public:
Sanjiao (double a,double b,double c):x(a),y(b),z(c){
};
void shifouweisanjiaoxing();
void shifouweizhijiao();
~Sanjiao(){
}};
void Sanjiao::shifouweisanjiaoxing() //是否为三角形函数
{
if(x+y>z&&x+z>y&&y+z>x&&x>0&&y>0&&z>0)
{
cout<<"是否构成三角形"<<":"<<"是"<<endl;
double p=0,s;//计算并输出面积函数
p=x/2+y/2+z/2;
s=sqrt((p-x)*(p-y)*(p-z)*p); //海伦公式计算面积
cout<<"三角形面积为"<<":"<<s<<endl;
}
else
cout<<"是否构成三角形"<<":"<<"否"<<endl;
}
void Sanjiao::shifouweizhijiao() //是否为直角函数
{
if(x*x==y*y+z*z||y*y==x*x+z*z||z*z==x*x+y*y&&x>0&&y>0&&z>0) //勾股定理判断
cout<<"是否为直角三角形"<<":"<<"是"<<endl;
else
cout<<"是否为直角三角形"<<":"<<"否"<<endl;
}
int main() //主函数
{
double j,k,l;
cout<<endl;
cout<<" ._________________. "<<endl
<<" | _______________ | "<<endl
<<" | I I | "<<endl
<<" | I 三角计算器 I | "<<endl
<<" | I_____________I | "<<endl
<<" !_________________! "<<endl
<<endl;
cout<<"请输入三角形的三边长度" <<endl;
cin>>j>>k>>l;
Sanjiao t(j,k,l);
t.shifouweizhijiao();
t.shifouweisanjiaoxing();
return 0;
}
设计一个地址类Address,其中包括某人姓名、所居住的街道地址、城市和邮编等属性,实现并测试这个类。
类中包括的成员函数(要完成操作)有:
(1)构造函数;
(2)析构函数;
(3)ChangeName()成员函数,用于改变对象的姓名等属性
(4)Display()成员函数,用于显示姓名、街道地址、城市和邮编等属性。
#include
#include
using namespace std;
class Address
{
private:
char Name[30];
char StreetAddress[30];
char City[30];
char Postcode[30];
public:
Address(char*a,char*b,char*c,char*d)
{
strcpy(Name,a);
strcpy(StreetAddress,b);
strcpy(City,c);
strcpy(Postcode,d);
}
void Changename(char*a)
{
strcpy(Name,a);
}
void Display()
{
cout <<"姓名:"<<Name<<endl;
cout <<"街道地址:"<<StreetAddress<<endl;
cout <<"城市:"<<City<<endl;
cout <<"邮编:"<<Postcode<<endl;
}
};
int main()
{
char name[30];
char streetaddress[30];
char city[30];
char postcode[30];
cout<<"请输入信息:" <<endl;
cout<< "名字"<<endl;
cin>>name;
cout<<"街道地址"<<endl;
cin>>streetaddress;
cout<<"城市"<<endl;
cin>>city;
cout<<"邮编"<<endl;
cin>>postcode;
Address x(name,streetaddress,city,postcode);
x.Display();
cout<<"输入要更改的名字"<<endl;
cin>>name;
x.Changename(name);
x.Display();
return 0;
}
完善下面的产品类,该类用于管理产品的名称、单价和库存数量,能够根据用户输入的产品名称和购买数量计算相应的金额。在 main 函数中模拟几种商品(由键盘输入) ,并实现一个菜单式程序,演示用户任意购买各种商品的过程。
class product
{
char* tag; //产品名称
double price; //单价
int quantity; //库存数量
public:
//构造函数
//析构函数
//购买某种商品函数buy,返回false表示库存数量不够,否则更新库存数量,并计算费用
//属性相关函数,如库存调整、显示库存数量等
};
#include
#include
#include
using namespace std;
int i = 0;
class product
{
public:
string huo;
double price,shuliang;
void import();
void buy();
void display();
};
product p[50];
void product::import() //入库
{
cout << "请输入名称:" << endl;
cin >> huo;
cout << "请输入单价:" << endl;
cin >> price;
cout << "请输入存入数量:" << endl;
cin >> shuliang;
}
void product::buy() //购买
{
int x,y,n;
cout << "您想购买什么?" << endl;
for (x = 0; x <= i - 1; x++)
cout << x+1 << "~" << p[x].huo << endl;
cout<<" 选择 :" <<endl;
cin >> y;
y=y-1;
cout << "请输入您想购买的数量:"
<<endl
<<" 选择 :" <<endl;
cin >> n;
if (n <= p[y].shuliang)
{
cout << "您需支付的金额:" << n * p[y].price << endl;
p[y].shuliang -= n;
}
else
cout << "产品不足!" << endl;
}
void product::display() //查询
{
cout << "您想查询哪款产品信息?" <<endl
<<endl;
int x;
if (i == 0)
cout << "库中无产品" << endl;
else
for (x = 0; x <= i - 1; x++)
cout << x+1 << "~" << p[x].huo << endl;
int y;
cout<<" 选择 :" <<endl;
cin >> y;
y=y-1;
cout << "产品名称:" << p[y].huo << endl;
cout << "产品单价:" << p[y].price << endl;
cout << "产品当前数量:" << p[y].shuliang << endl;
}
int main()
{
while (1)
{
int a;
cout<<endl<<endl
<<" (1) 产品入库 "<<endl
<<" (2) 产品信息 "<<endl
<<" (3) 购买产品 "<<endl
<<endl
<<" 选择 :" <<endl;
cin >> a;
if (a == 1)
{
p[i].import();
i++;
system("cls");
}
if (a == 2)
{
p[0].display();
}
if (a == 3)
p[0].buy();
}
return 0;
}
队列是一种连续的存储结构,存入数据只能从一端(称为尾部)进入,取出数据则只能从另一端(头部)取出。根据下述描述实现一个自定义的队列类:
class Queue
{
public:
Queue (int size = 10); //构造函数
~Queue (); //析构函数
bool empty () const { return front == rear; } //队列是否为空
bool full() const; //队列是否已满
int size () const; //队列中元素的个数
void push (int); //插入一个元素
int pop (); //弹出一个元素
private:
int* data; //数据区
int front, rear; //首尾位置
int capacity; //数据区容量
};
#include
using namespace std;
class queue
{
public:
queue(int k)
{
size=k;
front=rear=0;
data=new int[size];
length=0;
}
bool full();
bool empty();
bool push(int val);
bool pop();
int queuelength();
void show();
private:
int front;
int rear;
int *data;
int size; //额定范围
int length; //实际长度
};
int main()
{
int k; //最大规格
int num; //录入数据
int P;
cout<<"请输入数列长度"<<endl;
cin>>k;
queue q(k);
while(1)
{
cout<<endl
<<" ._________________. "<<endl
<<" | _______________ | "<<endl
<<" | I I | "<<endl
<<" | I 数列 I | "<<endl
<<" | I_____________I | "<<endl
<<" !_________________! "<<endl
<<" (1) 输入 "<<endl
<<" (2) 输出 "<<endl
<<" (3) 退出 "<<endl
<<endl
<<" 选择 :" ;
cin>>P;
switch(P)
{
case 1:
cout<<"输入一个数"<<endl;
cin>>num;q.push(num);q.queuelength();q.show();break;
case 2:
cout<<"输出"<<endl;
q.pop();q.queuelength();q.show();break;
case 3:
cout<<"再见"<<endl;
return 0;
}
}
}
bool queue::full()
{
if((rear+1)%size==front){
return true;}
return false;
}
bool queue::empty()
{
if(front==rear){
return true;}
return false;
}
bool queue::push(int val)
{
if(full()){
cout<<"数列空!"<<endl;return false;}
data[rear]=val;
rear=(rear+1)%size;
length++;
return true;
}
bool queue::pop()
{
if(empty()){
cout<<"数列空!"<<endl;return false;}
front=(front+1)%size;
length--;
return true;
}
int queue::queuelength(){
return length;}
void queue::show()
{
if(empty()==true){
cout<<"数列空!"<<endl;}
else{
cout<<"输出:";
for(int i=front;i<rear;i++)
{
cout<<data[i]<<" ";}cout<<endl;
}}
集合是一类数据的聚合体,根据下述描述实现一个集合类的定义:
const int SetCapacity = 100;
class set
{
int elements[SetCapacity]; //数据区
int size; //元素个数
public:
set(); //构造函数
set(const set& src); //拷贝构造函数
bool Contains(int el); //是否包含元素el
bool Add(int el); //添加元素el
bool Remove(int el); //删除元素el
void Assign(set& st); //将st赋值给当前集合
bool EqualTo(set& st); //判别集合st与当前集合是否相同(元素相同)
bool Empty(); //集合是否为空
set Intersect(set& st); //求集合st 与当前集合的交集
set Union(set& st); //求集合st 与当前集合的并集
void print(); //显示集合的所有元素
};
#include
using namespace std;
const int SetCapacity = 100;
class set
{
int elements[SetCapacity]; //数据区
int _size; //元素个数
int k; //计数变量
public:
set(int *a,int size)
{
_size=size;
for(k=0;k<_size;k++)
{
elements[k]=a[k];
}
}; //构造函数
set(const set& src)
{
this->_size=src._size;
for(k=0;k<_size;k++)
{
this->elements[k]=src.elements[k];
}
}
bool Contains(int el) //是否包含元素el
{
for(k=0;k<_size;k++)
{
if(elements[k]==el)
{
cout<<"Found "<<el<<" at: elements["<<k<<"]."<<endl;
return true;
}
}
cout<<"Not found."<<endl;
return false;
}
bool Add(int el) //添加元素el
{
k=_size;
elements[k]=el;
_size++;
cout<<"Successfully added."<<endl;
}
bool Remove(int el) //删除元素el
{
bool search;
for(k=0;k<_size;k++)
{
if(elements[k]==el)
{
search=true;
break;
}
}
if(search==false)
{
cout<<"Not found."<<endl;
}
else
{
cout<<"Found "<<el<<" at: elements["<<k<<"]."<<endl;
int k0;
for(;k<_size-1;k++)
{
elements[k]=elements[k+1];
}
_size--;
}
}
void Assign(set& st) //将st赋值给当前集合
{
_size=st._size;
for(k=0;k<_size;k++)
{
elements[k]=st.elements[k];
}
}
bool EqualTo(set& st) //判别集合st与当前集合是否相同(元素相同)
{
if(st._size!=_size)
{
cout<<"The set doesn't equals to the other set."<<endl;
return false;
}
for(k=0;k<_size;k++)
{
if(st.elements[k]!=elements[k])
{
cout<<"The set doesn't equals to the other set."<<endl;
return false;
}
}
cout<<"The set equals to the other set."<<endl;
return true;
}
bool Empty() //集合是否为空
{
if(_size==0)
{
cout<<"The set is empty."<<endl;
return true;
}
return false;
}
set Intersect(set& st) //求集合st 与当前集合的交集
{
int temp[SetCapacity];
int tempsize=0;
int l;
int tempk=0;
for(k=0;k<_size;k++)
{
for(l=0;l<st._size;l++)
{
if(elements[k]==st.elements[l])
{
temp[tempk]=elements[k];
tempsize++;
tempk++;
}
}
}
return set(temp,tempsize);
}
set Union(set& st) //求集合st 与当前集合的并集
{
int temp[SetCapacity];
int tempsize=_size;
int l;
int tempk;
bool judge=true;
k=0;
for(tempk=0;tempk<tempsize;tempk++)
{
temp[tempk]=elements[k];
k++;
}
for(l=0;l<st._size;l++)
{
for(k=0;k<_size;k++)
{
if(elements[k]==st.elements[l])
{
judge=false;
break;
}
}
if(judge==true)
{
temp[tempk]=st.elements[l];
tempk++;
tempsize++;
}
judge=true;
}
return set(temp,tempsize);
}
void print()
{
for(k=0;k<_size;k++)
{
cout<<elements[k]<<" ";
}
cout<<endl;
}
};
int main()
{
int a[5]={
1,2,3,4,5};
int b[6]={
3,4,5,6,7,8};
int size1=5;
int size2=6;
set s0(a,size1);
set s2(a,size1);
set s3(b,size2);
s0.print();
s0.Contains(5);
s0.Contains(12);
s0.Add(6);
s0.print();
s0.Remove(2);
s0.print();
set s1(s0);
s1.EqualTo(s0);
s2.EqualTo(s0);
set s4=s2.Intersect(s3);
set s5=s2.Union(s3);
s4.print();
s5.print();
s5.Assign(s4);
s5.print();
return 0;
}
大整数计算程序设计:当一个整数超过了系统提供的整型数据的表示范围时,可以考虑用若干个整型数“拼接”而成,也可以采用字符串来存放。试根据如下梗概描述设计一个大整数类,并编写相应的方法。
class LongInt
{
int size;
char* data; //采用字符串存放
public:
LongInt(){ size = 0; data = 0; }
LongInt(char* s); //由字符串构造大整数对象
LongInt(long num); //构造一个指定长度的大整数对象
LongInt(LongInt& li); //拷贝构造函数
~LongInt(); //析构函数
LongInt read(); //从键盘读入大整数
void write(); //输出大整数
LongInt add(LongInt& li); //大整数求和
LongInt& operator=(const LongInt& li);
};
LongInt& LongInt::operator=(const LongInt& li)
{
if(this == &li)
return *this;
delete[] data;
size = li.size;
data = new char[size+1];
strcpy(data, li.data);
}
#include
#include
#include
using namespace std;
void reverse_string(std::string &ans)
{
int n = ans.length(), i;
char tmp;
for (i=0; i<n/2; i++)
{
tmp = ans.at(i);
ans.at(i) = ans.at(n-i-1);
ans.at(n-i-1) = tmp; }
}
void remove_zeros(std::string &ans)
{
if (ans == "0") {
return; }
int i = 0; for (i=0; i<ans.length(); i++)
{
if (ans.at(i) != '0')
{
break; } }
ans = ans.substr(i);}
class BigInt {
public: std::string num;
BigInt(void) {
} BigInt(std::string Num): num(Num) {
}
BigInt Add(const BigInt & b)
{
std::string ans;
int i, n1 = std::min(num.length(), b.num.length()), n2 = std::max(num.length(), b.num.length()), a1, a2, s = 0, si = 0;
for (i=0; i<n1; i++)
{
a1 = num.at(num.length()-i-1) - '0';
a2 = b.num.at(b.num.length()-i-1) - '0';
if (a1 + a2 + si< 10)
{
s = a1 + a2 + si; si = 0; }
else
{
s = (a1 + a2 + si) - 10;si = 1; }
ans.push_back((char)(s + '0')); }
for (i=n1; i<n2; i++)
{
if (n2 == num.length())
{
a1 = num.at(n2-i-1) - '0'; }
else
{
a1 = b.num.at(n2-i-1) - '0';}
if (a1 + si < 10)
{
s = a1 + si;
si = 0; }
else
{
s = (a1 + si) - 10;
si = 1; }
ans.push_back((char)(s + '0')); }
if (si == 1)
{
ans.push_back('1'); }
reverse_string(ans);
return BigInt(ans); }
int Compare(const BigInt & b)
{
int n1 = num.length(), n2 = b.num.length(), i = 0;
if (n1 > n2)
{
return 1; }
else if (n1 < n2)
{
return -1; }
else
{
for (i=0; i<n1; i++)
{
if (num.at(i) > b.num.at(i))
{
return 1; }
else if (num.at(i) < b.num.at(i))
{
return -1; } }
return 0; } }
BigInt Subtract(const BigInt & b)
{
std::string ans;
int oper = Compare(b), i, n1 = num.length(), n2 = b.num.length(), a1, a2, s = 0, si = 0;
if (oper == 0)
{
return BigInt("0"); }
else if (oper == -1)
{
n1 = b.num.length();
n2 = num.length();
for (i=0; i<n2; i++)
{
a1 = b.num.at(n1-i-1) - '0';
a2 = num.at(n2-i-1) - '0';
if (a1 - a2 - si >= 0)
{
s = a1 - a2 - si;
si = 0; }
else
{
s = (a1 - a2 - si) + 10;
si = 1; }
ans.push_back((char)(s + '0')); }
for (i=n2; i<n1; i++)
{
a1 = b.num.at(n1-i-1) - '0';
if (a1 - si >= 0)
{
s = a1 - si;
si = 0; }
else
{
s = (a1 - si) + 10;
si = 1; }
ans.push_back((char)(s + '0')); }
reverse_string(ans);
remove_zeros(ans);
std::string ans1 = "-";
ans = ans1.append(ans); }
else
{
for (i=0; i<n2; i++)
{
a1 = num.at(n1-i-1) - '0';
a2 = b.num.at(n2-i-1) - '0';
if (a1 - a2 - si >= 0)
{
s = a1 - a2 - si;
si = 0; }
else
{
s = (a1 - a2 - si) + 10;
si = 1; }
ans.push_back((char)(s + '0')); }
for (i=n2; i<n1; i++)
{
a1 = num.at(n1-i-1) - '0';
if (a1 - si >= 0)
{
s = a1 - si;
si = 0; }
else
{
s = (a1 - si) + 10;
si = 1; }
ans.push_back((char)(s + '0')); }
reverse_string(ans);
remove_zeros(ans); }
return BigInt(ans); }
BigInt Multiply(const BigInt & b)
{
BigInt ans("0");
std::string tmp;
int i, j, k, n1 = num.length(), n2 = b.num.length(), a1, a2, s = 0, si = 0;
for (j=n2-1; j>=0; j--)
{
a2 = b.num.at(j) - '0';
if (a2 == 0)
{
continue; }
tmp.clear();
s = 0;
si = 0;
for (k=0; k<n2-1-j; k++)
{
tmp.push_back('0'); }
for (i=n1-1; i>=0; i--)
{
a1 = num.at(i) - '0';
s = (a1 * a2 + si) % 10;
si = (a1 * a2 + si) / 10;
tmp.push_back((char)(s + '0')); }
if (si != 0)
{
tmp.push_back((char) (si + '0')); }
reverse_string(tmp);
ans = ans.Add(BigInt(tmp)); }
return ans; }
BigInt Divide(const BigInt & b)
{
std::string ans;
BigInt div;
int n1 = num.length(), n2 = b.num.length(), i, tmp = 0;
if (n1 < n2)
{
return BigInt("0"); }
div.num = num.substr(0, n2-1);
for (i = 0; i <= n1 - n2; i++)
{
div.num.push_back(num.at(i+n2-1));
tmp = 0;
while (div.Compare(b) >= 0)
{
tmp++;
div = div.Subtract(b); }
ans.push_back((char) (tmp + '0')); }
remove_zeros(ans);
return BigInt(ans); }};
int main()
{
cout<<" ._________________. "<<endl
<<" | _______________ | "<<endl
<<" | I I | "<<endl
<<" | I 计算器 I | "<<endl
<<" | I_____________I | "<<endl
<<" !_________________! "<<endl
<<endl
<<"请输入计算公式:a+b" <<endl;
BigInt a,b;
char oper;
std::cin >> a.num >> oper >> b.num;
switch (oper)
{
case '+':
std::cout << a.Add(b).num;
break;
case '-':
std::cout << a.Subtract(b).num;
break;
case '*':
std::cout << a.Multiply(b).num;
break;
case '/':
std::cout << a.Divide(b).num;
break;
default: break; }
return 0;}