2、下面是用C++改写的:

#include
#include
#include
using namespace std;

// 因为在定义类时不能对数据成员直接初始化,
// 故下面这个全局数组定义在类(命名空间)的外面,待解决
char Precede_Matrix[7][7] =
{
 {'>', '>', '<', '<', '<', '>', '>',},
 {'>', '>', '<', '<', '<', '>', '>',},
 {'>', '>', '>', '>', '<', '>', '>',},
 {'>', '>', '>', '>', '<', '>', '>',},
 {'<', '<', '<', '<', '<', '=', '0',},
 {'>', '>', '>', '>', '0', '>', '>',},
 {'<', '<', '<', '<', '<', '0', '=',}
};

namespace ConsoleApplicationCal
{
 class Program
 {
  // 写这个构造函数是因为想在main函数中创建Program对象时
  // 自动调用Main()了,符合C#的运行规则
 public: Program::Program(void)
   {
    Main();
   }

 public: static char Precede(char a, char b)
   {
    int i = 0;
    int j = 0;
    switch (a)
    {
    case '+': i = 0; break;
    case '-': i = 1; break;
    case '*': i = 2; break;
    case '/': i = 3; break;
    case '(': i = 4; break;
    case ')': i = 5; break;
    case '#': i = 6; break;
    default: break;
    }
    switch (b)
    {
    case '+': j = 0; break;
    case '-': j = 1; break;
    case '*': j = 2; break;
    case '/': j = 3; break;
    case '(': j = 4; break;
    case ')': j = 5; break;
    case '#': j = 6; break;
    default: break;
    }

    return (Precede_Matrix[i][j]);
   }

 public: static double Operate(double a, char oper, double b)
   {
    switch (oper)
    {
    case '+': return a + b;
    case '-': return a - b;
    case '*': return a * b;
    case '/': return a / b;
    default: return -1;
    }
   }

 public: static bool IsOperand(char c)
   {
    if (('0' <= c && c <= '9') || c == '.') // c是数字或小数点
     return true;
    else
     return false;
   }

 public: static void Main(void)
   {
    string str;
    while (cin >> str)
    {
     str += "#";      //  后是#(结束标志)

     double a;
     double b;
     char x;
     char theta;

     stack OPTR;
     OPTR.push('#');
     stack OPND;

     int i = 0;
     char c = str[i++];
     double operand = 0;
     while (!(c == '#' && OPTR.top() == '#'))
     {
      if (IsOperand(c)) // c是数字或小数点(这里一定是数字),小数点已在下面转换掉了
      {
       int startIndex = i - 1;
       int length = 1; // c是数字,故初始一定是1
       while (IsOperand(str[i]))
       {
        i++;
        length++;
       }

       string doubleString = str.substr(startIndex, length);
       //     operand = atof(&str[i - 1]); // 把从c开头的数转化成double
       char **endPtr = NULL; // 没什么用,只是为了strtod的传参
       OPND.push(strtod(doubleString.c_str(), endPtr));

       c = str[i++];
      }
      else                            // c is operator or delimiter
      {
       switch (Precede(OPTR.top(), c))
       {

       case '<':
        OPTR.push(c);
        c = str[i++];
        break;

       case '=':
        x = OPTR.top();
        OPTR.pop();

        c = str[i++];
        break;

       case '>':
        theta = OPTR.top();
        OPTR.pop();

        b = OPND.top();
        OPND.pop();

        a = OPND.top();
        OPND.pop();

        OPND.push(Operate(a, theta, b));
        break;

       default:
        break;
       }
      }
     }
     //  OPTR栈的栈顶元素和当前读入的字符均为“#”
     //  即“#”=“#”时整个表达式求值完毕
     cout << OPND.top() << endl;
    }
   }
 };
}

int main(int argc, char **argv)
{
 // 仿照Winform中的Main函数new一个窗体对象:Application.Run(new Form1());
 // 都在堆上分配空间
 delete(new ConsoleApplicationCal::Program);

 return 0;
}

  可以看到,上面的C++程序主体是在设计一个类,而C#将这种特点发挥到了,C#程序是从Main()开始执行的,完全在类中进行一切。

  另外,上面的C++程序开头的全局变量初始化之所以不能定义在类里面,是因为这是在设计一个类!往往不能在类中直接对数据成员初始化,只有静态常量整型数据成员才可以直接(也必须)在类中初始化。

  后,发现C#中的构造函数挺妙的,东西多。