C++面向对象程序设计实践——任务与指导书(1)


C++课程设计——面向对象程序设计实践(1)


一、任务描述
实验1:工具与语法训练

  1. 目的
    (1)了解学习 C++语言的集成化开发环境的使用方法和主要功能;
    (2)掌握程序的编辑、编译、连接和运行的基本步骤;
    (3)初步掌握系统提供的程序调试工具和程序调试方法。
  2. 步骤
    (1) 根据教师对一种工具的演示,以及对其他工具的简要说明,查阅资料,分析、比较和选择一种开发工具。
    (2) 自行查找、下载和安装选择的开发工具,也可以使用系统已安装的工具。
    (3) 查阅资料,运行环境,利用小程序了解环境的使用方法。
  3. 内容

1.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<iostream>
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;
}

1.2

在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<iostream>
#include<stdio.h>
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. 目的
    (1)掌握类的概念和定义方法;
    (2)掌握对象的定义方法和类成员的表示方法;
    (3)加深理解构造函数和析构函数的概念、作用及构造方法;
    (4)初步掌握面向对象的程序设计方法。
  2. 步骤
    对于任务中的每个问题,分析并设计解题思路,编制程序,通过观察和调试工具纠错,运行得到正确结果。
  3. 内容:

最少数量要求:题1~题3选一;题4~题6选一。

2.1

设计一个三角形处理类,包含三条边长为数据成员,实现并测试这个类。类中包括的成员函数(要完成操作)有:
(1)构造函数;
(2)析构函数;
(3)判别是否构成三角形函数;
(4)是否构成直角三角形函数;
(5)计算面积函数。

#include<iostream>
#include<math.h>
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;	
}

2.2

设计一个地址类Address,其中包括某人姓名、所居住的街道地址、城市和邮编等属性,实现并测试这个类。
类中包括的成员函数(要完成操作)有:
(1)构造函数;
(2)析构函数;
(3)ChangeName()成员函数,用于改变对象的姓名等属性
(4)Display()成员函数,用于显示姓名、街道地址、城市和邮编等属性。

#include<iostream>
#include<string.h> 
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;
}

2.3

完善下面的产品类,该类用于管理产品的名称、单价和库存数量,能够根据用户输入的产品名称和购买数量计算相应的金额。在 main 函数中模拟几种商品(由键盘输入) ,并实现一个菜单式程序,演示用户任意购买各种商品的过程。
class product
{
char* tag; //产品名称
double price; //单价
int quantity; //库存数量
public:
//构造函数
//析构函数
//购买某种商品函数buy,返回false表示库存数量不够,否则更新库存数量,并计算费用
//属性相关函数,如库存调整、显示库存数量等
};

#include<iostream>
#include<string>
#include<iomanip>
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;
}

2.4

队列是一种连续的存储结构,存入数据只能从一端(称为尾部)进入,取出数据则只能从另一端(头部)取出。根据下述描述实现一个自定义的队列类:
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<iostream>
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;
	}}	

2.5

集合是一类数据的聚合体,根据下述描述实现一个集合类的定义:
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 <iostream>
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;
}

2.6

大整数计算程序设计:当一个整数超过了系统提供的整型数据的表示范围时,可以考虑用若干个整型数“拼接”而成,也可以采用字符串来存放。试根据如下梗概描述设计一个大整数类,并编写相应的方法。
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<string>
#include<iostream>
#include<algorithm>
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;}
  • 19
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GodOuO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值