地址:http://blog.csdn.net/justme0/article/details/7994133
寫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()); } } }}
2、下面是用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;elsereturn false;}public: static 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是數字,故初始一定是1while (IsOperand(str[i])){i++;length++;}string doubleString = str.substr(startIndex, length);// operand = atof(&str[i - 1]);//把從c開頭的數轉化成doublechar **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#中的建構函式挺妙的,東西多。