2010-07-22 40 views
1

我不知道是什麼Bjarne的意思與此練習:運動在C++編程語言第三版 - 臺計算器

「轉換的桌面計算器使用,而不是使用靜態變量NUMBER_VALUE和STRING_VALUE中的符號結構。 「

他的意思是把這兩個變量放在一個結構中,然後通過一個結構使用它們?

編輯:另外一個練習與計算器相關,它說: 「允許用戶在分類器中定義函數提示:將函數定義爲一系列操作,就像用戶輸入它們一樣。序列可以存儲爲字符串或者標記列表,然後在函數調用時讀取並執行這些操作。如果你想讓一個用戶定義的函數採用參數,你必須爲此創建一個符號「。

任何人都可以舉例說明它的含義嗎? 用戶應該定義什麼類型的函數,我沒有明白。能夠定義例如從其參數返回^ 2值的函數,例如?

這是代碼。

#include <iostream> 
#include <map> 

using namespace std; 

double term(bool); 
double expr(bool); 
double prim(bool); 
double error(const string&); 

double number_value; 
string string_value; 

int no_of_errors; 
map<string, double> table; 

enum Token_value { 
    NAME,   NUMBER,   END, 
    PLUS = '+', MINUS = '-',  MUL = '*', DIV = '/', 
    PRINT = ';', ASSIGN = '=', LP = '(',  RP = ')' 
}; 

Token_value curr_tok = PRINT; 
Token_value get_token(); 

double expr(bool get) 
{ 
     double left = term(get); 

     for(;;) 
      switch(curr_tok) { 
       case PLUS: 
        left += term(true); 
        break; 
       case MINUS: 
        left -= term(true); 
        break; 
       default: 
         return left; 
      } 
} 

double term(bool get) 
{ 
     double left = prim(get); 

     for(;;) 
      switch(curr_tok) { 
       case MUL: 
        left *= prim(true); 
        break; 
       case DIV: 
        if(double d = prim(true)) { 
         left /= d; 
         break; 
        } 
        return error("divide by zero"); 
       default: 
         return left; 
      } 
} 

double prim(bool get) 
{ 
     if(get) 
      get_token(); 

     switch(curr_tok) { 
      case NUMBER: { 
       double v = number_value; 
       get_token(); 
       return v; 
      } 
      case NAME: { 
       double &v = table[string_value]; 
       if(get_token() == ASSIGN) 
        v = expr(true); 
       return v; 
      } 
      case MINUS: 
       return -prim(true); 
      case LP: { 
       double e = expr(true); 
       if(curr_tok != RP) 
        return error(") expected"); 
       get_token(); 
       return e; 
      } 
      default: 
        return error("primary expected"); 
     } 
} 

Token_value get_token() 
{ 
     char ch = 0; 
     do { 
      if(!cin.get(ch)) 
       return curr_tok = END; 
     } while(ch != '\n' && isspace(ch)); 

     switch(ch) { 
      case 0: 
       return curr_tok = END; 
      case ';': 
      case '\n': 
       return curr_tok = PRINT; 
      case '+': 
      case '-': 
      case '/': 
      case '*': 
      case '(': 
      case ')': 
      case '=': 
       return curr_tok = Token_value(ch); 
      case '0': case '1': case '2': case '3': 
      case '4': case '5': case '6': case '7': 
      case '8': case '9': case '.': 
       cin.putback(ch); 
       cin >> number_value; 
       return curr_tok = NUMBER; 
      default: 
        if(isalpha(ch)) { 
         string_value = ch; 
         while(cin.get(ch) && isalnum(ch)) 
          string_value.push_back(ch); 
         cin.putback(ch); 
         return curr_tok = NAME; 
        } 
        error("bad token"); 
        return curr_tok = PRINT; 
     } 
} 

double error(const string &s) 
{ 
     no_of_errors++; 
     cerr << "error: " << s << '\n'; 
     return 1; 
} 

int main() 
{ 
     table["pi"] = 3.14; 
     table["e"] = 2.71; 

     while(cin) { 
      get_token(); 
      if(curr_tok == END) 
      break; 
      if(curr_tok == PRINT) 
      continue; 
      cout << expr(false) << endl; 
     } 
     return no_of_errors; 
} 

回答

1

這正是他的意思,在我看來。此外,結構不應該是全局的,它應該作爲參數傳遞(通過適當的值或參考)。

+0

他爲什麼說變量是「靜態的」?他們是全球性的,不是靜態的?還是全局變量也是自動靜態的? – Tool 2010-07-22 22:52:56

+1

本身不存在「全局」變量,只是全局名稱空間中的一個靜態變量。 – GManNickG 2010-07-22 22:54:37

+0

那麼用戶定義函數呢? 有什麼建議,我應該怎麼做呢?我希望實現類似於定義func(x)x * x; (某種宏觀風格) - 那麼當詞法分析器找到「define」關鍵字時,它將函數定義/參數存儲在適當的結構中? – Tool 2010-07-22 23:04:15