C语言综合实验3—计算器四则运算

题目要求:编程实现计算器程序,完成实数的加、减、乘、除运算。注意运算符优先级别。表达式要求采用中缀形式,例如:2.3+7.2*7
提示:表达式处理可参考“逆波兰表达式”范例。

完整程序如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 #define MAXSIZE 100
  6 #define SYMBOLSIZE 50
  7 
  8 //表达式运算符结构体
  9 typedef struct oper_symbol
 10 {
 11     char oper; //运算符
 12     unsigned int index;//运算符在表达式中的位置索引
 13 }oper_symbol;
 14 
 15 //表达式计算函数声明
 16 double caculate(char * expression);
 17 double get_data(char * str,int beg,int end);
 18 int is_operator_symbol(char ch);
 19 long int power(int base,int times);
 20 
 21 int main()
 22 {
 23     char *expression = NULL;
 24     double ret;
 25     expression = (char*)malloc(sizeof(char)*MAXSIZE);
 26     if(expression == NULL)
 27     {
 28         printf("内存分配失败.\n");
 29         return -1;
 30     }
 31     memset(expression,0,MAXSIZE*sizeof(char));
 32     while(1)
 33     {
 34         printf("请输入一个表达式: ");
 35         scanf("%s",expression);
 36         ret = caculate(expression);
 37         printf("表达式计算结果为: %lf\n",ret);
 38     }
 39     free(expression);
 40     system("pause");
 41     return 0;
 42 }
 43 
 44 //表达式计算函数声明
 45 double caculate(char * expression)
 46 {
 47     unsigned int i,j,k;
 48     unsigned int symbol_len = 0; //运算符栈的长度
 49     unsigned int datas_len = 0;  //操作数栈的长度
 50     unsigned int symbol_index_len=0; //运算符的个数
 51     double left_data,right_data; //左右操作数
 52     double temp,ret;
 53 
 54     double *datas = (double*)malloc(sizeof(double)*MAXSIZE);
 55     char *symbols = (char*)malloc(sizeof(char*)*SYMBOLSIZE);
 56     oper_symbol * symbols_index = (oper_symbol*)malloc(sizeof(oper_symbol)*SYMBOLSIZE);
 57 
 58     if(datas == NULL || symbols == NULL || symbols_index == NULL)
 59     {
 60         printf("内存分配失败.\n");
 61         return 0;
 62     }
 63     for(i=0;i<strlen(expression);i++)
 64     {
 65         if(is_operator_symbol(expression[i]))
 66         {
 67             symbols_index[symbol_index_len].oper = expression[i];
 68             symbols_index[symbol_index_len].index = i;
 69             symbol_index_len++;
 70         }
 71     }
 72     //根据运算符提取两边的数据进行计算
 73     for(j=0,i=0;j<symbol_index_len;j++)
 74     {
 75         //取左操作数
 76         if(datas_len == 0)
 77             left_data = get_data(expression,i,symbols_index[j].index);
 78         else
 79             left_data = datas[--datas_len];
 80         //取右操作数
 81         if( j+1 == symbol_index_len)
 82             right_data = get_data(expression,symbols_index[j].index+1,strlen(expression));
 83         else
 84             right_data = get_data(expression,symbols_index[j].index+1,symbols_index[j+1].index);
 85         //如果运算符是*和/,先计算结果在保存
 86         if(symbols_index[j].oper == '*' || symbols_index[j].oper == '/')
 87         {
 88             switch(symbols_index[j].oper)
 89             {
 90             case '*':
 91                 temp = left_data * right_data;
 92                 break;
 93             case '/':
 94                 temp = left_data / right_data;
 95                 break;
 96             }
 97             datas[datas_len++] = temp;
 98         }
 99         //否则将左右操作数都不错
100         else
101         {
102             datas[datas_len++] = left_data;
103             datas[datas_len++] = right_data;
104             //记录+和-运算符的个数
105             symbols[symbol_len++] = symbols_index[j].oper;
106         }
107     }
108     //开始从后向前进行计算
109     k = symbol_len;
110     //直到操作符为空为止
111     while(k)
112     {
113         //取出左右两个操作数
114         left_data = datas[--datas_len];
115         right_data = datas[--datas_len];
116         k = symbol_len-1;
117         switch(symbols[k])
118         {
119         case '+':
120             temp = right_data + left_data;
121             break;
122         case '-':
123             temp = left_data - right_data;
124             break;
125         }
126         datas[datas_len++] = temp;
127         symbol_len--;
128     }
129     ret = datas[0];
130     free(datas);
131     free(symbols);
132     free(symbols_index);
133     return ret;
134 }
135 
136 //判断字符是否是运算符
137 int is_operator_symbol(char ch)
138 {
139     if(ch == '+' || ch == '-' || ch == '*' || ch == '/')
140         return 1;
141     return 0;
142 }
143 //从字符串中提出去浮点数
144 double get_data(char * str,int beg,int end)
145 {
146     int i,k;
147     double ret = 0.0f;
148     double integer = 0.0f;
149     double decimal = 0.0f;
150     double temp;
151     i = beg;
152     //取整数部分
153     while(str[i] != '.' && i < end)
154     {
155         integer *= 10;
156         integer += str[i] ^ 0x30;
157         i++;
158     }
159     //取小数部分
160     if(str[i] == '.')
161     {
162         i++;
163         k=1;
164         while(i<end)
165         {
166             temp =  str[i] ^ 0x30;
167             temp /= power(10,k);
168             decimal += temp;
169             k++;
170             i++;
171         }
172     }
173     //整数部分加上小数部分
174     ret = integer+decimal;
175     return ret;
176 }
177 
178 long int power(int base,int times)
179 {
180     long ret = 1;
181     int i;
182     for(i=0;i<times;i++)
183         ret *= base;
184     return ret;
185 }

测试结果如下:

转载于:https://www.cnblogs.com/Anker/archive/2013/05/13/3074916.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值