写C#程序就是在设计一个类先看一个C#程序(计算一个表达式):
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
- namespace ConsoleApplicationCal
- {
- class Program
- {
- private static char[,] Precede_Matrix = new char[7, 7]
- {
- {">", ">", "<", "<", "<", ">", ">",},
- {">", ">", "<", "<", "<", ">", ">",},
- {">", ">", ">", ">", "<", ">", ">",},
- {">", ">", ">", ">", "<", ">", ">",},
- {"<", "<", "<", "<", "<", "=", "0",},
- {">", ">", ">", ">", "0", ">", ">",},
- {"<", "<", "<", "<", "<", "0", "=",}
- };
-
- 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;
- }
-
- static void Main(string[] args)
- {
- string str;
- while ((str = Console.ReadLine()) != null)
- {
- str += "#"; // 最后是#(结束标志)
-
- double a;
- double b;
- char x;
- char theta;
-
- Stack<char> OPTR = new Stack<char>();
- OPTR.Push("#");
- Stack<double> OPND = new Stack<double>();
-
- int i = 0;
- char c = str[i++];
- double operand = 0;
- while (!(c == "#" && OPTR.Peek() == "#"))
- {
- if (IsOperand(c)) // c是数字或小数点(这里一定是数字),小数点已在下面转换掉了
- {
- int startIndex = i - 1;
- int length = 1; // c是数字,故初始一定是1
- while (IsOperand(str[i]))
- {
- i++;
- length++;
- }
-
- string doubleString = str.Substring(startIndex, length);
- // operand = atof(&str[i - 1]); // 把从c开头的数转化成double
- OPND.Push(double.Parse(doubleString));
-
-
- c = str[i++];
- }
- else // c is operator or delimiter
- {
- switch (Precede(OPTR.Peek(), c))
- {
-
- case "<":
- OPTR.Push(c);
- c = str[i++];
- break;
-
- case "=":
- x = OPTR.Pop();
-
- c = str[i++];
- break;
-
- case ">":
- theta = OPTR.Pop();
- b = OPND.Pop();
- a = OPND.Pop();
- OPND.Push(Operate(a, theta, b));
- break;
-
- default:
- break;
- }
- }
- }
- // OPTR栈的栈顶元素和当前读入的字符均为“#”
- // 即“#”=“#”时整个表达式求值完毕
- Console.WriteLine(OPND.Peek());
- }
- }
- }
- }
下面是用C++改写的:
- #include <iostream>
- #include <stack>
- #include <string>
- 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: void Main(void)
- {
- string str;
- while (cin >> str)
- {
- str += "#"; // 最后是#(结束标志)
-
- double a;
- double b;
- char x;
- char theta;
-
- stack<char> OPTR;
- OPTR.push("#");
- stack<double> 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());
- ConsoleApplicationCal::Program objForm;
-
- return 0;
- }
可以看到,上面的C++程序主体就是在设计一个类,而C#将这种特点发挥到了极致,C#程序是从Main()开始执行的,完全在类中进行一切。另外,上面的C++程序开头的全局变量初始化之所以不能定义在类里面,是因为这是在设计一个类!不能在类中直接对数据成员初始化,只有
静态常量整型数据成员才可以在类中初始化。