一个C#风格的C++程序

地址: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;
				else
					return 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是数字,故初始一定是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());
	// 都在堆上分配空间
	delete(new ConsoleApplicationCal::Program);  // 为了对比,这里就省略了检查分配空间失败的情况

	return 0;
}

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

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

最后,发现C#中的构造函数挺妙的,东西多。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值