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

用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日

悬赏问题

  • ¥30 51单片机C语言数码管驱动单片机为AT89C52
  • ¥100 只改动本课件的 cal_portfolio_weight_series(decision_date), 跑完本课件。设计一个信息比率尽量高的策略。
  • ¥20 如何在visual studio 2022中添加ImageMagick库
  • ¥50 如何实现uniapp编译的微信小程序做可回溯视频
  • ¥15 求Houdini使用行家,付费。价格面议。
  • ¥15 前端高拍仪调用问题报错
  • ¥15 想用octave解决这个数学问题
  • ¥15 Centos新建的临时ip无法上网,如何解决?
  • ¥15 海康威视如何实现客户端软件对设备语音请求的处理。
  • ¥15 支付宝h5参数如何实现跳转