用于练习c++的计算器


计算器


  • 这是用C++写的一个计算器
  • 是用逆波兰式算法,输入一行表达式回车后输出结果
  • 表达式可以输入(±*/()1234567890(不检查非法的输入))
  • 不能输入小数,也不会输出小数
  • 非常简陋非常不安全
  • 代码中的双向链表是一个多余的存在,但我懒得改了
源文件
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include"stack.h"	//用vs2015写的,源文件和头文件在同一文件中

//打印菜单
void menu() {
	std::cout << "请输入表达式(退出:0,清空:q):\n" << std::endl;
}

int main() {
	//bbb();

	// 打印菜单
	menu();

	//流程
	while(1){
		char len[128];
		gets_s(len);
		if (len[0] == '0') {
			std::cout << "ooo" << std::endl;
			exit(0);
		}
		else if (!strcmp(len, "q"))
			system("cls");
		else{
			//输出结果
			stacp* a;
			a=stack(len);
		}
	}

	return 0;
}
头文件
#ifndef STACK_H//可以随便写只要没有   .     就可以
#define  STACK_H

#include<iostream>
#include<math.h>
#include<stdlib.h>

//双向链表的组成单元(结构体)
struct stacp {

	int number = 0;
	char sig;
	char f;		//0:是数字,1:是符号
	stacp* front=0;
	stacp* next=0;
};
//记录
stacp * stack(char* a) {
	int i = 0, j = 0, k = 0;

	//建立双向链表的表头
	stacp* const p = (stacp*)malloc(sizeof(stacp));
	stacp* p1 = p;
	p1->front = 0;
	p1->next = 0;
	stacp* p2;

	//安全检查
	//按中缀表达式的形式存入双向链表中
	for (; a[i] != 0; ) {
		if (a[i] == 42 || a[i]== 43 || a[i] == 45 || a[i] == 47	//'+' '-' '*' '/'
			||a[i]==40||a[i]==41) {								//'('	')'

			//读取一个符号---a[i]就是符号
			p2 = (stacp*)malloc(sizeof(stacp));
			p2->sig = a[i];
			p2->number = 2000000000 + a[i];
			p2->f = 1;				//定义p2

			p1->next = p2;			//连接p1与p2
			p2->front = p1;
			p1 = p1->next;
			p1->next = 0;


			//相当于返回值
			i++;
			k++;
		}
		else if (a[i + j] <= 57 && a[i + j] >= 48) {
			for (j = 0; a[i + j] <= 57 && a[i + j] >= 48; j++) {

			}

			//读取一个数字---i是开始,0-j是过程
			int pul = 0;
			for (int hh = 0; hh < j; hh++) {
				pul += pow(10,j-hh-1)*(a[i + hh] - 48);
			}
			p2 = (stacp*)malloc(sizeof(stacp));
			p2->number = pul;
			p2->f = 0;				//定义p2

			p1->next = p2;			//连接p1与p2
			p2->front = p1;
			p1 = p1->next;
			p1->next = 0;



			//相当于返回值
			i = i + j;
			j = 0;
			k++;
		}
		else {
			std::cout << "无意义" << std::endl;
			exit(-1);
		}

	}

	//p3指向是双向链表的表头,k是链表的个数
	stacp* p3 = p->next;
	for (int mm = 0; mm < k; ++mm) {
		//if ((p3->f) == 0)								//用于读取符号1
		//std::cout << (p3->number) << std::endl;
		//else											//用于读取符号3
			//std::cout << (p3->sig) << std::endl;		//用于读取符号4



		p3 = p3->next;
	}

	//改成后缀式
	p3 = p->next;//找到双向链表开始的地方

	const int size_st = 128;
	const int max = 2000000000;
	int uk[size_st]{ 0 },*pk=uk ;								//用于拷贝
	int ui[size_st]{ 0 },*pi=ui;						//栈	puu:指向栈底的指针,
														//		ui: 指向栈顶的指针
	int uo[size_st]{ 0 }, *po = uo;						//输出

	//拷贝
	for (int mm = 0; mm < k; ++mm) {
		*pk = (p3->number);
		++pk;
		p3 = p3->next;
	}
	pk = uk;
	p3 = p->next;

	for (int mm = 0; mm < k; ++mm) {					//这个地方的判断是需要
										
		if ((*pk > 2000000000) && (*pk == 2000000041)&& (*(pi - 1) == 2000000040)) {
			--pi;
			*pi = 0;
			++pk;
		}									//更改的
		else if (*pk > 2000000000 && (pi == ui|| *pk == 2000000040||*(pi-1)==2000000040 ||
			(*(pi-1)== 2000000043 || *(pi - 1) == 2000000045)&&
			(*pk== 2000000042|| *pk == 2000000047))) {		//符号入栈
			*pi = *pk;

			++pi;
			++pk;
		}
		else if (*pk < 2000000000) {						//数字输出
			*po = *pk;
			++po;
			++pk;
		}
		else {
			--mm;
			--pi;
			*po = *pi;
			*pi = 0;
			++po;

		}


	}

	//清空栈
	while (pi != ui) {
		--pi;
		*po = *pi;
		*pi = 0;
		++po;
	}

	//	计算 后缀式为:uo【max】,po;
	//目前只能用加法和乘法
	po = uo;

	while (*po != 0) {
		if(*po<2000000000){
			*pi = *po;
			++pi;
			++po;
		}
		else if(*po==2000000043){//加
			*(pi - 2) += *(pi - 1);
			*pi = 0;
			--pi;
			++po;
		}
		else if(*po == 2000000045) {//减
			*(pi - 2) -= *(pi - 1);
			*pi = 0;
			--pi;
			++po;
		}
		else if (*po == 2000000042) {//乘
			*(pi - 2) *= *(pi - 1);
			*pi = 0;
			--pi;
			++po;
		}
		else  {						//除
			*(pi - 2) /= *(pi - 1);
			*pi = 0;
			--pi;
			++po;
		}
	}
	std::cout << ui[0] << std::endl;
}
#endif
  • malloc了的内存有作用域吗
  • 不能计算大于2000000000(9个0)的数
  • 首位的-会被无视
  • q是清空,0是退出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值