计算器
- 这是用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是退出