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

• 写回答

#### 4条回答默认 最新

关注
``````#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;
}

``````
本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

#### 问题事件

• 已结题 （查看结题原因） 6月12日

#### 悬赏问题

• ¥20 C语言字符串不区分大小写字典排序相关问题
• ¥15 关于#python#的问题：我希望通过逆向技术爬取1688搜索页下滑加载的数据
• ¥15 学习C++过程中遇到的问题
• ¥15 关于Linux的终端里，模拟实现一个带口令保护的屏保程序遇到的输入输出的问题！(语言-c语言)
• ¥15 学习C++过程中遇到的问题
• ¥15 请问，这个嵌入式Linux系统怎么分析，crc检验区域在哪
• ¥15 二分类改为多分类问题