歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 用C#風格寫C++程序(探索C#對象模型)

用C#風格寫C++程序(探索C#對象模型)

日期:2017/3/1 10:09:30   编辑:Linux編程

寫C#程序就是在設計一個類

先看一個C#程序(計算一個表達式):

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace ConsoleApplicationCal
  6. {
  7. class Program
  8. {
  9. private static char[,] Precede_Matrix = new char[7, 7]
  10. {
  11. {'>', '>', '<', '<', '<', '>', '>',},
  12. {'>', '>', '<', '<', '<', '>', '>',},
  13. {'>', '>', '>', '>', '<', '>', '>',},
  14. {'>', '>', '>', '>', '<', '>', '>',},
  15. {'<', '<', '<', '<', '<', '=', '0',},
  16. {'>', '>', '>', '>', '0', '>', '>',},
  17. {'<', '<', '<', '<', '<', '0', '=',}
  18. };
  19. public static char Precede(char a, char b)
  20. {
  21. int i = 0;
  22. int j = 0;
  23. switch (a)
  24. {
  25. case '+': i = 0; break;
  26. case '-': i = 1; break;
  27. case '*': i = 2; break;
  28. case '/': i = 3; break;
  29. case '(': i = 4; break;
  30. case ')': i = 5; break;
  31. case '#': i = 6; break;
  32. default: break;
  33. }
  34. switch (b)
  35. {
  36. case '+': j = 0; break;
  37. case '-': j = 1; break;
  38. case '*': j = 2; break;
  39. case '/': j = 3; break;
  40. case '(': j = 4; break;
  41. case ')': j = 5; break;
  42. case '#': j = 6; break;
  43. default: break;
  44. }
  45. return (Precede_Matrix[i, j]);
  46. }
  47. public static double Operate(double a, char oper, double b)
  48. {
  49. switch (oper)
  50. {
  51. case '+': return a + b;
  52. case '-': return a - b;
  53. case '*': return a * b;
  54. case '/': return a / b;
  55. default: return -1;
  56. }
  57. }
  58. public static bool IsOperand(char c)
  59. {
  60. if (('0' <= c && c <= '9') || c == '.') // c是數字或小數點
  61. return true;
  62. else
  63. return false;
  64. }
  65. static void Main(string[] args)
  66. {
  67. string str;
  68. while ((str = Console.ReadLine()) != null)
  69. {
  70. str += "#"; // 最後是#(結束標志)
  71. double a;
  72. double b;
  73. char x;
  74. char theta;
  75. Stack<char> OPTR = new Stack<char>();
  76. OPTR.Push('#');
  77. Stack<double> OPND = new Stack<double>();
  78. int i = 0;
  79. char c = str[i++];
  80. double operand = 0;
  81. while (!(c == '#' && OPTR.Peek() == '#'))
  82. {
  83. if (IsOperand(c)) // c是數字或小數點(這裡一定是數字),小數點已在下面轉換掉了
  84. {
  85. int startIndex = i - 1;
  86. int length = 1; // c是數字,故初始一定是1
  87. while (IsOperand(str[i]))
  88. {
  89. i++;
  90. length++;
  91. }
  92. string doubleString = str.Substring(startIndex, length);
  93. // operand = atof(&str[i - 1]); // 把從c開頭的數轉化成double
  94. OPND.Push(double.Parse(doubleString));
  95. c = str[i++];
  96. }
  97. else // c is operator or delimiter
  98. {
  99. switch (Precede(OPTR.Peek(), c))
  100. {
  101. case '<':
  102. OPTR.Push(c);
  103. c = str[i++];
  104. break;
  105. case '=':
  106. x = OPTR.Pop();
  107. c = str[i++];
  108. break;
  109. case '>':
  110. theta = OPTR.Pop();
  111. b = OPND.Pop();
  112. a = OPND.Pop();
  113. OPND.Push(Operate(a, theta, b));
  114. break;
  115. default:
  116. break;
  117. }
  118. }
  119. }
  120. // OPTR棧的棧頂元素和當前讀入的字符均為“#”
  121. // 即“#”=“#”時整個表達式求值完畢
  122. Console.WriteLine(OPND.Peek());
  123. }
  124. }
  125. }
  126. }

下面是用C++改寫的:

  1. #include <iostream>
  2. #include <stack>
  3. #include <string>
  4. using namespace std;
  5. // 因為在定義類時不能對數據成員直接初始化,
  6. // 故下面這個全局數組定義在類(命名空間)的外面,待解決
  7. char Precede_Matrix[7][7] =
  8. {
  9. {'>', '>', '<', '<', '<', '>', '>',},
  10. {'>', '>', '<', '<', '<', '>', '>',},
  11. {'>', '>', '>', '>', '<', '>', '>',},
  12. {'>', '>', '>', '>', '<', '>', '>',},
  13. {'<', '<', '<', '<', '<', '=', '0',},
  14. {'>', '>', '>', '>', '0', '>', '>',},
  15. {'<', '<', '<', '<', '<', '0', '=',}
  16. };
  17. namespace ConsoleApplicationCal
  18. {
  19. class Program
  20. {
  21. // 寫這個構造函數是因為想在main函數中創建Program對象時
  22. // 就自動調用Main()了,符合C#的運行規則
  23. public: Program::Program(void)
  24. {
  25. Main();
  26. }
  27. public: static char Precede(char a, char b)
  28. {
  29. int i = 0;
  30. int j = 0;
  31. switch (a)
  32. {
  33. case '+': i = 0; break;
  34. case '-': i = 1; break;
  35. case '*': i = 2; break;
  36. case '/': i = 3; break;
  37. case '(': i = 4; break;
  38. case ')': i = 5; break;
  39. case '#': i = 6; break;
  40. default: break;
  41. }
  42. switch (b)
  43. {
  44. case '+': j = 0; break;
  45. case '-': j = 1; break;
  46. case '*': j = 2; break;
  47. case '/': j = 3; break;
  48. case '(': j = 4; break;
  49. case ')': j = 5; break;
  50. case '#': j = 6; break;
  51. default: break;
  52. }
  53. return (Precede_Matrix[i][j]);
  54. }
  55. public: static double Operate(double a, char oper, double b)
  56. {
  57. switch (oper)
  58. {
  59. case '+': return a + b;
  60. case '-': return a - b;
  61. case '*': return a * b;
  62. case '/': return a / b;
  63. default: return -1;
  64. }
  65. }
  66. public: static bool IsOperand(char c)
  67. {
  68. if (('0' <= c && c <= '9') || c == '.') // c是數字或小數點
  69. return true;
  70. else
  71. return false;
  72. }
  73. public: void Main(void)
  74. {
  75. string str;
  76. while (cin >> str)
  77. {
  78. str += "#"; // 最後是#(結束標志)
  79. double a;
  80. double b;
  81. char x;
  82. char theta;
  83. stack<char> OPTR;
  84. OPTR.push('#');
  85. stack<double> OPND;
  86. int i = 0;
  87. char c = str[i++];
  88. double operand = 0;
  89. while (!(c == '#' && OPTR.top() == '#'))
  90. {
  91. if (IsOperand(c)) // c是數字或小數點(這裡一定是數字),小數點已在下面轉換掉了
  92. {
  93. int startIndex = i - 1;
  94. int length = 1; // c是數字,故初始一定是1
  95. while (IsOperand(str[i]))
  96. {
  97. i++;
  98. length++;
  99. }
  100. string doubleString = str.substr(startIndex, length);
  101. // operand = atof(&str[i - 1]); // 把從c開頭的數轉化成double
  102. char **endPtr = NULL; // 沒什麼用,只是為了strtod的傳參
  103. OPND.push(strtod(doubleString.c_str(), endPtr));
  104. c = str[i++];
  105. }
  106. else // c is operator or delimiter
  107. {
  108. switch (Precede(OPTR.top(), c))
  109. {
  110. case '<':
  111. OPTR.push(c);
  112. c = str[i++];
  113. break;
  114. case '=':
  115. x = OPTR.top();
  116. OPTR.pop();
  117. c = str[i++];
  118. break;
  119. case '>':
  120. theta = OPTR.top();
  121. OPTR.pop();
  122. b = OPND.top();
  123. OPND.pop();
  124. a = OPND.top();
  125. OPND.pop();
  126. OPND.push(Operate(a, theta, b));
  127. break;
  128. default:
  129. break;
  130. }
  131. }
  132. }
  133. // OPTR棧的棧頂元素和當前讀入的字符均為“#”
  134. // 即“#”=“#”時整個表達式求值完畢
  135. cout << OPND.top() << endl;
  136. }
  137. }
  138. };
  139. }
  140. int main(int argc, char **argv)
  141. {
  142. // 仿照Winform中的Main函數new一個窗體對象
  143. // Application.Run(new Form1());
  144. ConsoleApplicationCal::Program objForm;
  145. return 0;
  146. }

可以看到,上面的C++程序主體就是在設計一個類,而C#將這種特點發揮到了極致,C#程序是從Main()開始執行的,完全在類中進行一切。

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

Copyright © Linux教程網 All Rights Reserved