寫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++程序開頭的全局變量初始化之所以不能定義在類裡面,是因為這是在設計一個類!不能在類中直接對數據成員初始化,只有靜態常量整型數據成員才可以在類中初始化。