一个简单计算器的实现
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 }
运行结果: