读书人

用C#作派写C++程序(探索C#对象模型)

发布时间: 2012-09-23 10:28:11 作者: rapoo

用C#风格写C++程序(探索C#对象模型)

写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;elsereturn 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是数字,故初始一定是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());ConsoleApplicationCal::Program objForm;return 0;}

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

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

1楼chaihengcug4小时前
非常有用,收藏了

读书人网 >C++

热点推荐