• 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 }

    测试结果如下:

    冷静思考,勇敢面对,把握未来!
  • 相关阅读:
    SQL server多表联合查询
    Linux at命令
    git用法总结详细
    vue插槽
    vue组件通信
    vue高阶函数
    vue过滤器
    vue侦听器watch
    Vue 计算属性 computed
    Spring事务失效的场景
  • 原文地址:https://www.cnblogs.com/Anker/p/3074916.html
Copyright © 2020-2023  润新知