C++计算器的实现

该博客介绍了用C++实现的计算器,可进行+ - * / 与()的复合运算。主要通过构建操作数栈和操作符栈,依据操作符判断实现合理出入栈以保证优先级,栈的初始化及进栈出栈操作自定义,还支持负数和浮点数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

能够实现+ - * / 与()的复合运算

功能简介

  1. 计算器的实现主要通过构建操作数栈和操作符栈
  2. 通过对操作符的判断来实现合理出入栈,来实现优先级
  3. 其中对栈的初始化,以及进栈出栈操作均为自己定义
  4. 支持负数,浮点数
  5. !!!!!运行()是确保输入法是

运行结果展示在这里插入图片描述

代码头文件expr.h

expr.h

#pragma once// ExprCPro.cpp: 定义控制台应用程序的入口点。
//
#ifndef CIRCLE_H
#define CIRCLE_H


typedef struct StackNodeOPND //操作数栈
{
	double value;
	StackNodeOPND *next;
}*OPND;

typedef struct StackNodeOPTD //操作符栈
{
	char op;
	StackNodeOPTD *next;
}*OPTD;


int init(OPND&opnd);   //操作数栈初始化
int init(OPTD&optr);   //栈初始化
int push(OPND&opnd, const double value);//进栈操作
int push(OPTD&optd, const char op);
int pop(OPND&opnd, double &value);//出栈操作
int pop(OPTD&optd, char &op);
int getTop(OPND&opnd, double &value);//得到栈顶元素
int getTop(OPTD&optd, char &op);
int isEmpty(OPND &opnd);//判断栈是否为空
int isEmpty(OPTD &optd);
char precede(char a, char b);//优先级比较
double calc(double a, char theta, double b);//运算函数
double parse(char expr[]);//解析传入的字符串




#endif

对头文件定义函数的实现

expr.cpp


#include "stdafx.h"
#include "targetver.h"
#include<iostream>
#include <string>
#include <stack>
#include <string.h>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <vector>
#include "expr.h"

using namespace std;


int init(OPND&opnd)   //栈初始化
{
	while (opnd != NULL) {  //删除栈
		OPND temp = opnd;
		opnd = temp->next;
		free(temp);
	}
	opnd = NULL;
	return 0;
}

int init(OPTD&optr)   //栈初始化
{
	while (optr != NULL) {  //删除栈
		OPTD temp = optr;
		optr = temp->next;
		free(temp);
	}
	optr = NULL;
	return 0;
}

int push(OPND&opnd, const double value) {  //添加栈指针
	OPND temp = (OPND)malloc(sizeof(StackNodeOPND));
	if (!temp) {
		return -1;
	}
	temp->value = value;
	temp->next = opnd;
	opnd = temp;
	return 0;
}

int push(OPTD&optd, const char op) {  //添加栈指针
	OPTD temp = (OPTD)malloc(sizeof(StackNodeOPTD));
	if (!temp) {
		return -1;
	}
	temp->op = op;
	temp->next = optd;
	optd = temp;
	return 0;
}



int pop(OPND&opnd, double &value) {
	if (opnd == NULL) {
		return -1;
	}
	value = opnd->value;
	OPND temp = opnd;
	opnd = temp->next;
	free(temp);
	return 0;
}

int pop(OPTD&optd, char &op) {
	if (optd == NULL) {
		return -1;
	}
	op = optd->op;
	OPTD temp = optd;
	optd = temp->next;
	free(temp);
	return 0;
}


int getTop(OPND&opnd, double &value) {
	if (opnd == NULL) {
		return -1;
	}
	value = opnd->value;
	return 0;
}

int getTop(OPTD&optd, char &op) {
	if (optd == NULL) {
		return -1;
	}
	op = optd->op;
	return 0;
}

int isEmpty(OPND &opnd) {
	if (opnd == NULL) {
		return 1;
	}
	else {
		return 0;
	}
}

int isEmpty(OPTD &optd) {
	if (optd == NULL) {
		return 1;
	}
	else {
		return 0;
	}
}

char precede(char a, char b) {
	char aPriorTable[6][6] = {
		//+  -  *  /  (   )
	{ '>','>','<','<','<','>' },
	{ '>','>','<','<','<','>' },
	{ '>','>','>','>','<','>' },
	{ '>','>','>','>','<','>' },
	{ '<','<','<','<','<','=' },
	{ '>','>','>','>','>','>' }
	};
	int x = -1;
	int y = -1;
	//
	if (a == 0) {
		return '<';
	}
	char opr[] = "+-*/()";
	if (b == '+')y = 0;
	if (b == '-')y = 1;
	if (b == '*')y = 2;
	if (b == '/')y = 3;
	if (b == '(')y = 4;
	if (b == ')')y = 5;
	if (a == '+')x = 0;
	if (a == '-')x = 1;
	if (a == '*')x = 2;
	if (a == '/')x = 3;
	if (a == '(')x = 4;
	if (a == ')')x = 5;
	return aPriorTable[x][y];
	//for (int i = 0; i < 6; i++) {
	//	if (a == opr[i])x = i;
		//	printf("\n x is%d", x);
	//	if (b == opr[i])y = i;
	//	if (b == '-')y = 1;
		//	printf("\n y is%d", y);
		//	printf("\naPriorTable[x][y]is %c", aPriorTable[x][y]);
	//	return aPriorTable[x][y];
	//}
}

double calc(double a, char theta, double b) {
	double value = 0;
	switch (theta) {
	case'+':value = a + b; break;
	case'-':value = a - b; break;
	case'*':value = a * b; break;
	case'/':value = a / b; break;
	default: {
		exit(0);
	}
	}
	return value;
}






double parse(char expr[]) {
	OPND opnd = NULL;
	OPTD optr = NULL;
	init(opnd);
	init(optr);
	for (int i = 0; expr[i] != '\0'; i++) {
		char c = expr[i];
		if (c >= '0'&&c <= '9' || c == '.') {
			char token[20] = { 0 };
			int j = 0;
			while (expr[i + j] >= '0'&&expr[i + j] <= '9' || expr[i + j] == '.') {
			//	printf("this is %c", expr[i + j]);
				token[j] = expr[i+j];//error
				j++;
			}
			token[j] = '\0';
			i = i + j - 1;
			double value = atof(token);
			//printf("value is %f", value);
			push(opnd, value);
		}
		else {
			char op = 0;
			getTop(optr, op);//b is op   optr is a
			switch (precede(op, c)) {
			case '<':push(optr, c);
				break;
			case'=':
				//printf("%c", op);
				pop(optr, op);
				break;
			case'>':
				double a = 0;
				double b = 0;
				pop(opnd, b);
				pop(opnd, a);
				pop(optr, op);
				push(opnd, calc(a, op, b));
				i--;
				break;

			}



		}
	}
	while (!isEmpty(optr)) {
		double a = 0;
		double b = 0;
		char op = 0;
		pop(opnd, b);
		pop(opnd, a);
		pop(optr, op);
	
		push(opnd, calc(a, op, b));
	}
	double value = 0;
	pop(opnd, value);
	return value;

}

Main函数

main.cpp

// ConsoleApplication3.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include "expr.h"

int main()
{

	using namespace std;
		char str1[20];
		cout << "支持四则运算与优先级+-*/" << endl;
		cout << "edg 5+(3-1)" << endl;
		cin.get(str1, 20);
		double b = parse(str1);
		printf("the result is %0.3f", b);
		getchar();
		getchar();
		return 0;

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值