• 一个简单计算器的实现


     Bjarne Stroustrup 《C++程序设计原理与实践》

     文法:

      

    std_lib_facilities.h
    
     1 #include <iostream>
     2 #include <string>
     3 #include <vector>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <stdio.h>//C语言的标准I/O库
     7 using namespace std;
     8 
     9 double primary();
    10 double term();
    11 double expression();
    12 
    13 //内联函数,防止在看到输出之前窗口关闭
    14 //这是Windows操作系统的特点,而不是C++的特点
    15 inline void keep_window_open()
    16 {
    17     char ch;
    18     //std::cin >> ch;
    19     getchar();
    20 }
    21 
    22 inline void error(string s)
    23 {
    24     cout << s << endl;
    25 }
    main.cpp
      1 /**********************************************************
      2 *
      3 *                      2013-2-4
      4 *
      5 *                     简单计算器
      6 *
      7 *                     CocoonFan
      8 *
      9 ***********************************************************/
     10 /***********************************************************
     11 * 
     12 ***********************************************************/
     13 
     14 #include "std_lib_facilities.h"
     15 const char number = '8';//代表数字
     16 const char quit = 'q';
     17 const char print = ';';
     18 const string prompt = "  >>";
     19 const string result = "=";
     20 
     21 class Token{
     22 public:
     23     char kind;//运算符号的类型
     24     double value;
     25 
     26     //constructor
     27     Token(char ch)
     28     //以冒号开始的成员初始化列表仅用于构造函数中
     29         :kind(ch),value(0){}
     30     Token(char ch, double val)
     31         :kind(ch),value(val){}
     32 };
     33 
     34 class Token_stream{
     35 public:
     36     Token_stream();
     37     Token get();
     38     void putback(Token t);
     39 private:
     40     bool full;
     41     Token buffer;
     42 };
     43 
     44 //constructor
     45 Token_stream::Token_stream()
     46     :full(false),buffer(0){}
     47 
     48 //put a Token back
     49 void Token_stream::putback(Token t)
     50 {
     51     if(full){//if buffer is full...
     52         error("putback() into a full buffer");
     53     }
     54     buffer = t;
     55     full = true;
     56 }
     57 
     58 //read a Tocken
     59 Token Token_stream::get()
     60 {
     61     if(full){//do we hava a Token ready?
     62         full = false;
     63         return buffer;
     64     }
     65 
     66     char ch;
     67     cin >> ch;
     68 
     69     switch(ch){
     70         case ';':
     71         case 'q':
     72         case '(':
     73         case ')':
     74         case '+':
     75         case '-':
     76         case '*':
     77         case '/':
     78             return Token(ch);
     79         case '.':
     80         case '0':
     81         case '1':
     82         case '2':
     83         case '3':
     84         case '4':
     85         case '5':
     86         case '6':
     87         case '7':
     88         case '8':
     89         case '9':
     90         {
     91             cin.putback(ch);
     92             double val;
     93             cin >> val;
     94             return Token(number,val);
     95         }
     96         default:
     97             error("Bad token");
     98 
     99     }
    100 }
    101 
    102 
    103 Token_stream ts;
    104 
    105 double expression()
    106 {
    107     double left = term();
    108     Token t = ts.get();
    109 
    110     while(true){
    111         switch(t.kind){
    112             case '+':
    113                 left += term();
    114                 t = ts.get();
    115                 break;
    116             case '-':
    117                 left -= term();
    118                 t = ts.get();
    119                 break;
    120             default:
    121                 ts.putback(t);
    122                 return left;
    123         }
    124     }
    125 }
    126 
    127 double term()
    128 {
    129     double left = primary();
    130     Token t = ts.get();
    131 
    132     while(true){
    133         switch(t.kind){
    134             case '*':
    135                 left *= primary();
    136                 t = ts.get();
    137                 break;
    138             case '/':
    139             {
    140                 double d = primary();
    141                 if(d == 0){
    142                     error("divide by zero");
    143                 }
    144                 left/=d;
    145                 t = ts.get();
    146                 break;
    147             }
    148             default:
    149                 ts.putback(t);
    150                 return left;
    151         }
    152     }
    153 }
    154 
    155 double primary()
    156 {
    157     Token t = ts.get();
    158     switch(t.kind){
    159         case '(':
    160         {
    161             double d = expression();
    162             t = ts.get();
    163             if(t.kind != ')'){
    164                 error("')'expcted");
    165             }
    166             return d;
    167         }
    168         case number:
    169             return t.value;
    170         case '-':
    171             return -primary();
    172         case '+':
    173             return primary();
    174         default:
    175             error("primary expected");
    176     }
    177 }
    178 int main()
    179 {
    180     double val = 0;
    181     while(cin){
    182         cout << prompt;
    183         Token t = ts.get();
    184 
    185         if(t.kind == quit) break;
    186         if(t.kind == print)
    187             cout << result << val << endl;
    188         else
    189             ts.putback(t);
    190         val = expression();
    191     }
    192 }


    运行结果:

      

  • 相关阅读:
    vue 仿IOS 滚轮选择器
    一道题目学ES6 API,合并对象id相同的两个数组对象
    Express中间件原理详解
    webpack原理与实战
    LS522 体积小低电压低成本的13.56MHz非接触式读写卡芯片,集成了在13.56MHz下所有类型的被动非接触式通信方式和协议,支持ISO14443A/B的多层应用( PIN对PIN MFRC522 )
    SP213EEA-L/TR +5V高性能RS232收发器
    多速率SDI集成接收器 SDI解码芯片 GS2971A-IBE3
    低电容3.3V TVS管 R CLAMP3304N.TCT
    高ESD耐压/TVS二极管 UCLAMP2804L.TCT
    高性能正电压稳压管SC4215HSETRT
  • 原文地址:https://www.cnblogs.com/CocoonFan/p/2908623.html
Copyright © 2020-2023  润新知