题目要求:编程实现计算器程序,完成实数的加、减、乘、除运算。注意运算符优先级别。表达式要求采用中缀形式,例如: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 }
测试结果如下: