天星灵师 2021-06-17 18:10 采纳率: 50%
浏览 612
已结题

用C语言编写一个计算器,要求能进行加减乘除,乘方和带括号的运算

 

  • 写回答

4条回答 默认 最新

  • CSDN专家-link 2021-06-17 18:16
    关注
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #define INIT_STRING_SIZE 100
    #define True 1
    #define False 0
    int saved_class[4] = { 0, 0, 0, 0 };
    typedef struct aNum {
    	double data;
    	char oper;
    	int dataClass;
    	int power;
    	struct aNum *next;
    }num;
    typedef struct {
    	char *formula;
    	int length;
    }string;
    
    void setNULL(char *num)//清空一个字符串
    {
    	int i = 0;
    	while (i<5)
    	{
    		num[i] = NULL;
    		++i;
    	}
    }
    int countOperators(string *input, int &counter)//processing step 1
    {//计算运算符个数
    	int i = 0;
    	while (input->formula[i] != '\0')
    	{
    		switch (input->formula[i++])
    		{
    		case '+':
    		case '-':
    		case '*':
    		case '/':++counter; break;
    		default:break;
    		}
    		++input->length;
    	}
    	return 1;
    }
    int getData(string *input, num *nums)//processing step 2
    {//把数字,符号和class存入nums的结构体
    	int i = 0;    //counter of input->formula
    	int k = 0;  //counter of temp;
    	int power = 0;
    	char temp[5];
    	int inBracket = False;
    	num *p = nums;
    	num *body;
    
    	while (i <= input->length)
    	{
    		if ((input->formula[i]<'0' || input->formula[i]>'9')&&input->formula[i]!='.'&&input->formula[i]!='^')
    		{//进入此处时数据已经收集完毕
    			if (input->formula[i] == '(')
    			{
    				inBracket = True;
    				++i;
    				continue;
    			}
    			if (input->formula[i] == ')')
    			{
    				inBracket = False;
    				++i;
    				continue;
    			}
    			body = (num *)calloc(1, sizeof(num));
    
    			body->data = atof(temp);    //得到数字
    			setNULL(temp);              //归零temp
    			k = 0;
    
    			switch (input->formula[i])
    			{
    			case '+':body->dataClass = inBracket == False ? 1 : 3;  //计算当前运算符的等级
    				++saved_class[body->dataClass - 1];                 //在等级数组里记录一次
    				body->oper = input->formula[i];                     //得到运算符
    				break;
    
    			case '-':body->dataClass = inBracket == False ? 1 : 3;
    				++saved_class[body->dataClass - 1];
    				body->oper = input->formula[i];
    				break;
    
    			case 'x':
    			case '*':body->dataClass = inBracket == False ? 2 : 4;
    				++saved_class[body->dataClass - 1];
    				body->oper = input->formula[i];
    				break;
    
    			case '/':body->dataClass = inBracket == False ? 2 : 4;
    				++saved_class[body->dataClass - 1];
    				body->oper = input->formula[i];
    				break;
    
    			default:break;
    			}
    			if (power != 0)
    			{
    				body->power = power;
    				power = 0;
    			}
    			p->next = body;
    			p = p->next;
    		}
    		else if (input->formula[i] == '^')
    		{
    			power = input->formula[++i] - 48;
    		}
    		else
    		{
    			temp[k++] = input->formula[i];
    		}
    		++i;
    	}
    	return 1;
    }
    double compute(double num1, double num2, char opt)
    {//每次运算单独提取
    	double result;
    	switch (opt)
    	{
    	case '-':result = num1 - num2; break;
    	case '+':result = num1 + num2; break;
    	case 'x':
    	case '*':result = num1 * num2; break;
    	case '/':result = num1 / num2; break;
    	}
    	return result;
    }
    int processingData(num *nums)//processing step 3
    {//nums作为头结点是没有数据的
    	int s = 3;//saved_class
    	int i = 0;
    	num *p = nums;
    	num *p_front;
    	while (saved_class[s] == 0&&s>0)
    		--s;
    	while (p->next->next != NULL)//class oper next 都可以
    	{
    		if (p->next->dataClass != s + 1)
    		{
    			p = p->next;
    			continue;
    		}
    		p_front = p;
    		p = p->next;//p此时指向待计算的第一个struct aNUm
    		if(p->power != 0)
    		{
    			p->data = pow(p->data, p->power);
    			p->power = 0;
    		}
    		if (p->next->power != 0)
    		{
    			p->next->data = pow(p->next->data, p->next->power);
    			p->next->power = 0;
    		}
    		p->next->data = compute(p->data, p->next->data, p->oper);
    
    		p_front->next = p->next;
    		free(p);
    		--saved_class[s];
    		while (saved_class[s] == 0&&s!=0)
    			--s;
    		p = nums;
    
    
    	}
    	if (nums->next->power != 0)//处理单个数字输入的情况,比如2^2
    	{
    		nums->next->data = pow(nums->next->data, nums->next->power);
    	}
    
    
    	printf("result=%lf\n", nums->next->data);
    	return 1;
    }
    int main()
    {
    	int counter = 0;
    	num *nums = NULL;
    	string *input;
    	input = (string *)calloc(1, sizeof(string));
    	input->formula = (char *)calloc(INIT_STRING_SIZE, sizeof(string));
    
    
    	puts("Input formula:");
    	scanf("%s", input->formula);
    
    	//得到运算符和运算符个数
    	countOperators(input, counter);
    	//根据运算符个数申请存储数字的空间
    	nums = (num *)calloc(1, sizeof(num));
    	//存储数字和运算符
    	getData(input, nums);
    	processingData(nums);
    
    	free(input->formula);
    	free(input);
    	free(nums->next);
    	free(nums);
    	system("pause");//如果你是linux或者macos,可能需要去掉这句
    	return 0;
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月12日

悬赏问题

  • ¥15 PointNet++的onnx模型只能使用一次
  • ¥20 西南科技大学数字信号处理
  • ¥15 有两个非常“自以为是”烦人的问题急期待大家解决!
  • ¥30 STM32 INMP441无法读取数据
  • ¥15 R语言绘制密度图,一个密度曲线内fill不同颜色如何实现
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧,别用大模型回答,大模型的答案没啥用
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。